From 23d1b911fc1f38a554cb8b09a3478d533e929e9b Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 02:27:21 -0700 Subject: [PATCH 01/10] 25: Refactor the code according to the Google C++ Style Guide --- xdf.cpp | 458 ++++++++++++++++++++++++++++---------------------------- xdf.h | 333 +++++++++++++++++++--------------------- 2 files changed, 381 insertions(+), 410 deletions(-) diff --git a/xdf.cpp b/xdf.cpp index 96c3c81..ae448e3 100644 --- a/xdf.cpp +++ b/xdf.cpp @@ -33,7 +33,7 @@ Xdf::Xdf() { } -int Xdf::load_xdf(std::string filename) +int Xdf::LoadXdf(std::string filename) { clock_t time; time = clock(); @@ -79,13 +79,13 @@ int Xdf::load_xdf(std::string filename) //for each chunk while (1) { - uint64_t ChLen = readLength(file);//chunk length + uint64_t ChLen = ReadLength(file);//chunk length if (ChLen == 0) break; uint16_t tag; //read tag of the chunk, 6 possibilities - readBin(file, &tag); + ReadBin(file, &tag); switch (tag) { @@ -93,7 +93,7 @@ int Xdf::load_xdf(std::string filename) { char* buffer = new char[ChLen - 2]; file.read(buffer, ChLen - 2); - fileHeader = buffer; + file_header_ = buffer; pugi::xml_document doc; @@ -101,7 +101,7 @@ int Xdf::load_xdf(std::string filename) pugi::xml_node info = doc.child("info"); - version = info.child("version").text().as_float(); + version_ = info.child("version").text().as_float(); delete[] buffer; } @@ -111,13 +111,13 @@ int Xdf::load_xdf(std::string filename) //read [StreamID] uint32_t streamID; int index; - Xdf::readBin(file, &streamID); + Xdf::ReadBin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; if (it == idmap.end()) { index = idmap.size(); idmap.emplace_back(streamID); - streams.emplace_back(); + streams_.emplace_back(); } else index = std::distance(idmap.begin(), it); @@ -128,31 +128,31 @@ int Xdf::load_xdf(std::string filename) //read [Content] char* buffer = new char[ChLen - 6]; file.read(buffer, ChLen - 6); - streams[index].streamHeader = buffer; + streams_[index].stream_header = buffer; doc.load_buffer_inplace(buffer, ChLen - 6); pugi::xml_node info = doc.child("info"); pugi::xml_node desc = info.child("desc"); - streams[index].info.channel_count = info.child("channel_count").text().as_int(); - streams[index].info.nominal_srate = info.child("nominal_srate").text().as_double(); - streams[index].info.name = info.child("name").text().get(); - streams[index].info.type = info.child("type").text().get(); - streams[index].info.channel_format = info.child("channel_format").text().get(); + streams_[index].info.channel_count = info.child("channel_count").text().as_int(); + streams_[index].info.nominal_srate = info.child("nominal_srate").text().as_double(); + streams_[index].info.name = info.child("name").text().get(); + streams_[index].info.type = info.child("type").text().get(); + streams_[index].info.channel_format = info.child("channel_format").text().get(); for (auto channel = desc.child("channels").child("channel"); channel; channel = channel.next_sibling("channel")) { - streams[index].info.channels.emplace_back(); + streams_[index].info.channels.emplace_back(); for (auto const &entry : channel.children()) - streams[index].info.channels.back().emplace(entry.name(), entry.child_value()); + streams_[index].info.channels.back().emplace(entry.name(), entry.child_value()); } - if (streams[index].info.nominal_srate > 0) - streams[index].sampling_interval = 1 / streams[index].info.nominal_srate; + if (streams_[index].info.nominal_srate > 0) + streams_[index].sampling_interval = 1 / streams_[index].info.nominal_srate; else - streams[index].sampling_interval = 0; + streams_[index].sampling_interval = 0; delete[] buffer; } @@ -162,262 +162,262 @@ int Xdf::load_xdf(std::string filename) //read [StreamID] uint32_t streamID; int index; - Xdf::readBin(file, &streamID); + Xdf::ReadBin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; if (it == idmap.end()) { index = idmap.size(); idmap.emplace_back(streamID); - streams.emplace_back(); + streams_.emplace_back(); } else index = std::distance(idmap.begin(), it); //read [NumSampleBytes], [NumSamples] - uint64_t numSamp = readLength(file); + uint64_t numSamp = ReadLength(file); //check the data type - if (streams[index].info.channel_format.compare("float32") == 0) + if (streams_[index].info.channel_format.compare("float32") == 0) { //if the time series is empty - if (streams[index].time_series.empty()) - streams[index].time_series.resize(streams[index].info.channel_count); + if (streams_[index].time_series.empty()) + streams_[index].time_series.resize(streams_[index].info.channel_count); //for each sample for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = readBin(file); + auto tsBytes = ReadBin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::readBin(file, &ts); - streams[index].time_stamps.emplace_back(ts); + Xdf::ReadBin(file, &ts); + streams_[index].time_stamps.emplace_back(ts); } else { - ts = streams[index].last_timestamp + streams[index].sampling_interval; - streams[index].time_stamps.emplace_back(ts); + ts = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].time_stamps.emplace_back(ts); } - streams[index].last_timestamp = ts; + streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams[index].info.channel_count; ++v) + for (int v = 0; v < streams_[index].info.channel_count; ++v) { float data; - Xdf::readBin(file, &data); - streams[index].time_series[v].emplace_back(data); + Xdf::ReadBin(file, &data); + streams_[index].time_series[v].emplace_back(data); } } } - else if (streams[index].info.channel_format.compare("double64") == 0) + else if (streams_[index].info.channel_format.compare("double64") == 0) { //if the time series is empty - if (streams[index].time_series.empty()) - streams[index].time_series.resize(streams[index].info.channel_count); + if (streams_[index].time_series.empty()) + streams_[index].time_series.resize(streams_[index].info.channel_count); //for each sample for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = readBin(file); + auto tsBytes = ReadBin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::readBin(file, &ts); - streams[index].time_stamps.emplace_back(ts); + Xdf::ReadBin(file, &ts); + streams_[index].time_stamps.emplace_back(ts); } else { - ts = streams[index].last_timestamp + streams[index].sampling_interval; - streams[index].time_stamps.emplace_back(ts); + ts = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].time_stamps.emplace_back(ts); } - streams[index].last_timestamp = ts; + streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams[index].info.channel_count; ++v) + for (int v = 0; v < streams_[index].info.channel_count; ++v) { double data; - Xdf::readBin(file, &data); - streams[index].time_series[v].emplace_back(data); + Xdf::ReadBin(file, &data); + streams_[index].time_series[v].emplace_back(data); } } } - else if (streams[index].info.channel_format.compare("int8") == 0) + else if (streams_[index].info.channel_format.compare("int8") == 0) { //if the time series is empty - if (streams[index].time_series.empty()) - streams[index].time_series.resize(streams[index].info.channel_count); + if (streams_[index].time_series.empty()) + streams_[index].time_series.resize(streams_[index].info.channel_count); //for each sample for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = readBin(file); + auto tsBytes = ReadBin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::readBin(file, &ts); - streams[index].time_stamps.emplace_back(ts); + Xdf::ReadBin(file, &ts); + streams_[index].time_stamps.emplace_back(ts); } else { - ts = streams[index].last_timestamp + streams[index].sampling_interval; - streams[index].time_stamps.emplace_back(ts); + ts = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].time_stamps.emplace_back(ts); } - streams[index].last_timestamp = ts; + streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams[index].info.channel_count; ++v) + for (int v = 0; v < streams_[index].info.channel_count; ++v) { int8_t data; - Xdf::readBin(file, &data); - streams[index].time_series[v].emplace_back(data); + Xdf::ReadBin(file, &data); + streams_[index].time_series[v].emplace_back(data); } } } - else if (streams[index].info.channel_format.compare("int16") == 0) + else if (streams_[index].info.channel_format.compare("int16") == 0) { //if the time series is empty - if (streams[index].time_series.empty()) - streams[index].time_series.resize(streams[index].info.channel_count); + if (streams_[index].time_series.empty()) + streams_[index].time_series.resize(streams_[index].info.channel_count); //for each sample for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = readBin(file); + auto tsBytes = ReadBin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::readBin(file, &ts); - streams[index].time_stamps.emplace_back(ts); + Xdf::ReadBin(file, &ts); + streams_[index].time_stamps.emplace_back(ts); } else { - ts = streams[index].last_timestamp + streams[index].sampling_interval; - streams[index].time_stamps.emplace_back(ts); + ts = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].time_stamps.emplace_back(ts); } - streams[index].last_timestamp = ts; + streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams[index].info.channel_count; ++v) + for (int v = 0; v < streams_[index].info.channel_count; ++v) { int16_t data; - Xdf::readBin(file, &data); - streams[index].time_series[v].emplace_back(data); + Xdf::ReadBin(file, &data); + streams_[index].time_series[v].emplace_back(data); } } } - else if (streams[index].info.channel_format.compare("int32") == 0) + else if (streams_[index].info.channel_format.compare("int32") == 0) { //if the time series is empty - if (streams[index].time_series.empty()) - streams[index].time_series.resize(streams[index].info.channel_count); + if (streams_[index].time_series.empty()) + streams_[index].time_series.resize(streams_[index].info.channel_count); //for each sample for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = readBin(file); + auto tsBytes = ReadBin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::readBin(file, &ts); - streams[index].time_stamps.emplace_back(ts); + Xdf::ReadBin(file, &ts); + streams_[index].time_stamps.emplace_back(ts); } else { - ts = streams[index].last_timestamp + streams[index].sampling_interval; - streams[index].time_stamps.emplace_back(ts); + ts = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].time_stamps.emplace_back(ts); } - streams[index].last_timestamp = ts; + streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams[index].info.channel_count; ++v) + for (int v = 0; v < streams_[index].info.channel_count; ++v) { int32_t data; - Xdf::readBin(file, &data); - streams[index].time_series[v].emplace_back(data); + Xdf::ReadBin(file, &data); + streams_[index].time_series[v].emplace_back(data); } } } - else if (streams[index].info.channel_format.compare("int64") == 0) + else if (streams_[index].info.channel_format.compare("int64") == 0) { //if the time series is empty - if (streams[index].time_series.empty()) - streams[index].time_series.resize(streams[index].info.channel_count); + if (streams_[index].time_series.empty()) + streams_[index].time_series.resize(streams_[index].info.channel_count); //for each sample for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = readBin(file); + auto tsBytes = ReadBin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::readBin(file, &ts); - streams[index].time_stamps.emplace_back(ts); + Xdf::ReadBin(file, &ts); + streams_[index].time_stamps.emplace_back(ts); } else { - ts = streams[index].last_timestamp + streams[index].sampling_interval; - streams[index].time_stamps.emplace_back(ts); + ts = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].time_stamps.emplace_back(ts); } - streams[index].last_timestamp = ts; + streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams[index].info.channel_count; ++v) + for (int v = 0; v < streams_[index].info.channel_count; ++v) { int64_t data; - Xdf::readBin(file, &data); - streams[index].time_series[v].emplace_back(data); + Xdf::ReadBin(file, &data); + streams_[index].time_series[v].emplace_back(data); } } } - else if (streams[index].info.channel_format.compare("string") == 0) + else if (streams_[index].info.channel_format.compare("string") == 0) { //for each event for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = readBin(file); + auto tsBytes = ReadBin(file); double ts; //temporary time stamp if (tsBytes == 8) - Xdf::readBin(file, &ts); + Xdf::ReadBin(file, &ts); else - ts = streams[index].last_timestamp + streams[index].sampling_interval; + ts = streams_[index].last_timestamp + streams_[index].sampling_interval; //read the event - auto length = Xdf::readLength(file); + auto length = Xdf::ReadLength(file); char* buffer = new char[length + 1]; file.read(buffer, length); buffer[length] = '\0'; - eventMap.emplace_back(std::make_pair(buffer, ts), index); + event_map_.emplace_back(std::make_pair(buffer, ts), index); delete[] buffer; - streams[index].last_timestamp = ts; + streams_[index].last_timestamp = ts; } } } @@ -426,13 +426,13 @@ int Xdf::load_xdf(std::string filename) { uint32_t streamID; int index; - Xdf::readBin(file, &streamID); + Xdf::ReadBin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; if (it == idmap.end()) { index = idmap.size(); idmap.emplace_back(streamID); - streams.emplace_back(); + streams_.emplace_back(); } else index = std::distance(idmap.begin(), it); @@ -441,11 +441,11 @@ int Xdf::load_xdf(std::string filename) double collectionTime; double offsetValue; - Xdf::readBin(file, &collectionTime); - Xdf::readBin(file, &offsetValue); + Xdf::ReadBin(file, &collectionTime); + Xdf::ReadBin(file, &offsetValue); - streams[index].clock_times.emplace_back(collectionTime); - streams[index].clock_values.emplace_back(offsetValue); + streams_[index].clock_times.emplace_back(collectionTime); + streams_[index].clock_values.emplace_back(offsetValue); } break; case 6: //read [StreamFooter] chunk @@ -455,13 +455,13 @@ int Xdf::load_xdf(std::string filename) //read [StreamID] uint32_t streamID; int index; - Xdf::readBin(file, &streamID); + Xdf::ReadBin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; if (it == idmap.end()) { index = idmap.size(); idmap.emplace_back(streamID); - streams.emplace_back(); + streams_.emplace_back(); } else index = std::distance(idmap.begin(), it); @@ -469,16 +469,16 @@ int Xdf::load_xdf(std::string filename) char* buffer = new char[ChLen - 6]; file.read(buffer, ChLen - 6); - streams[index].streamFooter = buffer; + streams_[index].stream_footer = buffer; doc.load_buffer_inplace(buffer, ChLen - 6); pugi::xml_node info = doc.child("info"); - streams[index].info.first_timestamp = info.child("first_timestamp").text().as_double(); - streams[index].info.last_timestamp = info.child("last_timestamp").text().as_double(); - streams[index].info.measured_srate = info.child("measured_srate").text().as_double(); - streams[index].info.sample_count = info.child("sample_count").text().as_int(); + streams_[index].info.first_timestamp = info.child("first_timestamp").text().as_double(); + streams_[index].info.last_timestamp = info.child("last_timestamp").text().as_double(); + streams_[index].info.measured_sampling_rate = info.child("measured_srate").text().as_double(); + streams_[index].info.sample_count = info.child("sample_count").text().as_int(); delete[] buffer; } break; @@ -503,21 +503,21 @@ int Xdf::load_xdf(std::string filename) //=============find the min and max time stamps============= //========================================================== - syncTimeStamps(); + SyncTimeStamps(); - findMinMax(); + FindMinMaxTimeStamps(); - findMajSR(); + FindMajorSamplingRate(); - getHighestSampleRate(); + FindMaxSampleRate(); - loadSampleRateMap(); + LoadSamplingRateMap(); - calcTotalChannel(); + CalculateChannelCount(); - loadDictionary(); + LoadDictionary(); - calcEffectiveSrate(); + CalculateEffectiveSamplingRate(); //loading finishes, close file file.close(); @@ -531,10 +531,10 @@ int Xdf::load_xdf(std::string filename) return 0; } -void Xdf::syncTimeStamps() +void Xdf::SyncTimeStamps() { // Sync time stamps - for (auto &stream : this->streams) + for (auto &stream : this->streams_) { if (!stream.clock_times.empty()) { @@ -561,15 +561,15 @@ void Xdf::syncTimeStamps() } // Sync event time stamps - for (auto &elem : this->eventMap) + for (auto &elem : this->event_map_) { - if (!this->streams[elem.second].clock_times.empty()) + if (!this->streams_[elem.second].clock_times.empty()) { size_t k = 0; // index iterating through streams[elem.second].clock_times - while (k < this->streams[elem.second].clock_times.size() - 1) + while (k < this->streams_[elem.second].clock_times.size() - 1) { - if (this->streams[elem.second].clock_times[k+1] < elem.first.second) + if (this->streams_[elem.second].clock_times[k+1] < elem.first.second) { k++; } @@ -579,19 +579,19 @@ void Xdf::syncTimeStamps() } } - elem.first.second += this->streams[elem.second].clock_values[k]; // apply the last offset value to the timestamp; if there hasn't yet been an offset value take the first recorded one + elem.first.second += this->streams_[elem.second].clock_values[k]; // apply the last offset value to the timestamp; if there hasn't yet been an offset value take the first recorded one } } // Update first and last time stamps in stream footer - for (size_t k = 0; k < this->streams.size(); k++) + for (size_t k = 0; k < this->streams_.size(); k++) { - if (streams[k].info.channel_format.compare("string") == 0) + if (streams_[k].info.channel_format.compare("string") == 0) { double min = NAN; double max = NAN; - for (auto const &elem : this->eventMap) + for (auto const &elem : this->event_map_) { if (elem.second == (int)k) { @@ -607,18 +607,18 @@ void Xdf::syncTimeStamps() } } - streams[k].info.first_timestamp = min; - streams[k].info.last_timestamp = max; + streams_[k].info.first_timestamp = min; + streams_[k].info.last_timestamp = max; } else { - streams[k].info.first_timestamp = streams[k].time_stamps.front(); - streams[k].info.last_timestamp = streams[k].time_stamps.back(); + streams_[k].info.first_timestamp = streams_[k].time_stamps.front(); + streams_[k].info.last_timestamp = streams_[k].time_stamps.back(); } } } -void Xdf::resample(int userSrate) +void Xdf::Resample(int sampling_rate) { //if user entered a preferred sample rate, we resample all the channels to that sample rate //Otherwise, we resample all channels to the sample rate that has the most channels @@ -626,14 +626,14 @@ void Xdf::resample(int userSrate) clock_t time = clock(); #define BUF_SIZE 8192 - for (auto &stream : streams) + for (auto &stream : streams_) { if (!stream.time_series.empty() && - stream.info.nominal_srate != userSrate && + stream.info.nominal_srate != sampling_rate && stream.info.nominal_srate != 0) { int fsin = stream.info.nominal_srate; // input samplerate - int fsout = userSrate; // output samplerate + int fsout = sampling_rate; // output samplerate double bandwidth = 0.95; // bandwidth double rp = 0.1; // passband ripple factor double rs = 140; // stopband attenuation @@ -699,9 +699,9 @@ void Xdf::resample(int userSrate) //====================================================================== - calcTotalLength(userSrate); + CalculateTotalLength(sampling_rate); - adjustTotalLength(); + AdjustTotalLength(); time = clock() - time; @@ -710,22 +710,22 @@ void Xdf::resample(int userSrate) } //function of reading the length of each chunk -uint64_t Xdf::readLength(std::ifstream &file) +uint64_t Xdf::ReadLength(std::ifstream &file) { uint8_t bytes; - Xdf::readBin(file, &bytes); + Xdf::ReadBin(file, &bytes); uint64_t length = 0; switch (bytes) { case 1: - length = readBin(file); + length = ReadBin(file); break; case 4: - length = readBin(file); + length = ReadBin(file); break; case 8: - length = readBin(file); + length = ReadBin(file); break; default: std::cout << "Invalid variable-length integer length (" @@ -736,32 +736,32 @@ uint64_t Xdf::readLength(std::ifstream &file) return length; } -void Xdf::findMinMax() +void Xdf::FindMinMaxTimeStamps() { //find the smallest timestamp of all streams - for (auto const &stream : streams) + for (auto const &stream : streams_) { if (!std::isnan(stream.info.first_timestamp)) { - minTS = stream.info.first_timestamp; + min_timestamp_ = stream.info.first_timestamp; break; } } - for (auto const &stream : streams) + for (auto const &stream : streams_) { - if (!std::isnan(stream.info.first_timestamp) && stream.info.first_timestamp < minTS) - minTS = stream.info.first_timestamp; + if (!std::isnan(stream.info.first_timestamp) && stream.info.first_timestamp < min_timestamp_) + min_timestamp_ = stream.info.first_timestamp; } //find the max timestamp of all streams - for (auto const &stream : streams) + for (auto const &stream : streams_) { - if (!std::isnan(stream.info.last_timestamp) && stream.info.last_timestamp > maxTS) - maxTS = stream.info.last_timestamp; + if (!std::isnan(stream.info.last_timestamp) && stream.info.last_timestamp > max_timestamp_) + max_timestamp_ = stream.info.last_timestamp; } } -void Xdf::findMajSR() +void Xdf::FindMajorSamplingRate() { // find out which sample rate has the most channels typedef int sampRate; @@ -770,7 +770,7 @@ void Xdf::findMajSR() std::vector > srateMap; // pairs of all the streams //find out whether a sample rate already exists in srateMap - for (auto const &stream : streams) + for (auto const &stream : streams_) { if (stream.info.nominal_srate != 0) { @@ -797,36 +797,36 @@ void Xdf::findMajSR() const std::pair &first) { return largest.second < first.second; }))); - majSR = srateMap[index].first; //the sample rate that has the most channels + major_sampling_rate_ = srateMap[index].first; //the sample rate that has the most channels } else { - majSR = 0; //if there are no streams with a fixed sample reate + major_sampling_rate_ = 0; //if there are no streams with a fixed sample reate } } -void Xdf::calcTotalChannel() +void Xdf::CalculateChannelCount() { //calculating total channel count, and indexing them onto streamMap - for (size_t c = 0; c < streams.size(); c++) + for (size_t c = 0; c < streams_.size(); c++) { - if(!streams[c].time_series.empty()) + if(!streams_[c].time_series.empty()) { - totalCh += streams[c].info.channel_count; + channel_count_ += streams_[c].info.channel_count; - for (int i = 0; i < streams[c].info.channel_count; i++) - streamMap.emplace_back(c); + for (int i = 0; i < streams_[c].info.channel_count; i++) + stream_map_.emplace_back(c); } } } -void Xdf::calcTotalLength(int sampleRate) +void Xdf::CalculateTotalLength(int sampling_rate) { - totalLen = (maxTS - minTS) * sampleRate; + total_len_ = (max_timestamp_ - min_timestamp_) * sampling_rate; } -void Xdf::freeUpTimeStamps() +void Xdf::FreeUpTimeStamps() { //free up as much memory as possible - for (auto &stream : streams) + for (auto &stream : streams_) { //we don't need to keep all the time stamps unless it's a stream with irregular samples //filter irregular streams and string streams @@ -840,74 +840,74 @@ void Xdf::freeUpTimeStamps() } } -void Xdf::adjustTotalLength() +void Xdf::AdjustTotalLength() { - for (auto const &stream : streams) + for (auto const &stream : streams_) { if(!stream.time_series.empty()) { - if (totalLen < stream.time_series.front().size()) - totalLen = stream.time_series.front().size(); + if (total_len_ < stream.time_series.front().size()) + total_len_ = stream.time_series.front().size(); } } } -void Xdf::getHighestSampleRate() +void Xdf::FindMaxSampleRate() { - for (auto const &stream : streams) + for (auto const &stream : streams_) { - if (stream.info.nominal_srate > maxSR) - maxSR = stream.info.nominal_srate; + if (stream.info.nominal_srate > max_sampling_rate_) + max_sampling_rate_ = stream.info.nominal_srate; } } -void Xdf::loadSampleRateMap() +void Xdf::LoadSamplingRateMap() { - for (auto const &stream : streams) - sampleRateMap.emplace(stream.info.nominal_srate); + for (auto const &stream : streams_) + sampling_rate_map_.emplace(stream.info.nominal_srate); } -void Xdf::detrend() +void Xdf::Detrend() { - for (auto &stream : streams) + for (auto &stream : streams_) { for (auto &row : stream.time_series) { long double init = 0.0; long double mean = std::accumulate(row.begin(), row.end(), init) / row.size(); for(auto &val: row) val -= mean; - offsets.emplace_back(mean); + offsets_.emplace_back(mean); } } } -void Xdf::calcEffectiveSrate() +void Xdf::CalculateEffectiveSamplingRate() { - for (auto &stream : streams) + for (auto &stream : streams_) { if (stream.info.nominal_srate) { try { - stream.info.effective_sample_rate + stream.info.effective_sampling_rate = stream.info.sample_count / (stream.info.last_timestamp - stream.info.first_timestamp); - if (stream.info.effective_sample_rate) - effectiveSampleRateVector.emplace_back(stream.info.effective_sample_rate); + if (stream.info.effective_sampling_rate) + effective_sampling_rates_.emplace_back(stream.info.effective_sampling_rate); pugi::xml_document doc; - doc.load_string(stream.streamFooter.c_str()); + doc.load_string(stream.stream_footer.c_str()); pugi::xml_node sampleCount = doc.child("info").child("sample_count"); pugi::xml_node effectiveSampleRate = doc.child("info").insert_child_after("effective_sample_rate", sampleCount); effectiveSampleRate.append_child(pugi::node_pcdata) - .set_value(std::to_string(stream.info.effective_sample_rate).c_str()); + .set_value(std::to_string(stream.info.effective_sampling_rate).c_str()); std::stringstream buffer; doc.save(buffer); - stream.streamFooter = buffer.str(); + stream.stream_footer = buffer.str(); } catch (std::exception &e) { @@ -918,9 +918,9 @@ void Xdf::calcEffectiveSrate() } } -int Xdf::writeEventsToXDF(std::string file_path) +int Xdf::WriteEventsToXdf(std::string file_path) { - if (userAddedStream) + if (user_added_stream_) { std::fstream file; file.open(file_path, std::ios::app | std::ios::binary); @@ -932,17 +932,17 @@ int Xdf::writeEventsToXDF(std::string file_path) //Num Length Bytes file.put(4); //length - int length = streams[userAddedStream].streamHeader.size() + 6; //+6 because of the length int itself and short int tag + int length = streams_[user_added_stream_].stream_header.size() + 6; //+6 because of the length int itself and short int tag file.write((char*)&length, 4); //tag short tag = 2; file.write((char*)&tag, 2); //streamNumber - int streamNumber = userAddedStream + 1; //+1 because the stream IDs in XDF are 1 based instead of 0 based + int streamNumber = user_added_stream_ + 1; //+1 because the stream IDs in XDF are 1 based instead of 0 based file.write((char*)&streamNumber, 4); //content - file.write(streams[userAddedStream].streamHeader.c_str(), length - 6);//length - 6 is the string length + file.write(streams_[user_added_stream_].stream_header.c_str(), length - 6);//length - 6 is the string length //write samples chunk //Num Length Bytes @@ -950,11 +950,11 @@ int Xdf::writeEventsToXDF(std::string file_path) //length //add the bytes of all following actions together int64_t stringTotalLength = 0; - for (auto const &event : userCreatedEvents) + for (auto const &event : user_created_events_) stringTotalLength += event.first.size(); int64_t sampleChunkLength = 2 + 4 + 1 + 4 + - userCreatedEvents.size() * + user_created_events_.size() * (1 + 8 + 1 + 4) + stringTotalLength; file.write((char*)&sampleChunkLength, 8); @@ -969,11 +969,11 @@ int Xdf::writeEventsToXDF(std::string file_path) file.put(4); //Num Samples - int numSamples = userCreatedEvents.size(); + int numSamples = user_created_events_.size(); file.write((char*)&numSamples, 4); //samples - for (auto const &event : userCreatedEvents) + for (auto const &event : user_created_events_) { //TimeStampBytes file.put(8); @@ -1007,60 +1007,60 @@ int Xdf::writeEventsToXDF(std::string file_path) return 0; //Success } -void Xdf::createLabels() +void Xdf::CreateLabels() { size_t channelCount = 0; - for (size_t st = 0; st < streams.size(); st++) + for (size_t st = 0; st < streams_.size(); st++) { - if (streams[st].info.channels.size()) + if (streams_[st].info.channels.size()) { - for (size_t ch = 0; ch < streams[st].info.channels.size(); ch++) + for (size_t ch = 0; ch < streams_[st].info.channels.size(); ch++) { // +1 for 1 based numbers; for user convenience only. The internal computation is still 0 based std::string label = "Stream " + std::to_string(st + 1) + " - Channel " + std::to_string(ch + 1) - + " - " + std::to_string((int)streams[st].info.nominal_srate) + " Hz\n"; + + " - " + std::to_string((int)streams_[st].info.nominal_srate) + " Hz\n"; - label += streams[st].info.name + '\n'; + label += streams_[st].info.name + '\n'; - for (auto const &entry : streams[st].info.channels[ch]) + for (auto const &entry : streams_[st].info.channels[ch]) { if (entry.second != "") label += entry.first + " : " + entry.second + '\n'; } - if (offsets.size()) + if (offsets_.size()) { - if (offsets[channelCount] >= 0) - label.append("baseline +").append(std::to_string(offsets[channelCount])); + if (offsets_[channelCount] >= 0) + label.append("baseline +").append(std::to_string(offsets_[channelCount])); else - label.append("baseline ").append(std::to_string(offsets[channelCount])); + label.append("baseline ").append(std::to_string(offsets_[channelCount])); } - labels.emplace_back(label); + labels_.emplace_back(label); channelCount++; } } else { - for (size_t ch = 0; ch < streams[st].time_series.size(); ch++) + for (size_t ch = 0; ch < streams_[st].time_series.size(); ch++) { // +1 for 1 based numbers; for user convenience only. The internal computation is still 0 based std::string label = "Stream " + std::to_string(st + 1) + " - Channel " + std::to_string(ch + 1) + " - " + - std::to_string((int)streams[st].info.nominal_srate) + - " Hz\n" + streams[st].info.name + '\n' + streams[st].info.type + '\n'; + std::to_string((int)streams_[st].info.nominal_srate) + + " Hz\n" + streams_[st].info.name + '\n' + streams_[st].info.type + '\n'; - label += streams[st].info.name + '\n'; + label += streams_[st].info.name + '\n'; - if (offsets.size()) + if (offsets_.size()) { - if (offsets[channelCount] >= 0) - label.append("baseline +").append(std::to_string(offsets[channelCount])); + if (offsets_[channelCount] >= 0) + label.append("baseline +").append(std::to_string(offsets_[channelCount])); else - label.append("baseline ").append(std::to_string(offsets[channelCount])); + label.append("baseline ").append(std::to_string(offsets_[channelCount])); } - labels.emplace_back(label); + labels_.emplace_back(label); channelCount++; } @@ -1068,26 +1068,26 @@ void Xdf::createLabels() } } -void Xdf::loadDictionary() +void Xdf::LoadDictionary() { //loop through the eventMap - for (auto const &entry : eventMap) + for (auto const &entry : event_map_) { //search the dictionary to see whether an event is already in it - auto it = std::find(dictionary.begin(),dictionary.end(),entry.first.first); + auto it = std::find(dictionary_.begin(),dictionary_.end(),entry.first.first); //if it isn't yet - if (it == dictionary.end()) + if (it == dictionary_.end()) { //add it to the dictionary, also store its index into eventType vector for future use - eventType.emplace_back(dictionary.size()); - dictionary.emplace_back(entry.first.first); + event_type_.emplace_back(dictionary_.size()); + dictionary_.emplace_back(entry.first.first); } //if it's already in there else //store its index into eventType vector - eventType.emplace_back(std::distance(dictionary.begin(), it)); + event_type_.emplace_back(std::distance(dictionary_.begin(), it)); } } -template T Xdf::readBin(std::istream& is, T* obj) { +template T Xdf::ReadBin(std::istream& is, T* obj) { T dummy; if(!obj) obj = &dummy; is.read(reinterpret_cast(obj), sizeof(T)); diff --git a/xdf.h b/xdf.h index 86892f3..5890c03 100644 --- a/xdf.h +++ b/xdf.h @@ -29,9 +29,9 @@ /*! \class Xdf * - * Xdf class is designed to store the data of an entire XDF file. - * It comes with methods to read XDF files and containers to store - * the data, as well as some additional methods e.g. resampling etc. + * Xdf class stores the data of an entire XDF file. It contains methods to + * read XDF files and containers to store the data, as well as additional + * methods such as resampling etc. */ class Xdf @@ -40,277 +40,248 @@ class Xdf //! Default constructor with no parameter. Xdf(); - //subclass for single streams /*! \class Stream * * XDF files uses stream as the unit to store data. An XDF file usually - * contains multiple streams, while each of them may contain one or more - * channels. - * The Stream class provides a handy way to store all the meta-data, - * time-series, time-stamps and all other information of a single stream - * from an XDF file. + * contains multiple streams, each of which may contain one or more + * channels. The Stream struct provides a way to store meta-data, time-series, + * time-stamps and all other information of a single stream from an XDF file. */ struct Stream { - //! A 2D vector which stores the time series of a stream. Each row represents a channel. - std::vector > time_series; - std::vector time_stamps; /*!< A vector to store time stamps. */ - std::string streamHeader; /*!< Raw XML of stream header chunk. */ - std::string streamFooter; /*!< Raw XML of stream footer chunk. */ + std::vector> time_series; /*!< 2D vector that stores the time series of a stream. Each row represents a channel.*/ + std::vector time_stamps; /*!< Stores the time stamps. */ + std::string stream_header; /*!< Raw XML of stream header chunk. */ + std::string stream_footer; /*!< Raw XML of stream footer chunk. */ struct { - int channel_count; /*!< Number of channels of the current stream */ - double nominal_srate; /*!< The nominal sample rate of the current stream. */ - std::string name; /*!< Name of the current stream. */ - std::string type; /*!< Type of the current stream. */ - std::string channel_format;/*!< Channel format of the current stream. */ - - std::vector > channels;/*!< A vector to store the meta-data of the channels of the current stream. */ - - std::vector > clock_offsets; /*!< A vector to store clock offsets from the ClockOffset chunk. */ - - double first_timestamp; /*!< First time stamp of the stream. */ - double last_timestamp; /*!< Last time stamp of the stream. */ - int sample_count; /*!< Sample count of the stream. */ - double measured_srate; /*!< Measured sample rate of the stream. */ - double effective_sample_rate = 0;/*!< Effective sample rate. */ - } info; /*!< Meta-data from the stream header of the current stream. */ - - double last_timestamp{ 0 }; /*!< For temporary use while loading the vector */ - double sampling_interval; /*!< If srate > 0, sampling_interval = 1/srate; otherwise 0 */ - std::vector clock_times;/*!< Vector of clock times from clock offset chunk (Tag 4). */ - std::vector clock_values;/*!< Vector of clock values from clock offset chunk (Tag 4). */ + int channel_count; /*!< Number of channels in the current stream */ + double nominal_srate; /*!< The nominal sampling rate of the current stream. */ + std::string name; /*!< The name of the current stream. */ + std::string type; /*!< The type of the current stream. */ + std::string channel_format; /*!< The channel format of the current stream. */ + + std::vector > channels; /*!< Stores the meta-data of the channels of the current stream. */ + + std::vector > clock_offsets; /*!< Stores the clock offsets from the ClockOffset chunk. */ + + double first_timestamp; /*!< First time stamp of the stream. */ + double last_timestamp; /*!< Last time stamp of the stream. */ + int sample_count; /*!< Sample count of the stream. */ + double measured_sampling_rate; /*!< Measured sampling rate of the stream. */ + double effective_sampling_rate = 0; /*!< Effective sampling rate. */ + } info; /*!< Meta-data from the stream header of the current stream. */ + + double last_timestamp{0}; /*!< For temporary use while loading the vector */ + double sampling_interval; /*!< sampling_interval = 1/sampling_rate if sampling_rate > 0, otherwise 0 */ + std::vector clock_times; /*!< Stores the clock times from clock offset chunks. */ + std::vector clock_values; /*!< Stores the clock values from clock offset chunks. */ }; - //XDF properties================================================================================= + std::vector streams_; /*!< Stores all streams of the current XDF file. */ + float version_; /*!< The version of the XDF file. */ - std::vector streams; /*!< A vector to store all the streams of the current XDF file. */ - float version; /*!< The version of XDF file */ + uint64_t total_len_ = 0; /*!< The total length is the product of the range between the smallest time stamp and the largest multiplied by major_sampling_rate_. */ - uint64_t totalLen = 0; /*!< The total length is the product of the range between the smallest - *time stamp and the largest multiplied by the major sample rate. */ - - double minTS = 0; /*!< The smallest time stamp across all streams. */ - double maxTS = 0; /*!< The largest time stamp across all streams. */ - size_t totalCh = 0; /*!< The total number of channel count. */ - int majSR = 0; /*!< The sample rate that has the most channels across all streams. */ - int maxSR = 0; /*!< Highest sample rate across all streams. */ - std::vector effectiveSampleRateVector; /*!< Effective Sample Rate of each stream. */ - double fileEffectiveSampleRate = 0; /*!< If effective sample rates in all the streams are the same, this is the value. */ - std::vector streamMap;/*!< A vector indexes which channels belong to which stream. - * The index is the same as channel number; the actual content is the stream Number */ + double min_timestamp_ = 0; /*!< The min time stamp across all streams. */ + double max_timestamp_ = 0; /*!< The max time stamp across all streams. */ + size_t channel_count_ = 0; /*!< The total number of channels. */ + int major_sampling_rate_ = 0; /*!< The sampling rate that was used by the most channels across all streams. */ + int max_sampling_rate_ = 0; /*!< Max sampling rate across all streams. */ + std::vector effective_sampling_rates_; /*!< Effective sampling rates of streams. */ + double file_effective_sampling_rate_ = 0; /*!< If effective_sampling_rates_ in all the streams are the same, this is the value. */ + std::vector stream_map_; /*!< Indexes which channels belong to which stream. The index is the same as channel number; the actual content is the stream number. */ /*! - * \brief Used as `std::vector, int> >` - * in eventMap. + * \brief An alias of std::string type used on event names. * \sa eventMap */ - typedef std::string eventName; + typedef std::string event_name_; /*! - * \brief Used as `std::vector, int> >` - * in eventMap. + * \brief An alias of double type used on event timestamps. * \sa eventMap */ - typedef double eventTimeStamp; - - std::vector, int> > eventMap;/*!< The vector to store all the events across all streams. - * The format is <, streamNum>. */ - std::vector dictionary;/*!< The vector to store unique event types with no repetitions. \sa eventMap */ - std::vector eventType; /*!< The vector to store events by their index in the dictionary.\sa dictionary, eventMap */ - std::vector labels; /*!< The vector to store descriptive labels of each channel. */ - std::set sampleRateMap; /*!< The vector to store all sample rates across all the streams. */ - std::vector offsets; /*!< Offsets of each channel after using subtractMean() function */ + typedef double event_timestamp_; - std::string fileHeader; /*!< Raw XML of the file header. */ - int userAddedStream { 0 }; /*!< For Sigviewer only: if user manually added events in Sigviewer, - * the events will be stored in a new stream after all current streams. - * The index will be userAddedStream. */ - std::vector > userCreatedEvents;/*!< User created events in Sigviewer. */ + std::vector, int>> event_map_; /*!< Stores all events across all streams. */ + std::vector dictionary_; /*!< Stores unique event types with no repetitions. \sa eventMap */ + std::vector event_type_; /*!< Stores events by their indices in the dictionary.\sa dictionary, eventMap */ + std::vector labels_; /*!< Stores descriptive labels of each channel. */ + std::set sampling_rate_map_; /*!< Stores sampling rates of all the streams. */ + std::vector offsets_; /*!< Offsets of each channel after using SubtractMean() method. */ - //Public Functions============================================================================================== + std::string file_header_; /*!< Raw XML of the file header. */ + int user_added_stream_{0}; /*!< Used by SigViewer only: if user manually added events in SigViewer, the events will be stored in a new stream after all current streams with index user_added_stream_. */ + std::vector > user_created_events_; /*!< Events created by user in SigViewer. */ /*! - * \brief Adjust `totalLen` to avoid possible deviation + * \brief Adjusts `total_len_` to avoid possible deviation. * - * `totalLen` is calculated by multiplying the difference between max time - * stamp and minimal time stamp by the `majSR` (major sample rate). + * `total_len_` is calculated by multiplying the difference between + * `max_timestamp_` and `min_timestamp_` by `major_sampling_rate_`. * However, this can be inaccurate. In case any channel is longer than - * `totalLen`, this function will make `totalLen` match the length of - * that channel. + * `total_len_`, this function will make `total_len_` match the length + * of that channel. * - * \sa totalLen, majSR, calcTotalLength() + * \sa total_len_, major_sampling_rate_, CalculateTotalLength() */ - void adjustTotalLength(); + void AdjustTotalLength(); /*! - * \brief Calculate the globle length (in samples). + * \brief Calculates the globle length (in samples). * - * This is calculated by multiplying the rage from the earliest - * time stamp to the last time stamp across all channels by the - * parameter sampleRate. + * This is calculated by multiplying the rage from `min_timestamp_` + * to `max_timestamp_` across all channels by `sampling_rate`. * - * \param sampleRate is the sample rate you wish to use to calculate the - * total length. + * \param sampling_rate The sampling rate used to calculate the total + * length. */ - void calcTotalLength(int sampleRate); + void CalculateTotalLength(int sampling_rate); /*! - * \brief Create labels for each channel and store them in _labels_ vector. - * \sa labels, offsets + * \brief Creates labels for each channel and stores them in `labels_`. + * \sa labels_, offsets_ */ - void createLabels(); + void CreateLabels(); /*! - * \brief Subtract the entire channel by its mean. + * \brief Subtracts all data in a channel by the mean. * - * Sigviewer displays both the channel signals as well as the zero baseline. - * Thus when the mean of a channel is too high or too low it would be very - * hard to see the fluctuation. Subtract the entire channel by its mean - * will make the signal fluctuate around the zero baseline, and has better - * visual effect. The mean of each channel times `-1` will be stored in - * member vector `offsets` + * SigViewer displays both the channel signals as well as the zero baseline. + * When the mean of a channel is too high or too low it becomes difficult to + * see the fluctuation. Subtracting the entire channel by its mean makes the + * signals fluctuate around the zero baseline, thus having better visual + * effect. The mean of each channel times `-1` is stored in `offsets_`. * - * \sa offsets + * \sa offsets_ */ - void detrend(); + void Detrend(); /*! - * \brief Delete the time stamps vectors when no longer needed to - * release some memory. + * \brief Deletes `Stream::time_stamps` when no longer needed (to release + * memory). * - * Sigviewer doesn't demand time stamps to display signals except - * irregular sample rate channels, events, and the first time stamp - * of each channel (used to decide where does a channel start when - * putting all streams together). In this case we can delete the time - * stamps when no longer needed to free up some memory. + * SigViewer doesn't demand time stamps to display signals except irregular + * sampling rate channels, events, and the min timestamp of each channel + * (used to determine where does a channel start when putting all streams + * together). Hence `Stream::time_stamps` can be deleted when no longer + * needed to free up the memory. */ - void freeUpTimeStamps(); + void FreeUpTimeStamps(); /*! - * \brief The main function of loading an XDF file. - * \param filename is the path to the file being loaded including the - * file name. + * \brief Loads an XDF file. + * \param filename The complete path to the target file. */ - int load_xdf(std::string filename); + int LoadXdf(std::string filename); /*! - * \brief Resample all streams and channel to a chosen sample rate - * \param userSrate is recommended to be between integer 1 and - * the highest sample rate of the current file. + * \brief Resamples all streams and channels to `sampling_rate`. + * \param `sampling_rate` in general should be between 1 and the highest + * sampling rate of the current file. */ - void resample(int userSrate); + void Resample(int sampling_rate); /*! - * \brief syncTimeStamps + * \brief Sync the timestamps. */ - void syncTimeStamps(); + void SyncTimeStamps(); /*! - * \brief writeEventsToXDF - * - * If user added some markups and events in Sigviewer, this function can - * store those user created events back to the XDF file in a new stream + * \brief Writes events to the XDF file. Used when user added markups + * and/or events in SigViewer, this method stores the newly created events + * to the XDF file in a new stream. */ - int writeEventsToXDF(std::string file_path); - - //Private Functions: Not intended to be used by external programs====================================== + int WriteEventsToXdf(std::string file_path); private: /*! - * \brief calcEffectiveSrate + * \brief Calculates the effective sampling rate. */ - void calcEffectiveSrate(); + void CalculateEffectiveSamplingRate(); /*! - * \brief Calculate the total channel count and store the result - * in `totalCh`. - * - * Channels of both regular and irregular sample rates are included. - * The streams with the channel format `string` are excluded, and are - * stored in `eventMap` instead. + * \brief Calculates the channel count and stores the result in + * `channel_count_`. Channels of both regular and irregular sampling rates + * are included. Streams with channel format `string` are excluded, and are + * stored in `event_map_` instead. * - * \sa totalCh, eventMap + * \sa channel_count_, event_map_ */ - void calcTotalChannel(); + void CalculateChannelCount(); /*! - * \brief Find the sample rate that has the most channels. + * \brief Finds the sampling rate that is used by the most channels. * * XDF format supports different sample rates across streams, but - * Sigviewer needs to display all channels in a unified sample rate. - * Thus if there are more than one sample rate in the file, some channels - * need to be resampled in order to be displayed. - * - * Libxdf uses third party _smarc_ library to do the resampling task. - * While _smarc_ library is powerful in the sense that it can resample - * signals to almost any sample rate, it's fairly slow, and for performance - * reason it's better to minimize the resampling process. + * SigViewer needs to display all channels in a unified sampling rate. + * If a file contains more than one sampling rate, some channels need + * to be resampled to be displayed. This method finds the sampling + * rate that was used by the most channels thus minimizing the number + * of channels to be resampled. * - * findMajSR() will find which sample rate currently has the most channels - * in the file. If only those channels with a different sample rate are to - * be resampled, the resampling process will be finished in the shortest - * possible period. - * - * \sa majSR, resample(int userSrate) + * \sa major_sampling_rate_, Resample(int sampling_rate) */ - void findMajSR(); + void FindMajorSamplingRate(); /*! - * \brief Find the minimal and maximal time stamps across all streams. + * \brief Finds the max sampling rate of all streams and store it in `max_sampling_rate_`. * - * The results will be stored in member variables `minTS` and `maxTS` respectively. - * \sa minTS, maxTS, calcTotalLength(int sampleRate); + * \sa max_sampling_rate_ */ - void findMinMax(); + void FindMaxSampleRate(); /*! - * \brief Get the highest sample rate of all streams and store - * it in `maxSR`. - * - * \sa maxSR + * \brief Finds the min and max timestamps across all streams. The + * results are stored in `min_timestamp_` and `max_timestamp_`. + * \sa min_timestamp_, max_timestamp_, CalculateTotalLength(int sampling_rate); */ - void getHighestSampleRate(); + void FindMinMaxTimeStamps(); /*! - * \brief Copy all unique types of events from _eventMap_ to - * _dictionary_ with no repeats. - * \sa dictionary, eventMap + * \brief Copies all unique types of events from `event_map_` to + * `dictionary_` excluding duplicates. + * \sa event_map_, dictionary_ */ - void loadDictionary(); + void LoadDictionary(); /*! - * \brief Load every sample rate appeared in the current file into - * member variable `sampleRateMap`. - * \sa sampleRateMap + * \brief Loads every sampling rate that appeared in the current file + * into `sampling_rate_map_`. + * \sa sampling_rate_map_ */ - void loadSampleRateMap(); + void LoadSamplingRateMap(); /*! - * \brief This function will get the length of the upcoming chunk, or the number of samples. + * \brief Gets the length of the upcoming chunk, or the number of samples. + * + * While loading XDF file there are two cases where this method are needed. + * One is to get the length of each chunk, the other is to get the number + * of samples when loading the time series (Chunk tag 3). * - * While loading XDF file there are 2 cases where this function will be - * needed. One is to get the length of each chunk, one is to get the - * number of samples when loading the time series (Chunk tag 3). - * \param file is the XDF file that is being loaded in the type of `std::ifstream`. + * \param file The XDF file that is being loaded in the type of `std::ifstream`. * \return The length of the upcoming chunk (in bytes). */ - uint64_t readLength(std::ifstream &file); + uint64_t ReadLength(std::ifstream &file); - /*! - * \brief Read a binary scalar variable from an input stream. + /*! + * \brief Reads a binary scalar variable from an input stream. + * + * This method is a convenience wrapper for the common + * `file.read((char*) var, sizeof(var))` operation. Examples: + * + * ``` + * double foo = readBin(file); // use return value + * ReadBin(file, &foo); // read directly into foo + * ``` * - * readBin is a convenience wrapper for the common - * file.read((char*) var, sizeof(var)) - * operation. Examples: - * double foo = readBin(file); // use return value - * readBin(file, &foo); // read directly into foo - * \param is an input stream to read from - * \param obj pointer to a variable to load the data into or nullptr - * \return the read data + * \param is An input stream to read from. + * \param obj Pointer to a variable to load the data into or nullptr. + * \return The read data. */ - template T readBin(std::istream& is, T* obj = nullptr); + template T ReadBin(std::istream& is, T* obj = nullptr); }; #endif // XDF_H From 55cc8ddab146aab5cd94a7385c2068aa6c6c9259 Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 14:19:57 -0700 Subject: [PATCH 02/10] Switch to snake_case() --- xdf.cpp | 168 ++++++++++++++++++++++++++++---------------------------- xdf.h | 82 +++++++++++++-------------- 2 files changed, 125 insertions(+), 125 deletions(-) diff --git a/xdf.cpp b/xdf.cpp index ae448e3..6823841 100644 --- a/xdf.cpp +++ b/xdf.cpp @@ -33,7 +33,7 @@ Xdf::Xdf() { } -int Xdf::LoadXdf(std::string filename) +int Xdf::load_xdf(std::string filename) { clock_t time; time = clock(); @@ -79,13 +79,13 @@ int Xdf::LoadXdf(std::string filename) //for each chunk while (1) { - uint64_t ChLen = ReadLength(file);//chunk length + uint64_t ChLen = read_length(file);//chunk length if (ChLen == 0) break; uint16_t tag; //read tag of the chunk, 6 possibilities - ReadBin(file, &tag); + read_bin(file, &tag); switch (tag) { @@ -111,7 +111,7 @@ int Xdf::LoadXdf(std::string filename) //read [StreamID] uint32_t streamID; int index; - Xdf::ReadBin(file, &streamID); + Xdf::read_bin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; if (it == idmap.end()) { @@ -162,7 +162,7 @@ int Xdf::LoadXdf(std::string filename) //read [StreamID] uint32_t streamID; int index; - Xdf::ReadBin(file, &streamID); + Xdf::read_bin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; if (it == idmap.end()) { @@ -175,7 +175,7 @@ int Xdf::LoadXdf(std::string filename) //read [NumSampleBytes], [NumSamples] - uint64_t numSamp = ReadLength(file); + uint64_t numSamp = read_length(file); //check the data type if (streams_[index].info.channel_format.compare("float32") == 0) @@ -188,19 +188,19 @@ int Xdf::LoadXdf(std::string filename) for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = ReadBin(file); + auto tsBytes = read_bin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::ReadBin(file, &ts); - streams_[index].time_stamps.emplace_back(ts); + Xdf::read_bin(file, &ts); + streams_[index].timestamps.emplace_back(ts); } else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].time_stamps.emplace_back(ts); + streams_[index].timestamps.emplace_back(ts); } streams_[index].last_timestamp = ts; @@ -209,7 +209,7 @@ int Xdf::LoadXdf(std::string filename) for (int v = 0; v < streams_[index].info.channel_count; ++v) { float data; - Xdf::ReadBin(file, &data); + Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } @@ -224,19 +224,19 @@ int Xdf::LoadXdf(std::string filename) for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = ReadBin(file); + auto tsBytes = read_bin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::ReadBin(file, &ts); - streams_[index].time_stamps.emplace_back(ts); + Xdf::read_bin(file, &ts); + streams_[index].timestamps.emplace_back(ts); } else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].time_stamps.emplace_back(ts); + streams_[index].timestamps.emplace_back(ts); } streams_[index].last_timestamp = ts; @@ -245,7 +245,7 @@ int Xdf::LoadXdf(std::string filename) for (int v = 0; v < streams_[index].info.channel_count; ++v) { double data; - Xdf::ReadBin(file, &data); + Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } @@ -260,19 +260,19 @@ int Xdf::LoadXdf(std::string filename) for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = ReadBin(file); + auto tsBytes = read_bin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::ReadBin(file, &ts); - streams_[index].time_stamps.emplace_back(ts); + Xdf::read_bin(file, &ts); + streams_[index].timestamps.emplace_back(ts); } else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].time_stamps.emplace_back(ts); + streams_[index].timestamps.emplace_back(ts); } streams_[index].last_timestamp = ts; @@ -281,7 +281,7 @@ int Xdf::LoadXdf(std::string filename) for (int v = 0; v < streams_[index].info.channel_count; ++v) { int8_t data; - Xdf::ReadBin(file, &data); + Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } @@ -296,19 +296,19 @@ int Xdf::LoadXdf(std::string filename) for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = ReadBin(file); + auto tsBytes = read_bin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::ReadBin(file, &ts); - streams_[index].time_stamps.emplace_back(ts); + Xdf::read_bin(file, &ts); + streams_[index].timestamps.emplace_back(ts); } else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].time_stamps.emplace_back(ts); + streams_[index].timestamps.emplace_back(ts); } streams_[index].last_timestamp = ts; @@ -317,7 +317,7 @@ int Xdf::LoadXdf(std::string filename) for (int v = 0; v < streams_[index].info.channel_count; ++v) { int16_t data; - Xdf::ReadBin(file, &data); + Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } @@ -332,19 +332,19 @@ int Xdf::LoadXdf(std::string filename) for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = ReadBin(file); + auto tsBytes = read_bin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::ReadBin(file, &ts); - streams_[index].time_stamps.emplace_back(ts); + Xdf::read_bin(file, &ts); + streams_[index].timestamps.emplace_back(ts); } else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].time_stamps.emplace_back(ts); + streams_[index].timestamps.emplace_back(ts); } streams_[index].last_timestamp = ts; @@ -353,7 +353,7 @@ int Xdf::LoadXdf(std::string filename) for (int v = 0; v < streams_[index].info.channel_count; ++v) { int32_t data; - Xdf::ReadBin(file, &data); + Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } @@ -368,19 +368,19 @@ int Xdf::LoadXdf(std::string filename) for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = ReadBin(file); + auto tsBytes = read_bin(file); double ts; //temporary time stamp if (tsBytes == 8) { - Xdf::ReadBin(file, &ts); - streams_[index].time_stamps.emplace_back(ts); + Xdf::read_bin(file, &ts); + streams_[index].timestamps.emplace_back(ts); } else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].time_stamps.emplace_back(ts); + streams_[index].timestamps.emplace_back(ts); } streams_[index].last_timestamp = ts; @@ -389,7 +389,7 @@ int Xdf::LoadXdf(std::string filename) for (int v = 0; v < streams_[index].info.channel_count; ++v) { int64_t data; - Xdf::ReadBin(file, &data); + Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } @@ -400,17 +400,17 @@ int Xdf::LoadXdf(std::string filename) for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp - auto tsBytes = ReadBin(file); + auto tsBytes = read_bin(file); double ts; //temporary time stamp if (tsBytes == 8) - Xdf::ReadBin(file, &ts); + Xdf::read_bin(file, &ts); else ts = streams_[index].last_timestamp + streams_[index].sampling_interval; //read the event - auto length = Xdf::ReadLength(file); + auto length = Xdf::read_length(file); char* buffer = new char[length + 1]; file.read(buffer, length); @@ -426,7 +426,7 @@ int Xdf::LoadXdf(std::string filename) { uint32_t streamID; int index; - Xdf::ReadBin(file, &streamID); + Xdf::read_bin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; if (it == idmap.end()) { @@ -441,8 +441,8 @@ int Xdf::LoadXdf(std::string filename) double collectionTime; double offsetValue; - Xdf::ReadBin(file, &collectionTime); - Xdf::ReadBin(file, &offsetValue); + Xdf::read_bin(file, &collectionTime); + Xdf::read_bin(file, &offsetValue); streams_[index].clock_times.emplace_back(collectionTime); streams_[index].clock_values.emplace_back(offsetValue); @@ -455,7 +455,7 @@ int Xdf::LoadXdf(std::string filename) //read [StreamID] uint32_t streamID; int index; - Xdf::ReadBin(file, &streamID); + Xdf::read_bin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; if (it == idmap.end()) { @@ -503,21 +503,21 @@ int Xdf::LoadXdf(std::string filename) //=============find the min and max time stamps============= //========================================================== - SyncTimeStamps(); + sync_timestamps(); - FindMinMaxTimeStamps(); + find_min_max_time_stamps(); - FindMajorSamplingRate(); + find_major_sampling_rate(); - FindMaxSampleRate(); + find_max_sampling_rate(); - LoadSamplingRateMap(); + load_sampling_rate_map(); - CalculateChannelCount(); + calculate_channel_count(); - LoadDictionary(); + load_dictionary(); - CalculateEffectiveSamplingRate(); + calculate_effective_sampling_rate(); //loading finishes, close file file.close(); @@ -531,7 +531,7 @@ int Xdf::LoadXdf(std::string filename) return 0; } -void Xdf::SyncTimeStamps() +void Xdf::sync_timestamps() { // Sync time stamps for (auto &stream : this->streams_) @@ -541,19 +541,19 @@ void Xdf::SyncTimeStamps() size_t m = 0; // index iterating through stream.time_stamps size_t n = 0; // index iterating through stream.clock_times - while (m < stream.time_stamps.size()) + while (m < stream.timestamps.size()) { - if (stream.clock_times[n] < stream.time_stamps[m]) + if (stream.clock_times[n] < stream.timestamps[m]) { - while (n < stream.clock_times.size() - 1 && stream.clock_times[n+1] < stream.time_stamps[m]) + while (n < stream.clock_times.size() - 1 && stream.clock_times[n+1] < stream.timestamps[m]) { n++; } - stream.time_stamps[m] += stream.clock_values[n]; + stream.timestamps[m] += stream.clock_values[n]; } else if (n == 0) { - stream.time_stamps[m] += stream.clock_values[n]; + stream.timestamps[m] += stream.clock_values[n]; } m++; } @@ -612,13 +612,13 @@ void Xdf::SyncTimeStamps() } else { - streams_[k].info.first_timestamp = streams_[k].time_stamps.front(); - streams_[k].info.last_timestamp = streams_[k].time_stamps.back(); + streams_[k].info.first_timestamp = streams_[k].timestamps.front(); + streams_[k].info.last_timestamp = streams_[k].timestamps.back(); } } } -void Xdf::Resample(int sampling_rate) +void Xdf::resample(int sampling_rate) { //if user entered a preferred sample rate, we resample all the channels to that sample rate //Otherwise, we resample all channels to the sample rate that has the most channels @@ -699,9 +699,9 @@ void Xdf::Resample(int sampling_rate) //====================================================================== - CalculateTotalLength(sampling_rate); + calculate_total_length(sampling_rate); - AdjustTotalLength(); + adjust_total_length(); time = clock() - time; @@ -710,22 +710,22 @@ void Xdf::Resample(int sampling_rate) } //function of reading the length of each chunk -uint64_t Xdf::ReadLength(std::ifstream &file) +uint64_t Xdf::read_length(std::ifstream &file) { uint8_t bytes; - Xdf::ReadBin(file, &bytes); + Xdf::read_bin(file, &bytes); uint64_t length = 0; switch (bytes) { case 1: - length = ReadBin(file); + length = read_bin(file); break; case 4: - length = ReadBin(file); + length = read_bin(file); break; case 8: - length = ReadBin(file); + length = read_bin(file); break; default: std::cout << "Invalid variable-length integer length (" @@ -736,7 +736,7 @@ uint64_t Xdf::ReadLength(std::ifstream &file) return length; } -void Xdf::FindMinMaxTimeStamps() +void Xdf::find_min_max_time_stamps() { //find the smallest timestamp of all streams for (auto const &stream : streams_) @@ -761,7 +761,7 @@ void Xdf::FindMinMaxTimeStamps() } } -void Xdf::FindMajorSamplingRate() +void Xdf::find_major_sampling_rate() { // find out which sample rate has the most channels typedef int sampRate; @@ -803,7 +803,7 @@ void Xdf::FindMajorSamplingRate() } } -void Xdf::CalculateChannelCount() +void Xdf::calculate_channel_count() { //calculating total channel count, and indexing them onto streamMap for (size_t c = 0; c < streams_.size(); c++) @@ -818,29 +818,29 @@ void Xdf::CalculateChannelCount() } } -void Xdf::CalculateTotalLength(int sampling_rate) +void Xdf::calculate_total_length(int sampling_rate) { total_len_ = (max_timestamp_ - min_timestamp_) * sampling_rate; } -void Xdf::FreeUpTimeStamps() +void Xdf::free_up_timestamps() { //free up as much memory as possible for (auto &stream : streams_) { //we don't need to keep all the time stamps unless it's a stream with irregular samples //filter irregular streams and string streams - if (stream.info.nominal_srate != 0 && !stream.time_stamps.empty() && stream.info.channel_format.compare("string")) + if (stream.info.nominal_srate != 0 && !stream.timestamps.empty() && stream.info.channel_format.compare("string")) { std::vector nothing; //however we still need to keep the first time stamp of each stream to decide at which position the signal should start - nothing.emplace_back(stream.time_stamps.front()); - stream.time_stamps.swap(nothing); + nothing.emplace_back(stream.timestamps.front()); + stream.timestamps.swap(nothing); } } } -void Xdf::AdjustTotalLength() +void Xdf::adjust_total_length() { for (auto const &stream : streams_) { @@ -852,7 +852,7 @@ void Xdf::AdjustTotalLength() } } -void Xdf::FindMaxSampleRate() +void Xdf::find_max_sampling_rate() { for (auto const &stream : streams_) { @@ -861,13 +861,13 @@ void Xdf::FindMaxSampleRate() } } -void Xdf::LoadSamplingRateMap() +void Xdf::load_sampling_rate_map() { for (auto const &stream : streams_) sampling_rate_map_.emplace(stream.info.nominal_srate); } -void Xdf::Detrend() +void Xdf::detrend() { for (auto &stream : streams_) { @@ -881,7 +881,7 @@ void Xdf::Detrend() } } -void Xdf::CalculateEffectiveSamplingRate() +void Xdf::calculate_effective_sampling_rate() { for (auto &stream : streams_) { @@ -918,7 +918,7 @@ void Xdf::CalculateEffectiveSamplingRate() } } -int Xdf::WriteEventsToXdf(std::string file_path) +int Xdf::write_events_to_xdf(std::string file_path) { if (user_added_stream_) { @@ -1007,7 +1007,7 @@ int Xdf::WriteEventsToXdf(std::string file_path) return 0; //Success } -void Xdf::CreateLabels() +void Xdf::create_labels() { size_t channelCount = 0; @@ -1068,7 +1068,7 @@ void Xdf::CreateLabels() } } -void Xdf::LoadDictionary() +void Xdf::load_dictionary() { //loop through the eventMap for (auto const &entry : event_map_) @@ -1087,7 +1087,7 @@ void Xdf::LoadDictionary() } } -template T Xdf::ReadBin(std::istream& is, T* obj) { +template T Xdf::read_bin(std::istream& is, T* obj) { T dummy; if(!obj) obj = &dummy; is.read(reinterpret_cast(obj), sizeof(T)); diff --git a/xdf.h b/xdf.h index 5890c03..700b529 100644 --- a/xdf.h +++ b/xdf.h @@ -29,9 +29,9 @@ /*! \class Xdf * - * Xdf class stores the data of an entire XDF file. It contains methods to - * read XDF files and containers to store the data, as well as additional - * methods such as resampling etc. + * Xdf class stores the data of an XDF file. It contains methods to read + * XDF files, store the data, and additional functionalities such as + * resampling etc. */ class Xdf @@ -44,13 +44,13 @@ class Xdf * * XDF files uses stream as the unit to store data. An XDF file usually * contains multiple streams, each of which may contain one or more - * channels. The Stream struct provides a way to store meta-data, time-series, - * time-stamps and all other information of a single stream from an XDF file. + * channels. The Stream struct stores meta-data, time series, timetamps + * and other information of a stream. */ struct Stream { - std::vector> time_series; /*!< 2D vector that stores the time series of a stream. Each row represents a channel.*/ - std::vector time_stamps; /*!< Stores the time stamps. */ + std::vector> time_series; /*!< Stores the time series of a stream. Each row represents a channel.*/ + std::vector timestamps; /*!< Stores the timestamps. */ std::string stream_header; /*!< Raw XML of stream header chunk. */ std::string stream_footer; /*!< Raw XML of stream footer chunk. */ @@ -62,12 +62,11 @@ class Xdf std::string type; /*!< The type of the current stream. */ std::string channel_format; /*!< The channel format of the current stream. */ - std::vector > channels; /*!< Stores the meta-data of the channels of the current stream. */ - + std::vector> channels; /*!< Stores the metadata of the channels of the current stream. */ std::vector > clock_offsets; /*!< Stores the clock offsets from the ClockOffset chunk. */ - double first_timestamp; /*!< First time stamp of the stream. */ - double last_timestamp; /*!< Last time stamp of the stream. */ + double first_timestamp; /*!< First timestamp of the stream. */ + double last_timestamp; /*!< Last timestamp of the stream. */ int sample_count; /*!< Sample count of the stream. */ double measured_sampling_rate; /*!< Measured sampling rate of the stream. */ double effective_sampling_rate = 0; /*!< Effective sampling rate. */ @@ -82,16 +81,16 @@ class Xdf std::vector streams_; /*!< Stores all streams of the current XDF file. */ float version_; /*!< The version of the XDF file. */ - uint64_t total_len_ = 0; /*!< The total length is the product of the range between the smallest time stamp and the largest multiplied by major_sampling_rate_. */ + uint64_t total_len_ = 0; /*!< The total length is the product of the range between the min timestamp and the max timestamp multiplied by major_sampling_rate_. */ - double min_timestamp_ = 0; /*!< The min time stamp across all streams. */ - double max_timestamp_ = 0; /*!< The max time stamp across all streams. */ + double min_timestamp_ = 0; /*!< The min timestamp across all streams. */ + double max_timestamp_ = 0; /*!< The max timestamp across all streams. */ size_t channel_count_ = 0; /*!< The total number of channels. */ int major_sampling_rate_ = 0; /*!< The sampling rate that was used by the most channels across all streams. */ int max_sampling_rate_ = 0; /*!< Max sampling rate across all streams. */ std::vector effective_sampling_rates_; /*!< Effective sampling rates of streams. */ double file_effective_sampling_rate_ = 0; /*!< If effective_sampling_rates_ in all the streams are the same, this is the value. */ - std::vector stream_map_; /*!< Indexes which channels belong to which stream. The index is the same as channel number; the actual content is the stream number. */ + std::vector stream_map_; /*!< Indexes which channels belong to which stream. The keys are channel numbers, the values are stream numbers. */ /*! * \brief An alias of std::string type used on event names. @@ -105,14 +104,14 @@ class Xdf typedef double event_timestamp_; std::vector, int>> event_map_; /*!< Stores all events across all streams. */ - std::vector dictionary_; /*!< Stores unique event types with no repetitions. \sa eventMap */ - std::vector event_type_; /*!< Stores events by their indices in the dictionary.\sa dictionary, eventMap */ + std::vector dictionary_; /*!< Stores unique event types with no repetitions. \sa event_map_ */ + std::vector event_type_; /*!< Stores events by their indices in the dictionary.\sa dictionary_, event_map_ */ std::vector labels_; /*!< Stores descriptive labels of each channel. */ std::set sampling_rate_map_; /*!< Stores sampling rates of all the streams. */ - std::vector offsets_; /*!< Offsets of each channel after using SubtractMean() method. */ + std::vector offsets_; /*!< Offsets of each channel after using the `detrend` method. \sa detrend() */ std::string file_header_; /*!< Raw XML of the file header. */ - int user_added_stream_{0}; /*!< Used by SigViewer only: if user manually added events in SigViewer, the events will be stored in a new stream after all current streams with index user_added_stream_. */ + int user_added_stream_{0}; /*!< Used by SigViewer only: if user manually added events in SigViewer, the events will be stored in a new stream after all current streams with index `user_added_stream_`. */ std::vector > user_created_events_; /*!< Events created by user in SigViewer. */ /*! @@ -124,12 +123,12 @@ class Xdf * `total_len_`, this function will make `total_len_` match the length * of that channel. * - * \sa total_len_, major_sampling_rate_, CalculateTotalLength() + * \sa total_len_, major_sampling_rate_, calculate_total_length() */ - void AdjustTotalLength(); + void adjust_total_length(); /*! - * \brief Calculates the globle length (in samples). + * \brief Calculates the global length (in samples). * * This is calculated by multiplying the rage from `min_timestamp_` * to `max_timestamp_` across all channels by `sampling_rate`. @@ -137,13 +136,13 @@ class Xdf * \param sampling_rate The sampling rate used to calculate the total * length. */ - void CalculateTotalLength(int sampling_rate); + void calculate_total_length(int sampling_rate); /*! * \brief Creates labels for each channel and stores them in `labels_`. * \sa labels_, offsets_ */ - void CreateLabels(); + void create_labels(); /*! * \brief Subtracts all data in a channel by the mean. @@ -156,7 +155,7 @@ class Xdf * * \sa offsets_ */ - void Detrend(); + void detrend(); /*! * \brief Deletes `Stream::time_stamps` when no longer needed (to release @@ -168,39 +167,39 @@ class Xdf * together). Hence `Stream::time_stamps` can be deleted when no longer * needed to free up the memory. */ - void FreeUpTimeStamps(); + void free_up_timestamps(); /*! * \brief Loads an XDF file. * \param filename The complete path to the target file. */ - int LoadXdf(std::string filename); + int load_xdf(std::string filename); /*! * \brief Resamples all streams and channels to `sampling_rate`. * \param `sampling_rate` in general should be between 1 and the highest * sampling rate of the current file. */ - void Resample(int sampling_rate); + void resample(int sampling_rate); /*! * \brief Sync the timestamps. */ - void SyncTimeStamps(); + void sync_timestamps(); /*! * \brief Writes events to the XDF file. Used when user added markups * and/or events in SigViewer, this method stores the newly created events * to the XDF file in a new stream. */ - int WriteEventsToXdf(std::string file_path); + int write_events_to_xdf(std::string file_path); private: /*! * \brief Calculates the effective sampling rate. */ - void CalculateEffectiveSamplingRate(); + void calculate_effective_sampling_rate(); /*! * \brief Calculates the channel count and stores the result in @@ -210,7 +209,7 @@ class Xdf * * \sa channel_count_, event_map_ */ - void CalculateChannelCount(); + void calculate_channel_count(); /*! * \brief Finds the sampling rate that is used by the most channels. @@ -222,37 +221,38 @@ class Xdf * rate that was used by the most channels thus minimizing the number * of channels to be resampled. * - * \sa major_sampling_rate_, Resample(int sampling_rate) + * \sa major_sampling_rate_, resample(int sampling_rate) */ - void FindMajorSamplingRate(); + void find_major_sampling_rate(); /*! * \brief Finds the max sampling rate of all streams and store it in `max_sampling_rate_`. * * \sa max_sampling_rate_ */ - void FindMaxSampleRate(); + void find_max_sampling_rate(); /*! * \brief Finds the min and max timestamps across all streams. The * results are stored in `min_timestamp_` and `max_timestamp_`. - * \sa min_timestamp_, max_timestamp_, CalculateTotalLength(int sampling_rate); + * + * \sa min_timestamp_, max_timestamp_, calculate_total_length(int sampling_rate); */ - void FindMinMaxTimeStamps(); + void find_min_max_time_stamps(); /*! * \brief Copies all unique types of events from `event_map_` to * `dictionary_` excluding duplicates. * \sa event_map_, dictionary_ */ - void LoadDictionary(); + void load_dictionary(); /*! * \brief Loads every sampling rate that appeared in the current file * into `sampling_rate_map_`. * \sa sampling_rate_map_ */ - void LoadSamplingRateMap(); + void load_sampling_rate_map(); /*! * \brief Gets the length of the upcoming chunk, or the number of samples. @@ -264,7 +264,7 @@ class Xdf * \param file The XDF file that is being loaded in the type of `std::ifstream`. * \return The length of the upcoming chunk (in bytes). */ - uint64_t ReadLength(std::ifstream &file); + uint64_t read_length(std::ifstream &file); /*! * \brief Reads a binary scalar variable from an input stream. @@ -281,7 +281,7 @@ class Xdf * \param obj Pointer to a variable to load the data into or nullptr. * \return The read data. */ - template T ReadBin(std::istream& is, T* obj = nullptr); + template T read_bin(std::istream& is, T* obj = nullptr); }; #endif // XDF_H From 913e98127c8419a07131ad1845143a752b4f3a0a Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 14:39:35 -0700 Subject: [PATCH 03/10] Updated README.md --- README.md | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index e94b609..7a50263 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## Introduction -Libxdf is a cross-platform C++ library for loading multimodal, multi-rate signals stored in [XDF](https://github.com/sccn/xdf/wiki/Specifications "Extensible Data Format") files. +Libxdf is a cross-platform C++ library for loading multi-modal, multi-rate signals stored in [XDF](https://github.com/sccn/xdf/wiki/Specifications "Extensible Data Format") files. Libxdf is used in the biosignal viewing application [SigViewer](https://github.com/cbrnr/sigviewer). It can also be integrated into other C++ applications. @@ -57,35 +57,32 @@ Example: ```C++ #include "xdf.h" -Xdf XDFdata; -XDFdata.load_xdf("C:/example.xdf"); +Xdf xdf; +xdf.load_xdf("C:/example.xdf"); ``` -To resample the signals to e.g. 100Hz: +To resample the signals, e.g. to 100Hz: ```C++ -XDFdata.resample(100); +xdf.resample(100); ``` -The functions in libxdf must be called following a certain order. For instance, if you call the `subtractMean` function before you load any data, it will cause undefined behavior. +The methods in libxdf must be called following a certain order. For instance, if you call the `detrend` method before you load any data, it will cause undefined behavior. The recommended order is shown here. Only `load_xdf` is mandatory. ```C++ -XDFdata.load_xdf(std::string filepath); -XDFdata.subtractMean(); -XDFdata.createLabels(); -XDFdata.resample(int sampleRate); -XDFdata.freeUpTimeStamps(); +xdf.load_xdf(std::string filepath); +xdf.detrend(); +xdf.create_labels(); +xdf.resample(int sampling_rate); +xdf.free_up_time_stamps(); ``` Libxdf depends on third party libraries [Pugixml v1.8](http://pugixml.org/) for XML parsing and [Smarc](http://audio-smarc.sourceforge.net/) for resampling. ## Documentation -Detailed documentation was generated via [Doxygen](http://www.stack.nl/~dimitri/doxygen/index.html) and is available [here](docs/html/class_xdf.html). - -## SigViewer Online Repo -SigViewer Online Repository is [here](repository/Updates.xml). +[Documentation](docs/html/class_xdf.html) was generated via [Doxygen](http://www.stack.nl/~dimitri/doxygen/index.html). ## Support From a02393f2c6ddca4cf6f8be282645d2dd40472631 Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 14:46:34 -0700 Subject: [PATCH 04/10] Updated docs with Doxygen --- docs/html/annotated.html | 52 +- docs/html/class_xdf-members.html | 115 +- docs/html/class_xdf.html | 482 ++-- docs/html/classes.html | 62 +- docs/html/doxygen.css | 350 ++- docs/html/dynsections.js | 28 +- docs/html/files.html | 63 +- docs/html/functions.html | 193 +- docs/html/functions_func.html | 77 +- docs/html/functions_type.html | 60 +- docs/html/functions_vars.html | 160 +- docs/html/index.html | 54 +- docs/html/jquery.js | 94 +- docs/html/md__r_e_a_d_m_e.html | 143 + docs/html/menu.js | 27 +- docs/html/menudata.js | 111 +- docs/html/pages.html | 54 +- docs/html/search/all_0.html | 14 +- docs/html/search/all_0.js | 2 +- docs/html/search/all_1.html | 14 +- docs/html/search/all_1.js | 10 +- docs/html/search/all_10.html | 14 +- docs/html/search/all_10.js | 3 +- docs/html/search/all_2.html | 14 +- docs/html/search/all_2.js | 10 +- docs/html/search/all_3.html | 14 +- docs/html/search/all_3.js | 8 +- docs/html/search/all_4.html | 14 +- docs/html/search/all_4.js | 9 +- docs/html/search/all_5.html | 14 +- docs/html/search/all_5.js | 4 +- docs/html/search/all_6.html | 14 +- docs/html/search/all_6.js | 5 +- docs/html/search/all_7.html | 14 +- docs/html/search/all_7.js | 9 +- docs/html/search/all_8.html | 14 +- docs/html/search/all_8.js | 7 +- docs/html/search/all_9.html | 14 +- docs/html/search/all_9.js | 3 +- docs/html/search/all_a.html | 14 +- docs/html/search/all_a.js | 2 +- docs/html/search/all_b.html | 14 +- docs/html/search/all_b.js | 11 +- docs/html/search/all_c.html | 14 +- docs/html/search/all_c.js | 12 +- docs/html/search/all_d.html | 14 +- docs/html/search/all_d.js | 7 +- docs/html/search/all_e.html | 14 +- docs/html/search/all_e.js | 3 +- docs/html/search/all_f.html | 14 +- docs/html/search/all_f.js | 2 +- docs/html/search/classes_0.html | 14 +- docs/html/search/classes_0.js | 2 +- docs/html/search/classes_1.html | 14 +- docs/html/search/classes_1.js | 2 +- docs/html/search/files_0.html | 14 +- docs/html/search/files_0.js | 2 +- docs/html/search/functions_0.html | 14 +- docs/html/search/functions_0.js | 2 +- docs/html/search/functions_1.html | 14 +- docs/html/search/functions_1.js | 4 +- docs/html/search/functions_2.html | 14 +- docs/html/search/functions_2.js | 2 +- docs/html/search/functions_3.html | 14 +- docs/html/search/functions_3.js | 2 +- docs/html/search/functions_4.html | 14 +- docs/html/search/functions_4.js | 2 +- docs/html/search/functions_5.html | 14 +- docs/html/search/functions_5.js | 2 +- docs/html/search/functions_6.html | 14 +- docs/html/search/functions_6.js | 2 +- docs/html/search/functions_7.html | 14 +- docs/html/search/functions_7.js | 2 +- docs/html/search/functions_8.html | 14 +- docs/html/search/functions_8.js | 2 +- docs/html/search/mag_sel.png | Bin 563 -> 465 bytes docs/html/search/nomatches.html | 2 +- docs/html/search/pages_0.html | 14 +- docs/html/search/pages_0.js | 2 +- docs/html/search/search.js | 31 +- docs/html/search/search_l.png | Bin 604 -> 567 bytes docs/html/search/search_r.png | Bin 612 -> 553 bytes docs/html/search/searchdata.js | 15 +- docs/html/search/typedefs_0.html | 14 +- docs/html/search/typedefs_0.js | 4 +- docs/html/search/variables_0.html | 14 +- docs/html/search/variables_0.js | 13 +- docs/html/search/variables_1.html | 14 +- docs/html/search/variables_1.js | 2 +- docs/html/search/variables_2.html | 14 +- docs/html/search/variables_2.js | 7 +- docs/html/search/variables_3.html | 14 +- docs/html/search/variables_3.js | 5 +- docs/html/search/variables_4.html | 14 +- docs/html/search/variables_4.js | 2 +- docs/html/search/variables_5.html | 14 +- docs/html/search/variables_5.js | 4 +- docs/html/search/variables_6.html | 14 +- docs/html/search/variables_6.js | 10 +- docs/html/search/variables_7.html | 14 +- docs/html/search/variables_7.js | 4 +- docs/html/search/variables_8.html | 14 +- docs/html/search/variables_8.js | 2 +- docs/html/search/variables_9.html | 14 +- docs/html/search/variables_9.js | 14 +- docs/html/search/variables_a.html | 14 +- docs/html/search/variables_a.js | 9 +- docs/html/search/variables_b.html | 14 +- docs/html/search/variables_b.js | 4 +- docs/html/search/variables_c.html | 14 +- docs/html/search/variables_c.js | 2 +- docs/html/struct_xdf_1_1_stream-members.html | 83 +- docs/html/struct_xdf_1_1_stream.html | 217 +- docs/html/tabs.css | 2 +- docs/html/xdf_8h.html | 55 +- docs/html/xdf_8h_source.html | 278 +- docs/latex/annotated.tex | 5 + docs/latex/class_xdf.tex | 360 +++ docs/latex/doxygen.sty | 576 ++++ docs/latex/files.tex | 4 + docs/latex/longtable_doxygen.sty | 448 +++ docs/latex/make.bat | 31 + docs/latex/md__r_e_a_d_m_e.tex | 79 + docs/latex/refman.tex | 197 ++ docs/latex/struct_xdf_1_1_stream.tex | 174 ++ docs/latex/tabu_doxygen.sty | 2557 ++++++++++++++++++ docs/latex/xdf_8h.tex | 23 + 127 files changed, 6597 insertions(+), 1498 deletions(-) create mode 100644 docs/html/md__r_e_a_d_m_e.html create mode 100644 docs/latex/annotated.tex create mode 100644 docs/latex/class_xdf.tex create mode 100644 docs/latex/doxygen.sty create mode 100644 docs/latex/files.tex create mode 100644 docs/latex/longtable_doxygen.sty create mode 100644 docs/latex/make.bat create mode 100644 docs/latex/md__r_e_a_d_m_e.tex create mode 100644 docs/latex/refman.tex create mode 100644 docs/latex/struct_xdf_1_1_stream.tex create mode 100644 docs/latex/tabu_doxygen.sty create mode 100644 docs/latex/xdf_8h.tex diff --git a/docs/html/annotated.html b/docs/html/annotated.html index 1796cb7..75b3253 100644 --- a/docs/html/annotated.html +++ b/docs/html/annotated.html @@ -1,21 +1,14 @@ - + - + -libxdf: Class List +Libxdf: Class List - - - - - @@ -28,44 +21,32 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */ -
- -
-
-
- -
- - + diff --git a/docs/html/class_xdf-members.html b/docs/html/class_xdf-members.html index 3634bf4..b266cde 100644 --- a/docs/html/class_xdf-members.html +++ b/docs/html/class_xdf-members.html @@ -1,21 +1,14 @@ - + - + -libxdf: Member List +Libxdf: Member List - - - - - @@ -28,44 +21,31 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */ - -
- -
-
-
- -
+
- - + diff --git a/docs/html/class_xdf.html b/docs/html/class_xdf.html index 41c7802..d0d0e24 100644 --- a/docs/html/class_xdf.html +++ b/docs/html/class_xdf.html @@ -1,21 +1,14 @@ - + - + -libxdf: Xdf Class Reference +Libxdf: Xdf Class Reference - - - - - @@ -28,44 +21,31 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */ - -
- -
-
-
- -
+
Classes | @@ -101,148 +82,138 @@ - - - - - - + + + + + +

Public Types

typedef std::string eventName
 Used as std::vector<std::pair<std::pair<eventName, eventTimeStamp>, int> > in eventMap. More...
 
typedef float eventTimeStamp
 Used as std::vector<std::pair<std::pair<eventName, eventTimeStamp>, int> > in eventMap. More...
 
typedef std::string event_name_
 An alias of std::string type used on event names. More...
 
typedef double event_timestamp_
 An alias of double type used on event timestamps. More...
 
- - + + - - - - - - - - - + + + + + + + + + - + - - - + + + - + - - - - - - + + + + + + + + +

Public Member Functions

 Xdf ()
 Default constructor with no parameter. More...
Xdf ()
 Default constructor with no parameter.
 
void adjustTotalLength ()
 Adjust totalLen to avoid possible deviation. More...
 
void calcTotalLength (int sampleRate)
 Calculate the globle length (in samples). More...
 
void createLabels ()
 Create labels for each channel and store them in labels vector. More...
 
void adjust_total_length ()
 Adjusts total_len_ to avoid possible deviation. More...
 
void calculate_total_length (int sampling_rate)
 Calculates the global length (in samples). More...
 
void create_labels ()
 Creates labels for each channel and stores them in labels_. More...
 
void detrend ()
 Subtract the entire channel by its mean. More...
 Subtracts all data in a channel by the mean. More...
 
void freeUpTimeStamps ()
 Delete the time stamps vectors when no longer needed to release some memory. More...
 
void free_up_timestamps ()
 Deletes Stream::time_stamps when no longer needed (to release memory). More...
 
int load_xdf (std::string filename)
 The main function of loading an XDF file. More...
 Loads an XDF file. More...
 
void resample (int userSrate)
 Resample all streams and channel to a chosen sample rate. More...
 
int writeEventsToXDF (std::string file_path)
 writeEventsToXDF More...
 
void resample (int sampling_rate)
 Resamples all streams and channels to sampling_rate. More...
 
+void sync_timestamps ()
 Sync the timestamps.
 
+int write_events_to_xdf (std::string file_path)
 Writes events to the XDF file. Used when user added markups and/or events in SigViewer, this method stores the newly created events to the XDF file in a new stream.
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Attributes

std::vector< Streamstreams
 
float version
 
uint64_t totalLen = 0
 
float minTS = 0
 
float maxTS = 0
 
size_t totalCh = 0
 
int majSR = 0
 
int maxSR = 0
 
std::vector< int > streamMap
 
std::vector< std::pair< std::pair< eventName, eventTimeStamp >, int > > eventMap
 
std::vector< std::string > dictionary
 
std::vector< uint16_t > eventType
 
std::vector< std::string > labels
 
std::set< double > sampleRateMap
 
std::vector< float > offsets
 
std::string fileHeader
 
int userAddedStream { 0 }
 
std::vector< std::pair< std::string, double > > userCreatedEvents
 
std::vector< Streamstreams_
 
float version_
 
uint64_t total_len_ = 0
 
double min_timestamp_ = 0
 
double max_timestamp_ = 0
 
size_t channel_count_ = 0
 
int major_sampling_rate_ = 0
 
int max_sampling_rate_ = 0
 
std::vector< double > effective_sampling_rates_
 
double file_effective_sampling_rate_ = 0
 
std::vector< int > stream_map_
 
std::vector< std::pair< std::pair< event_name_, event_timestamp_ >, int > > event_map_
 
std::vector< std::string > dictionary_
 
std::vector< uint16_t > event_type_
 
std::vector< std::string > labels_
 
std::set< double > sampling_rate_map_
 
std::vector< float > offsets_
 
std::string file_header_
 
int user_added_stream_ {0}
 
std::vector< std::pair< std::string, double > > user_created_events_
 

Detailed Description

-

Xdf class is designed to store the data of an entire XDF file. It comes with methods to read XDF files and containers to store the data, as well as some additional methods e.g. resampling etc.

+

Xdf class stores the data of an XDF file. It contains methods to read XDF files, store the data, and additional functionalities such as resampling etc.

Member Typedef Documentation

- -

§ eventName

+ +

◆ event_name_

- +
typedef std::string Xdf::eventNametypedef std::string Xdf::event_name_
-

Used as std::vector<std::pair<std::pair<eventName, eventTimeStamp>, int> > in eventMap.

-
See also
eventMap
+

An alias of std::string type used on event names.

+
See also
eventMap
- -

§ eventTimeStamp

+ +

◆ event_timestamp_

- +
typedef float Xdf::eventTimeStamptypedef double Xdf::event_timestamp_
-

Used as std::vector<std::pair<std::pair<eventName, eventTimeStamp>, int> > in eventMap.

-
See also
eventMap
- -
-
-

Constructor & Destructor Documentation

- -

§ Xdf()

- -
-
- - - - - - - -
Xdf::Xdf ()
-
- -

Default constructor with no parameter.

+

An alias of double type used on event timestamps.

+
See also
eventMap

Member Function Documentation

- -

§ adjustTotalLength()

+ +

◆ adjust_total_length()

- + @@ -250,47 +221,47 @@

-

Adjust totalLen to avoid possible deviation.

-

totalLen is calculated by multiplying the difference between max time stamp and minimal time stamp by the majSR (major sample rate). However, this can be inaccurate. In case any channel is longer than totalLen, this function will make totalLen match the length of that channel.

-
See also
totalLen, majSR, calcTotalLength()
+

Adjusts total_len_ to avoid possible deviation.

+

total_len_ is calculated by multiplying the difference between max_timestamp_ and min_timestamp_ by major_sampling_rate_. However, this can be inaccurate. In case any channel is longer than total_len_, this function will make total_len_ match the length of that channel.

+
See also
total_len_, major_sampling_rate_, calculate_total_length()
- -

§ calcTotalLength()

+ +

◆ calculate_total_length()

void Xdf::adjustTotalLength void Xdf::adjust_total_length ( )
- + - +
void Xdf::calcTotalLength void Xdf::calculate_total_length ( int sampleRate)sampling_rate)
-

Calculate the globle length (in samples).

-

This is calculated by multiplying the rage from the earliest time stamp to the last time stamp across all channels by the parameter sampleRate.

+

Calculates the global length (in samples).

+

This is calculated by multiplying the rage from min_timestamp_ to max_timestamp_ across all channels by sampling_rate.

Parameters
- +
sampleRateis the sample rate you wish to use to calculate the total length.
sampling_rateThe sampling rate used to calculate the total length.
- -

§ createLabels()

+ +

◆ create_labels()

- + @@ -298,13 +269,13 @@

-

Create labels for each channel and store them in labels vector.

-
See also
labels, offsets
+

Creates labels for each channel and stores them in labels_.

+
See also
labels_, offsets_
-

§ detrend()

+

◆ detrend()

@@ -318,20 +289,20 @@

-

Subtract the entire channel by its mean.

-

Sigviewer displays both the channel signals as well as the zero baseline. Thus when the mean of a channel is too high or too low it would be very hard to see the fluctuation. Subtract the entire channel by its mean will make the signal fluctuate around the zero baseline, and has better visual effect. The mean of each channel times -1 will be stored in member vector offsets

-
See also
offsets
+

Subtracts all data in a channel by the mean.

+

SigViewer displays both the channel signals as well as the zero baseline. When the mean of a channel is too high or too low it becomes difficult to see the fluctuation. Subtracting the entire channel by its mean makes the signals fluctuate around the zero baseline, thus having better visual effect. The mean of each channel times -1 is stored in offsets_.

+
See also
offsets_

- -

§ freeUpTimeStamps()

+ +

◆ free_up_timestamps()

void Xdf::createLabels void Xdf::create_labels ( )
- + @@ -339,13 +310,13 @@

-

Delete the time stamps vectors when no longer needed to release some memory.

-

Sigviewer doesn't demand time stamps to display signals except irregular sample rate channels, events, and the first time stamp of each channel (used to decide where does a channel start when putting all streams together). In this case we can delete the time stamps when no longer needed to free up some memory.

+

Deletes Stream::time_stamps when no longer needed (to release memory).

+

SigViewer doesn't demand time stamps to display signals except irregular sampling rate channels, events, and the min timestamp of each channel (used to determine where does a channel start when putting all streams together). Hence Stream::time_stamps can be deleted when no longer needed to free up the memory.

-

§ load_xdf()

+

◆ load_xdf()

void Xdf::freeUpTimeStamps void Xdf::free_up_timestamps ( )
- +
filenameis the path to the file being loaded including the file name.
filenameThe complete path to the target file.
- -

§ resample()

+ +

◆ resample()

- -

§ writeEventsToXDF()

+

Member Data Documentation

+ +

◆ channel_count_

- - - - - +
int Xdf::writeEventsToXDF (std::string file_path)size_t Xdf::channel_count_ = 0
+

The total number of channels.

-

writeEventsToXDF

-

If user added some markups and events in Sigviewer, this function can store those user created events back to the XDF file in a new stream

+
+
+ +

◆ dictionary_

+ +
+
+ + + + +
std::vector<std::string> Xdf::dictionary_
+
+

Stores unique event types with no repetitions.

See also
event_map_
-

Member Data Documentation

- -

§ dictionary

+ +

◆ effective_sampling_rates_

- +
std::vector<std::string> Xdf::dictionarystd::vector<double> Xdf::effective_sampling_rates_
-

The vector to store unique event types with no repetitions.

See also
eventMap
+

Effective sampling rates of streams.

- -

§ eventMap

+ +

◆ event_map_

- +
std::vector<std::pair<std::pair<eventName, eventTimeStamp>, int> > Xdf::eventMapstd::vector<std::pair<std::pair<event_name_, event_timestamp_>, int> > Xdf::event_map_
-

The vector to store all the events across all streams. The format is <<events, timestamps>, streamNum>.

+

Stores all events across all streams.

- -

§ eventType

+ +

◆ event_type_

- +
std::vector<uint16_t> Xdf::eventTypestd::vector<uint16_t> Xdf::event_type_
-

The vector to store events by their index in the dictionary.

See also
dictionary, eventMap
+

Stores events by their indices in the dictionary.

See also
dictionary_, event_map_
- -

§ fileHeader

+ +

◆ file_effective_sampling_rate_

- +
std::string Xdf::fileHeaderdouble Xdf::file_effective_sampling_rate_ = 0
-

Raw XML of the file header.

+

If effective_sampling_rates_ in all the streams are the same, this is the value.

- -

§ labels

+ +

◆ file_header_

- +
std::vector<std::string> Xdf::labelsstd::string Xdf::file_header_
-

The vector to store descriptive labels of each channel.

+

Raw XML of the file header.

- -

§ majSR

+ +

◆ labels_

- +
int Xdf::majSR = 0std::vector<std::string> Xdf::labels_
-

The sample rate that has the most channels across all streams.

+

Stores descriptive labels of each channel.

- -

§ maxSR

+ +

◆ major_sampling_rate_

- +
int Xdf::maxSR = 0int Xdf::major_sampling_rate_ = 0
-

Highest sample rate across all streams.

+

The sampling rate that was used by the most channels across all streams.

- -

§ maxTS

+ +

◆ max_sampling_rate_

- +
float Xdf::maxTS = 0int Xdf::max_sampling_rate_ = 0
-

The largest time stamp across all streams.

+

Max sampling rate across all streams.

- -

§ minTS

+ +

◆ max_timestamp_

- +
float Xdf::minTS = 0double Xdf::max_timestamp_ = 0
-

The smallest time stamp across all streams.

+

The max timestamp across all streams.

- -

§ offsets

+ +

◆ min_timestamp_

- +
std::vector<float> Xdf::offsetsdouble Xdf::min_timestamp_ = 0
-

Offsets of each channel after using subtractMean() function

+

The min timestamp across all streams.

- -

§ sampleRateMap

+ +

◆ offsets_

- +
std::set<double> Xdf::sampleRateMapstd::vector<float> Xdf::offsets_
-

The vector to store all sample rates across all the streams.

+

Offsets of each channel after using the detrend method.

See also
detrend()
- -

§ streamMap

+ +

◆ sampling_rate_map_

- +
std::vector<int> Xdf::streamMapstd::set<double> Xdf::sampling_rate_map_
-

A vector indexes which channels belong to which stream. The index is the same as channel number; the actual content is the stream Number

+

Stores sampling rates of all the streams.

- -

§ streams

+ +

◆ stream_map_

- +
std::vector<Stream> Xdf::streamsstd::vector<int> Xdf::stream_map_
-

A vector to store all the streams of the current XDF file.

+

Indexes which channels belong to which stream. The keys are channel numbers, the values are stream numbers.

- -

§ totalCh

+ +

◆ streams_

- +
size_t Xdf::totalCh = 0std::vector<Stream> Xdf::streams_
-

The total number of channel count.

+

Stores all streams of the current XDF file.

- -

§ totalLen

+ +

◆ total_len_

- +
uint64_t Xdf::totalLen = 0uint64_t Xdf::total_len_ = 0
-

The total length is the product of the range between the smallest time stamp and the largest multiplied by the major sample rate.

+

The total length is the product of the range between the min timestamp and the max timestamp multiplied by major_sampling_rate_.

- -

§ userAddedStream

+ +

◆ user_added_stream_

- +
int Xdf::userAddedStream { 0 }int Xdf::user_added_stream_ {0}
-

For Sigviewer only: if user manually added events in Sigviewer, the events will be stored in a new stream after all current streams. The index will be userAddedStream.

+

Used by SigViewer only: if user manually added events in SigViewer, the events will be stored in a new stream after all current streams with index user_added_stream_.

- -

§ userCreatedEvents

+ +

◆ user_created_events_

- +
std::vector<std::pair<std::string, double> > Xdf::userCreatedEventsstd::vector<std::pair<std::string, double> > Xdf::user_created_events_
-

User created events in Sigviewer.

+

Events created by user in SigViewer.

- -

§ version

+ +

◆ version_

- +
float Xdf::versionfloat Xdf::version_
-

The version of XDF file

+

The version of the XDF file.


The documentation for this class was generated from the following files:
    -
  • C:/Users/Yida Lin/Documents/GitHub/libxdf/libxdf/xdf.h
  • -
  • C:/Users/Yida Lin/Documents/GitHub/libxdf/libxdf/xdf.cpp
  • +
  • xdf.h
  • +
  • xdf.cpp
-
- + diff --git a/docs/html/classes.html b/docs/html/classes.html index eeb2709..0591d7a 100644 --- a/docs/html/classes.html +++ b/docs/html/classes.html @@ -1,21 +1,14 @@ - + - + -libxdf: Class Index +Libxdf: Class Index - - - - - @@ -28,44 +21,32 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */
-
- -
-
-
- -
s | x
+ + + - + + +
  s  
-
  x  
-
  x  
+
Xdf::Stream   Xdf   
Xdf::Stream   Xdf   
s | x
- - + diff --git a/docs/html/doxygen.css b/docs/html/doxygen.css index a2cf15f..5e35db3 100644 --- a/docs/html/doxygen.css +++ b/docs/html/doxygen.css @@ -1,9 +1,13 @@ -/* The standard CSS for doxygen 1.8.12 */ +/* The standard CSS for doxygen 1.8.18 */ body, table, div, p, dl { font: 400 14px/22px Roboto,sans-serif; } +p.reference, p.definition { + font: 400 14px/22px Roboto,sans-serif; +} + /* @group Heading Levels */ h1.groupheader { @@ -49,17 +53,24 @@ dt { font-weight: bold; } -div.multicol { +ul.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; + column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; + column-count: 3; } p.startli, p.startdd { margin-top: 2px; } +th p.starttd, p.intertd, p.endtd { + font-size: 100%; + font-weight: 700; +} + p.starttd { margin-top: 0px; } @@ -76,6 +87,15 @@ p.endtd { margin-bottom: 2px; } +p.interli { +} + +p.interdd { +} + +p.intertd { +} + /* @end */ caption { @@ -130,12 +150,12 @@ a.qindex { a.qindexHL { font-weight: bold; background-color: #9CAFD4; - color: #ffffff; + color: #FFFFFF; border: 1px double #869DCA; } .contents a.qindexHL:visited { - color: #ffffff; + color: #FFFFFF; } a.el { @@ -159,6 +179,25 @@ dl.el { margin-left: -1cm; } +ul { + overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; @@ -173,8 +212,8 @@ pre.fragment { } div.fragment { - padding: 0px; - margin: 4px 8px 4px 2px; + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; background-color: #FBFCFD; border: 1px solid #C4CFE5; } @@ -244,7 +283,7 @@ span.lineno a:hover { div.ah, span.ah { background-color: black; font-weight: bold; - color: #ffffff; + color: #FFFFFF; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; @@ -320,7 +359,7 @@ img.formulaDsp { } -img.formulaInl { +img.formulaInl, img.inline { vertical-align: middle; } @@ -398,6 +437,13 @@ blockquote { padding: 0 12px 0 16px; } +blockquote.DocNodeRTL { + border-left: 0; + border-right: 2px solid #9CAFD4; + margin: 0 4px 0 24px; + padding: 0 16px 0 12px; +} + /* @end */ /* @@ -494,7 +540,7 @@ table.memberdecls { white-space: nowrap; } -.memItemRight { +.memItemRight, .memTemplItemRight { width: 100%; } @@ -662,17 +708,17 @@ dl.reflist dd { padding-left: 0px; } -.params .paramname, .retval .paramname { +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { font-weight: bold; vertical-align: top; } -.params .paramtype { +.params .paramtype, .tparams .paramtype { font-style: italic; vertical-align: top; } -.params .paramdir { +.params .paramdir, .tparams .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } @@ -1077,72 +1123,143 @@ div.headertitle padding: 5px 5px 5px 10px; } -dl -{ - padding: 0 0 0 10px; +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; } -/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ -dl.section -{ +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { margin-left: 0px; padding-left: 0px; } -dl.note -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #D0C000; +dl.section.DocNodeRTL { + margin-right: 0px; + padding-right: 0px; } -dl.warning, dl.attention -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #FF0000; +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; } -dl.pre, dl.post, dl.invariant -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #00D000; +dl.note.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; } -dl.deprecated -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #505050; +dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #FF0000; } -dl.todo -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #00C0E0; +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; } -dl.test -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #3030E0; +dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00D000; } -dl.bug -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #C08050; +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.deprecated.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.todo.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.test.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.bug.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #C08050; } dl.section dd { @@ -1211,6 +1328,11 @@ dl.section dd { text-align: center; } +.plantumlgraph +{ + text-align: center; +} + .diagraph { text-align: center; @@ -1254,6 +1376,11 @@ div.toc { width: 200px; } +.PageDocRTL-title div.toc { + float: left !important; + text-align: right; +} + div.toc li { background: url("bdwn.png") no-repeat scroll 0 5px transparent; font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; @@ -1262,6 +1389,12 @@ div.toc li { padding-top: 2px; } +.PageDocRTL-title div.toc li { + background-position-x: right !important; + padding-left: 0 !important; + padding-right: 10px; +} + div.toc h3 { font: bold 12px/1.2 Arial,FreeSans,sans-serif; color: #4665A2; @@ -1291,6 +1424,26 @@ div.toc li.level4 { margin-left: 45px; } +.PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +} + +.PageDocRTL-title div.toc li.level2 { + margin-left: 0 !important; + margin-right: 15px; +} + +.PageDocRTL-title div.toc li.level3 { + margin-left: 0 !important; + margin-right: 30px; +} + +.PageDocRTL-title div.toc li.level4 { + margin-left: 0 !important; + margin-right: 45px; +} + .inherit_header { font-weight: bold; color: gray; @@ -1404,7 +1557,7 @@ tr.heading h2 { } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { - border-top-color: #ffffff; + border-top-color: #FFFFFF; border-width: 10px; margin: 0px -10px; } @@ -1432,7 +1585,7 @@ tr.heading h2 { } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { - border-bottom-color: #ffffff; + border-bottom-color: #FFFFFF; border-width: 10px; margin: 0px -10px; } @@ -1459,7 +1612,7 @@ tr.heading h2 { left: 100%; } #powerTip.e:after { - border-left-color: #ffffff; + border-left-color: #FFFFFF; border-width: 10px; top: 50%; margin-top: -10px; @@ -1475,7 +1628,7 @@ tr.heading h2 { right: 100%; } #powerTip.w:after { - border-right-color: #ffffff; + border-right-color: #FFFFFF; border-width: 10px; top: 50%; margin-top: -10px; @@ -1506,3 +1659,72 @@ tr.heading h2 { } } +/* @group Markdown */ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + +.DocNodeRTL { + text-align: right; + direction: rtl; +} + +.DocNodeLTR { + text-align: left; + direction: ltr; +} + +table.DocNodeRTL { + width: auto; + margin-right: 0; + margin-left: auto; +} + +table.DocNodeLTR { + width: auto; + margin-right: auto; + margin-left: 0; +} + +tt, code, kbd, samp +{ + display: inline-block; + direction:ltr; +} +/* @end */ + +u { + text-decoration: underline; +} + diff --git a/docs/html/dynsections.js b/docs/html/dynsections.js index 85e1836..3174bd7 100644 --- a/docs/html/dynsections.js +++ b/docs/html/dynsections.js @@ -1,3 +1,27 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); @@ -15,7 +39,7 @@ function toggleVisibility(linkObj) summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); - } + } return false; } @@ -94,4 +118,4 @@ function toggleInherit(id) $(img).attr('src',src.substring(0,src.length-10)+'open.png'); } } - +/* @license-end */ diff --git a/docs/html/files.html b/docs/html/files.html index 0e25f7d..8080c0a 100644 --- a/docs/html/files.html +++ b/docs/html/files.html @@ -1,21 +1,14 @@ - + - + -libxdf: File List +Libxdf: File List - - - - - @@ -28,44 +21,32 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */ -
- -
-
-
- -
File List
-
Here is a list of all files with brief descriptions:
-
[detail level 12345]
- - - - - - +
Here is a list of all documented files with brief descriptions:
+
  Documents
  GitHub
  libxdf
  libxdf
 xdf.cpp
 xdf.hThe header file of Xdf class
+
 xdf.hThe header file of Xdf class
- - + diff --git a/docs/html/functions.html b/docs/html/functions.html index 69170e3..c76419e 100644 --- a/docs/html/functions.html +++ b/docs/html/functions.html @@ -1,21 +1,14 @@ - + - + -libxdf: Class Members +Libxdf: Class Members - - - - - @@ -28,44 +21,32 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */ -
- -
-
-
- -
-
Here is a list of all class members with links to the classes they belong to:
+
Here is a list of all documented class members with links to the class documentation for each member:

- a -

    -
  • adjustTotalLength() -: Xdf +
  • adjust_total_length() +: Xdf

- c -

    -
  • calcTotalLength() -: Xdf +
  • calculate_total_length() +: Xdf
  • channel_count : Xdf::Stream
  • +
  • channel_count_ +: Xdf +
  • channel_format : Xdf::Stream
  • @@ -112,8 +96,8 @@

    - c -

    @@ -122,54 +106,60 @@

    - d -

    • detrend() : Xdf
    • -
    • dictionary -: Xdf +
    • dictionary_ +: Xdf

    - e -

      -
    • effective_sample_rate -: Xdf::Stream +
    • effective_sampling_rate +: Xdf::Stream
    • -
    • eventMap -: Xdf +
    • effective_sampling_rates_ +: Xdf
    • -
    • eventName -: Xdf +
    • event_map_ +: Xdf
    • -
    • eventTimeStamp -: Xdf +
    • event_name_ +: Xdf
    • -
    • eventType -: Xdf +
    • event_timestamp_ +: Xdf +
    • +
    • event_type_ +: Xdf

    - f -

      -
    • fileHeader -: Xdf +
    • file_effective_sampling_rate_ +: Xdf +
    • +
    • file_header_ +: Xdf
    • first_timestamp : Xdf::Stream
    • -
    • freeUpTimeStamps() -: Xdf +
    • free_up_timestamps() +: Xdf

    - i -

    - l -

-
- + diff --git a/docs/html/functions_func.html b/docs/html/functions_func.html index f538984..cdcf6c7 100644 --- a/docs/html/functions_func.html +++ b/docs/html/functions_func.html @@ -1,21 +1,14 @@ - + - + -libxdf: Class Members - Functions +Libxdf: Class Members - Functions - - - - - @@ -28,44 +21,32 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */
-
- -
-
-
- -
 
    -
  • adjustTotalLength() -: Xdf +
  • adjust_total_length() +: Xdf
  • -
  • calcTotalLength() -: Xdf +
  • calculate_total_length() +: Xdf
  • -
  • createLabels() -: Xdf +
  • create_labels() +: Xdf
  • detrend() : Xdf
  • -
  • freeUpTimeStamps() -: Xdf +
  • free_up_timestamps() +: Xdf
  • load_xdf() : Xdf
  • resample() -: Xdf +: Xdf
  • -
  • writeEventsToXDF() -: Xdf +
  • sync_timestamps() +: Xdf +
  • +
  • write_events_to_xdf() +: Xdf
  • Xdf() : Xdf
-
- + diff --git a/docs/html/functions_type.html b/docs/html/functions_type.html index fe5d4f8..c2ea584 100644 --- a/docs/html/functions_type.html +++ b/docs/html/functions_type.html @@ -1,21 +1,14 @@ - + - + -libxdf: Class Members - Typedefs +Libxdf: Class Members - Typedefs - - - - - @@ -28,44 +21,32 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */ -
- -
-
-
- -
 
    -
  • eventName -: Xdf +
  • event_name_ +: Xdf
  • -
  • eventTimeStamp -: Xdf +
  • event_timestamp_ +: Xdf
-
- + diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html index 5e89b7f..5c3eba1 100644 --- a/docs/html/functions_vars.html +++ b/docs/html/functions_vars.html @@ -1,21 +1,14 @@ - + - + -libxdf: Class Members - Variables +Libxdf: Class Members - Variables - - - - - @@ -28,44 +21,32 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */ -
- -
-
-
- -
- c -
-
- + diff --git a/docs/html/index.html b/docs/html/index.html index 3f07825..e9a68fa 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -1,21 +1,14 @@ - + - + -libxdf: Main Page +Libxdf: Main Page - - - - - @@ -28,44 +21,32 @@ -
libxdf -  0.92 +
Libxdf
-
A static C++ library for loading XDF files
+
A C++ library for loading XDF files
- + +/* @license-end */ -
- -
-
-
- -
-
libxdf Documentation
+
Libxdf Documentation
- - + diff --git a/docs/html/jquery.js b/docs/html/jquery.js index f5343ed..103c32d 100644 --- a/docs/html/jquery.js +++ b/docs/html/jquery.js @@ -1,71 +1,26 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element +},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** + * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler + * Licensed under MIT + * @author Ariel Flesler + * @version 2.1.2 + */ +;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*! - * jQuery UI 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI - */ -(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! - * jQuery UI Widget 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Widget - */ -(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! - * jQuery UI Mouse 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Mouse - * - * Depends: - * jquery.ui.widget.js - */ -(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! - * jQuery hashchange event - v1.3 - 7/21/2010 - * http://benalman.com/projects/jquery-hashchange-plugin/ - * - * Copyright (c) 2010 "Cowboy" Ben Alman - * Dual licensed under the MIT and GPL licenses. - * http://benalman.com/about/license/ - */ -(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$(' + + + +
+
+
Libxdf - a C++ library for loading XDF files
+
+
+
+

+<a name="intro"></a>Introduction

+

Libxdf is a cross-platform C++ library for loading multi-modal, multi-rate signals stored in XDF files. Libxdf is used in the biosignal viewing application SigViewer. It can also be integrated into other C++ applications.

+

Libxdf is open-source, free, and actively maintained.

+

+<a name="download"></a>Download

+ +

+<a name="quick"></a>Quick-Start Guide

+

+Building libxdf

+

Libxdf can be conveniently built either using qmake or cmake. Configuration files for both build tools are included with the source.

+

cmake builds a static library by default, but you can build a shared library by setting the BUILD_SHARED_LIBS variable (e.g. -DBUILD_SHARED_LIBS=ON).

+

+Use in conjunction with <a href="https://github.com/cbrnr/sigviewer">SigViewer</a>

+

Libxdf is a built-in component of SigViewer. If you wish to build SigViewer from source, follow these steps:

+
    +
  1. Download xdf.h and libxdf.a from the release page.
  2. +
  3. Copy xdf.h into sigviewer/external/include
  4. +
  5. Copy libxdf.a into sigviewer/external/lib
  6. +
  7. Build and run Sigviewer
  8. +
+

SigViewer using _libxdf_ to display signals in XDF files

+

Example: SigViewer using libxdf to display signals in an XDF file.

+

+Use in other C++ applications

+
    +
  1. Build libxdf from source or use a pre-built binary release
  2. +
  3. Instantiate an object of the Xdf class and call the load_xdf method.
  4. +
+

Example:

+
{C++}
+
#include "xdf.h"
+
+
Xdf xdf;
+
xdf.load_xdf("C:/example.xdf");
+

To resample the signals, e.g. to 100Hz:

+
{C++}
+
xdf.resample(100);
+

The methods in libxdf must be called following a certain order. For instance, if you call the detrend method before you load any data, it will cause undefined behavior.

+

The recommended order is shown here. Only load_xdf is mandatory.

+
{C++}
+
xdf.load_xdf(std::string filepath);
+
xdf.detrend();
+
xdf.create_labels();
+
xdf.resample(int sampling_rate);
+
xdf.free_up_time_stamps();
+

Libxdf depends on third party libraries Pugixml v1.8 for XML parsing and Smarc for resampling.

+

+<a name="doc"></a> Documentation

+

Documentation was generated via Doxygen.

+

+<a name="support"></a>Support

+

Email author or report a new issue.

+
+
+ + + + diff --git a/docs/html/menu.js b/docs/html/menu.js index 97db4c2..d18a2fe 100644 --- a/docs/html/menu.js +++ b/docs/html/menu.js @@ -1,3 +1,27 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { function makeTree(data,relPath) { var result=''; @@ -17,10 +41,11 @@ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); if (searchEnabled) { if (serverSide) { - $('#main-menu').append('
  • '); + $('#main-menu').append('
  • '); } else { $('#main-menu').append('
  • '); } } $('#main-menu').smartmenus(); } +/* @license-end */ diff --git a/docs/html/menudata.js b/docs/html/menudata.js index 74ef9c9..712c8a5 100644 --- a/docs/html/menudata.js +++ b/docs/html/menudata.js @@ -1,46 +1,67 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file +*/ var menudata={children:[ -{text:'Main Page',url:'index.html'}, -{text:'Related Pages',url:'pages.html'}, -{text:'Classes',url:'annotated.html',children:[ -{text:'Class List',url:'annotated.html'}, -{text:'Class Index',url:'classes.html'}, -{text:'Class Members',url:'functions.html',children:[ -{text:'All',url:'functions.html',children:[ -{text:'a',url:'functions.html#index_a'}, -{text:'c',url:'functions.html#index_c'}, -{text:'d',url:'functions.html#index_d'}, -{text:'e',url:'functions.html#index_e'}, -{text:'f',url:'functions.html#index_f'}, -{text:'i',url:'functions.html#index_i'}, -{text:'l',url:'functions.html#index_l'}, -{text:'m',url:'functions.html#index_m'}, -{text:'n',url:'functions.html#index_n'}, -{text:'o',url:'functions.html#index_o'}, -{text:'r',url:'functions.html#index_r'}, -{text:'s',url:'functions.html#index_s'}, -{text:'t',url:'functions.html#index_t'}, -{text:'u',url:'functions.html#index_u'}, -{text:'v',url:'functions.html#index_v'}, -{text:'w',url:'functions.html#index_w'}, -{text:'x',url:'functions.html#index_x'}]}, -{text:'Functions',url:'functions_func.html'}, -{text:'Variables',url:'functions_vars.html',children:[ -{text:'c',url:'functions_vars.html#index_c'}, -{text:'d',url:'functions_vars.html#index_d'}, -{text:'e',url:'functions_vars.html#index_e'}, -{text:'f',url:'functions_vars.html#index_f'}, -{text:'i',url:'functions_vars.html#index_i'}, -{text:'l',url:'functions_vars.html#index_l'}, -{text:'m',url:'functions_vars.html#index_m'}, -{text:'n',url:'functions_vars.html#index_n'}, -{text:'o',url:'functions_vars.html#index_o'}, -{text:'s',url:'functions_vars.html#index_s'}, -{text:'t',url:'functions_vars.html#index_t'}, -{text:'u',url:'functions_vars.html#index_u'}, -{text:'v',url:'functions_vars.html#index_v'}]}, -{text:'Typedefs',url:'functions_type.html'}]}]}, -{text:'Files',url:'files.html',children:[ -{text:'File List',url:'files.html'}, -{text:'File Members',url:'globals.html',children:[ -{text:'All',url:'globals.html'}, -{text:'Macros',url:'globals_defs.html'}]}]}]} +{text:"Main Page",url:"index.html"}, +{text:"Related Pages",url:"pages.html"}, +{text:"Classes",url:"annotated.html",children:[ +{text:"Class List",url:"annotated.html"}, +{text:"Class Index",url:"classes.html"}, +{text:"Class Members",url:"functions.html",children:[ +{text:"All",url:"functions.html",children:[ +{text:"a",url:"functions.html#index_a"}, +{text:"c",url:"functions.html#index_c"}, +{text:"d",url:"functions.html#index_d"}, +{text:"e",url:"functions.html#index_e"}, +{text:"f",url:"functions.html#index_f"}, +{text:"i",url:"functions.html#index_i"}, +{text:"l",url:"functions.html#index_l"}, +{text:"m",url:"functions.html#index_m"}, +{text:"n",url:"functions.html#index_n"}, +{text:"o",url:"functions.html#index_o"}, +{text:"r",url:"functions.html#index_r"}, +{text:"s",url:"functions.html#index_s"}, +{text:"t",url:"functions.html#index_t"}, +{text:"u",url:"functions.html#index_u"}, +{text:"v",url:"functions.html#index_v"}, +{text:"w",url:"functions.html#index_w"}, +{text:"x",url:"functions.html#index_x"}]}, +{text:"Functions",url:"functions_func.html"}, +{text:"Variables",url:"functions_vars.html",children:[ +{text:"c",url:"functions_vars.html#index_c"}, +{text:"d",url:"functions_vars.html#index_d"}, +{text:"e",url:"functions_vars.html#index_e"}, +{text:"f",url:"functions_vars.html#index_f"}, +{text:"i",url:"functions_vars.html#index_i"}, +{text:"l",url:"functions_vars.html#index_l"}, +{text:"m",url:"functions_vars.html#index_m"}, +{text:"n",url:"functions_vars.html#index_n"}, +{text:"o",url:"functions_vars.html#index_o"}, +{text:"s",url:"functions_vars.html#index_s"}, +{text:"t",url:"functions_vars.html#index_t"}, +{text:"u",url:"functions_vars.html#index_u"}, +{text:"v",url:"functions_vars.html#index_v"}]}, +{text:"Typedefs",url:"functions_type.html"}]}]}, +{text:"Files",url:"files.html",children:[ +{text:"File List",url:"files.html"}]}]} diff --git a/docs/html/pages.html b/docs/html/pages.html index bb0b702..da4e95f 100644 --- a/docs/html/pages.html +++ b/docs/html/pages.html @@ -1,21 +1,14 @@ - + - + -libxdf: Related Pages +Libxdf: Related Pages - - - - - @@ -28,44 +21,32 @@
    -
    libxdf -  0.92 +
    Libxdf
    -
    A static C++ library for loading XDF files
    +
    A C++ library for loading XDF files
    - + +/* @license-end */
    -
    - -
    -
    -
    - - - + diff --git a/docs/html/search/all_0.html b/docs/html/search/all_0.html index 4359463..ea50fff 100644 --- a/docs/html/search/all_0.html +++ b/docs/html/search/all_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_0.js b/docs/html/search/all_0.js index e8f97bc..0315a96 100644 --- a/docs/html/search/all_0.js +++ b/docs/html/search/all_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['adjusttotallength',['adjustTotalLength',['../class_xdf.html#aa7dc1ef8c04216d703604bf868146428',1,'Xdf']]] + ['adjust_5ftotal_5flength_0',['adjust_total_length',['../class_xdf.html#ae19b9ae0ee92b8c93fc3fd5be2d2d97f',1,'Xdf']]] ]; diff --git a/docs/html/search/all_1.html b/docs/html/search/all_1.html index bc87ea8..86b0682 100644 --- a/docs/html/search/all_1.html +++ b/docs/html/search/all_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_1.js b/docs/html/search/all_1.js index aaf7538..05cd6d5 100644 --- a/docs/html/search/all_1.js +++ b/docs/html/search/all_1.js @@ -1,4 +1,12 @@ var searchData= [ - ['buf_5fsize',['BUF_SIZE',['../xdf_8cpp.html#a6821bafc3c88dfb2e433a095df9940c6',1,'xdf.cpp']]] + ['calculate_5ftotal_5flength_1',['calculate_total_length',['../class_xdf.html#a72175fdbb081994f05b388e5ba92c903',1,'Xdf']]], + ['channel_5fcount_2',['channel_count',['../struct_xdf_1_1_stream.html#ab8fb7c3d645305e84f90d919f698082c',1,'Xdf::Stream']]], + ['channel_5fcount_5f_3',['channel_count_',['../class_xdf.html#afb6d47c75ebc215eb14aaf9e80133a7f',1,'Xdf']]], + ['channel_5fformat_4',['channel_format',['../struct_xdf_1_1_stream.html#ad7b61b077e247ba57a18c182e285d0ad',1,'Xdf::Stream']]], + ['channels_5',['channels',['../struct_xdf_1_1_stream.html#a71d987a538d0819cdbd58120d1a79ef5',1,'Xdf::Stream']]], + ['clock_5foffsets_6',['clock_offsets',['../struct_xdf_1_1_stream.html#a6f6328f0746591a3a471048b6b9bd258',1,'Xdf::Stream']]], + ['clock_5ftimes_7',['clock_times',['../struct_xdf_1_1_stream.html#a6bc91dcf23e551a9adbc415b562f3a79',1,'Xdf::Stream']]], + ['clock_5fvalues_8',['clock_values',['../struct_xdf_1_1_stream.html#a988989603854812cb693e56ff352a753',1,'Xdf::Stream']]], + ['create_5flabels_9',['create_labels',['../class_xdf.html#ab81f7f275ab38269d76be6ad0fdc9e29',1,'Xdf']]] ]; diff --git a/docs/html/search/all_10.html b/docs/html/search/all_10.html index 16ffd9a..b910674 100644 --- a/docs/html/search/all_10.html +++ b/docs/html/search/all_10.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_10.js b/docs/html/search/all_10.js index 63ddc8e..eb73c87 100644 --- a/docs/html/search/all_10.js +++ b/docs/html/search/all_10.js @@ -1,4 +1,5 @@ var searchData= [ - ['writeeventstoxdf',['writeEventsToXDF',['../class_xdf.html#a072e657d7620d61080a15a215c691210',1,'Xdf']]] + ['xdf_53',['Xdf',['../class_xdf.html',1,'Xdf'],['../class_xdf.html#a7900b5a4f3792b9d59a5d43db821607e',1,'Xdf::Xdf()']]], + ['xdf_2eh_54',['xdf.h',['../xdf_8h.html',1,'']]] ]; diff --git a/docs/html/search/all_2.html b/docs/html/search/all_2.html index 0f777c2..ffa7873 100644 --- a/docs/html/search/all_2.html +++ b/docs/html/search/all_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_2.js b/docs/html/search/all_2.js index d0b785d..4946a6f 100644 --- a/docs/html/search/all_2.js +++ b/docs/html/search/all_2.js @@ -1,11 +1,5 @@ var searchData= [ - ['calctotallength',['calcTotalLength',['../class_xdf.html#a75ef15a72071fe0d36ef6311214518fe',1,'Xdf']]], - ['channel_5fcount',['channel_count',['../struct_xdf_1_1_stream.html#ab8fb7c3d645305e84f90d919f698082c',1,'Xdf::Stream']]], - ['channel_5fformat',['channel_format',['../struct_xdf_1_1_stream.html#ad7b61b077e247ba57a18c182e285d0ad',1,'Xdf::Stream']]], - ['channels',['channels',['../struct_xdf_1_1_stream.html#a71d987a538d0819cdbd58120d1a79ef5',1,'Xdf::Stream']]], - ['clock_5foffsets',['clock_offsets',['../struct_xdf_1_1_stream.html#a6f6328f0746591a3a471048b6b9bd258',1,'Xdf::Stream']]], - ['clock_5ftimes',['clock_times',['../struct_xdf_1_1_stream.html#a6bc91dcf23e551a9adbc415b562f3a79',1,'Xdf::Stream']]], - ['clock_5fvalues',['clock_values',['../struct_xdf_1_1_stream.html#a988989603854812cb693e56ff352a753',1,'Xdf::Stream']]], - ['createlabels',['createLabels',['../class_xdf.html#ad98829202c9ae64505c9ecc7796c8ddc',1,'Xdf']]] + ['detrend_10',['detrend',['../class_xdf.html#a4d2c5859af84542a15a80c906465f4e3',1,'Xdf']]], + ['dictionary_5f_11',['dictionary_',['../class_xdf.html#a37903ef2145466774f7bb57dd72fb428',1,'Xdf']]] ]; diff --git a/docs/html/search/all_3.html b/docs/html/search/all_3.html index ac9dbf9..f9df19b 100644 --- a/docs/html/search/all_3.html +++ b/docs/html/search/all_3.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_3.js b/docs/html/search/all_3.js index 70ce471..bf154b5 100644 --- a/docs/html/search/all_3.js +++ b/docs/html/search/all_3.js @@ -1,5 +1,9 @@ var searchData= [ - ['detrend',['detrend',['../class_xdf.html#a4d2c5859af84542a15a80c906465f4e3',1,'Xdf']]], - ['dictionary',['dictionary',['../class_xdf.html#a26a2b517f020dc9f188c2277c76add85',1,'Xdf']]] + ['effective_5fsampling_5frate_12',['effective_sampling_rate',['../struct_xdf_1_1_stream.html#a97a11401e85fd9f64a5601b15bbc7820',1,'Xdf::Stream']]], + ['effective_5fsampling_5frates_5f_13',['effective_sampling_rates_',['../class_xdf.html#a21852b079ed18afa0117d67755a2c68d',1,'Xdf']]], + ['event_5fmap_5f_14',['event_map_',['../class_xdf.html#ad92266c3c43f6a508d43040090479726',1,'Xdf']]], + ['event_5fname_5f_15',['event_name_',['../class_xdf.html#a57eb7fdd01251b7613a7d106625ff019',1,'Xdf']]], + ['event_5ftimestamp_5f_16',['event_timestamp_',['../class_xdf.html#a4cf524f9428b9438b70cb17ea3f2d547',1,'Xdf']]], + ['event_5ftype_5f_17',['event_type_',['../class_xdf.html#a6a98e5d14a159cc9b24460f2441d6b4e',1,'Xdf']]] ]; diff --git a/docs/html/search/all_4.html b/docs/html/search/all_4.html index 8308168..aa2c933 100644 --- a/docs/html/search/all_4.html +++ b/docs/html/search/all_4.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_4.js b/docs/html/search/all_4.js index 4f5d3a3..1aa301a 100644 --- a/docs/html/search/all_4.js +++ b/docs/html/search/all_4.js @@ -1,8 +1,7 @@ var searchData= [ - ['effective_5fsample_5frate',['effective_sample_rate',['../struct_xdf_1_1_stream.html#abeb1d2eb26a46eac34a478f04f5143d6',1,'Xdf::Stream']]], - ['eventmap',['eventMap',['../class_xdf.html#a45004fc495cad33768fae80b996a68db',1,'Xdf']]], - ['eventname',['eventName',['../class_xdf.html#a4e3322abfe4d533d6b7a96cbbea7271a',1,'Xdf']]], - ['eventtimestamp',['eventTimeStamp',['../class_xdf.html#a1fbf3d641262cc1daade33eca1789990',1,'Xdf']]], - ['eventtype',['eventType',['../class_xdf.html#a4acb87e86380bf7266976cd6c4cb3826',1,'Xdf']]] + ['file_5feffective_5fsampling_5frate_5f_18',['file_effective_sampling_rate_',['../class_xdf.html#a4e36c1e1588711d7d09d2aa26f800f2c',1,'Xdf']]], + ['file_5fheader_5f_19',['file_header_',['../class_xdf.html#abb8518a32a84995d60648d1c0fdd6428',1,'Xdf']]], + ['first_5ftimestamp_20',['first_timestamp',['../struct_xdf_1_1_stream.html#a22a44cb3cd533ea668f9bb20dbc299de',1,'Xdf::Stream']]], + ['free_5fup_5ftimestamps_21',['free_up_timestamps',['../class_xdf.html#a957461547bca42a5314dafaaf307c1ee',1,'Xdf']]] ]; diff --git a/docs/html/search/all_5.html b/docs/html/search/all_5.html index 7919cd4..71848af 100644 --- a/docs/html/search/all_5.html +++ b/docs/html/search/all_5.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_5.js b/docs/html/search/all_5.js index 13c9097..fb47476 100644 --- a/docs/html/search/all_5.js +++ b/docs/html/search/all_5.js @@ -1,6 +1,4 @@ var searchData= [ - ['fileheader',['fileHeader',['../class_xdf.html#a1e46bbbf31121fb394aa8cf5c10d10b0',1,'Xdf']]], - ['first_5ftimestamp',['first_timestamp',['../struct_xdf_1_1_stream.html#a22a44cb3cd533ea668f9bb20dbc299de',1,'Xdf::Stream']]], - ['freeuptimestamps',['freeUpTimeStamps',['../class_xdf.html#a12332c25006e2c6d71883c368c3c1f61',1,'Xdf']]] + ['info_22',['info',['../struct_xdf_1_1_stream.html#adb53bf4089d3169c9ea89a9767b4ad11',1,'Xdf::Stream']]] ]; diff --git a/docs/html/search/all_6.html b/docs/html/search/all_6.html index 89d590c..a24601b 100644 --- a/docs/html/search/all_6.html +++ b/docs/html/search/all_6.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_6.js b/docs/html/search/all_6.js index 136d71c..ab4d0a3 100644 --- a/docs/html/search/all_6.js +++ b/docs/html/search/all_6.js @@ -1,4 +1,7 @@ var searchData= [ - ['info',['info',['../struct_xdf_1_1_stream.html#a732d62cf3216a3bd4990625b0eb723cf',1,'Xdf::Stream']]] + ['labels_5f_23',['labels_',['../class_xdf.html#a3a41f6cf908b5e6aa4e83f801b5d245d',1,'Xdf']]], + ['last_5ftimestamp_24',['last_timestamp',['../struct_xdf_1_1_stream.html#a9e05df342a36187ae492c75f10fc7713',1,'Xdf::Stream']]], + ['load_5fxdf_25',['load_xdf',['../class_xdf.html#a993e94535d6d9e544a64ffbbb2bb4e8c',1,'Xdf']]], + ['libxdf_20_2d_20a_20c_2b_2b_20library_20for_20loading_20_3ca_20href_3d_22https_3a_2f_2fgithub_2ecom_2fsccn_2fxdf_2fwiki_2fspecifications_22_20title_3d_22extensible_20data_20format_22_3exdf_3c_2fa_3e_20files_26',['Libxdf - a C++ library for loading <a href="https://github.com/sccn/xdf/wiki/Specifications" title="Extensible Data Format">XDF</a> files',['../md__r_e_a_d_m_e.html',1,'']]] ]; diff --git a/docs/html/search/all_7.html b/docs/html/search/all_7.html index 0e8c527..e42e45b 100644 --- a/docs/html/search/all_7.html +++ b/docs/html/search/all_7.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_7.js b/docs/html/search/all_7.js index 7b216e2..4d1cd0e 100644 --- a/docs/html/search/all_7.js +++ b/docs/html/search/all_7.js @@ -1,7 +1,8 @@ var searchData= [ - ['labels',['labels',['../class_xdf.html#a250d6f79d0333887393eab248fee3c93',1,'Xdf']]], - ['last_5ftimestamp',['last_timestamp',['../struct_xdf_1_1_stream.html#a9e05df342a36187ae492c75f10fc7713',1,'Xdf::Stream::last_timestamp()'],['../struct_xdf_1_1_stream.html#ab61b638cf490354db62fb7da999750cf',1,'Xdf::Stream::last_timestamp()']]], - ['load_5fxdf',['load_xdf',['../class_xdf.html#a993e94535d6d9e544a64ffbbb2bb4e8c',1,'Xdf']]], - ['libxdf',['libxdf',['../md__c_1__users__yida__lin__documents__git_hub_libxdf_libxdf__r_e_a_d_m_e.html',1,'']]] + ['major_5fsampling_5frate_5f_27',['major_sampling_rate_',['../class_xdf.html#a89b8115372c91f34e985acd673d502da',1,'Xdf']]], + ['max_5fsampling_5frate_5f_28',['max_sampling_rate_',['../class_xdf.html#a73ea312db24b43eff063c4d223f15d5d',1,'Xdf']]], + ['max_5ftimestamp_5f_29',['max_timestamp_',['../class_xdf.html#abda66058170e3fdae48b28339bbad2a6',1,'Xdf']]], + ['measured_5fsampling_5frate_30',['measured_sampling_rate',['../struct_xdf_1_1_stream.html#abd08634894478bb304c209e5bbdcabb4',1,'Xdf::Stream']]], + ['min_5ftimestamp_5f_31',['min_timestamp_',['../class_xdf.html#a2f24970506cdd71c7de9b1f01162d36c',1,'Xdf']]] ]; diff --git a/docs/html/search/all_8.html b/docs/html/search/all_8.html index 80bda06..888e619 100644 --- a/docs/html/search/all_8.html +++ b/docs/html/search/all_8.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_8.js b/docs/html/search/all_8.js index 1a931e0..841f929 100644 --- a/docs/html/search/all_8.js +++ b/docs/html/search/all_8.js @@ -1,8 +1,5 @@ var searchData= [ - ['majsr',['majSR',['../class_xdf.html#ac65175994e0e2eeec4dd2f4688cd2040',1,'Xdf']]], - ['maxsr',['maxSR',['../class_xdf.html#a3cb480731a20caa480e3e6744acb562c',1,'Xdf']]], - ['maxts',['maxTS',['../class_xdf.html#a6874a847c980f296ebbcf703fa48096a',1,'Xdf']]], - ['measured_5fsrate',['measured_srate',['../struct_xdf_1_1_stream.html#a9c1fbac049f7c15225de9fe9713abc0a',1,'Xdf::Stream']]], - ['mints',['minTS',['../class_xdf.html#a44da046e191b2ae90b9bfe4de8d58ea3',1,'Xdf']]] + ['name_32',['name',['../struct_xdf_1_1_stream.html#a112e1dcc0e4b7f9583755366da8c3c64',1,'Xdf::Stream']]], + ['nominal_5fsrate_33',['nominal_srate',['../struct_xdf_1_1_stream.html#a17696fc2ee37c1d79601fac1736deb35',1,'Xdf::Stream']]] ]; diff --git a/docs/html/search/all_9.html b/docs/html/search/all_9.html index 8ebc8a2..dc988f4 100644 --- a/docs/html/search/all_9.html +++ b/docs/html/search/all_9.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_9.js b/docs/html/search/all_9.js index aee204e..c7f17d9 100644 --- a/docs/html/search/all_9.js +++ b/docs/html/search/all_9.js @@ -1,5 +1,4 @@ var searchData= [ - ['name',['name',['../struct_xdf_1_1_stream.html#a112e1dcc0e4b7f9583755366da8c3c64',1,'Xdf::Stream']]], - ['nominal_5fsrate',['nominal_srate',['../struct_xdf_1_1_stream.html#a17696fc2ee37c1d79601fac1736deb35',1,'Xdf::Stream']]] + ['offsets_5f_34',['offsets_',['../class_xdf.html#a640243fd0bf0ed9f80ca8cd6c2c447f1',1,'Xdf']]] ]; diff --git a/docs/html/search/all_a.html b/docs/html/search/all_a.html index f17bf66..0ce816b 100644 --- a/docs/html/search/all_a.html +++ b/docs/html/search/all_a.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_a.js b/docs/html/search/all_a.js index eaf8cb6..7008424 100644 --- a/docs/html/search/all_a.js +++ b/docs/html/search/all_a.js @@ -1,4 +1,4 @@ var searchData= [ - ['offsets',['offsets',['../class_xdf.html#a1a2b080f29080a5c521de907769d9419',1,'Xdf']]] + ['resample_35',['resample',['../class_xdf.html#a4ef5de06800e56726b6ce4a50ffdb0b4',1,'Xdf']]] ]; diff --git a/docs/html/search/all_b.html b/docs/html/search/all_b.html index 6ef469e..28c2413 100644 --- a/docs/html/search/all_b.html +++ b/docs/html/search/all_b.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_b.js b/docs/html/search/all_b.js index 56ec070..fbfd127 100644 --- a/docs/html/search/all_b.js +++ b/docs/html/search/all_b.js @@ -1,5 +1,12 @@ var searchData= [ - ['readme_2emd',['README.md',['../_r_e_a_d_m_e_8md.html',1,'']]], - ['resample',['resample',['../class_xdf.html#a67c5890ac84f257e91bdb93dcbe958ae',1,'Xdf']]] + ['sample_5fcount_36',['sample_count',['../struct_xdf_1_1_stream.html#a329234a46df00cd51a67a7f4f637c08a',1,'Xdf::Stream']]], + ['sampling_5finterval_37',['sampling_interval',['../struct_xdf_1_1_stream.html#a1cac0dbcbe6756cd02b662feae416ba1',1,'Xdf::Stream']]], + ['sampling_5frate_5fmap_5f_38',['sampling_rate_map_',['../class_xdf.html#ae6086c443d6ea7b8940f652edb20aaef',1,'Xdf']]], + ['stream_39',['Stream',['../struct_xdf_1_1_stream.html',1,'Xdf']]], + ['stream_5ffooter_40',['stream_footer',['../struct_xdf_1_1_stream.html#a9f3e86932b7937d1ebeaa896bc7b6a12',1,'Xdf::Stream']]], + ['stream_5fheader_41',['stream_header',['../struct_xdf_1_1_stream.html#a2fcba64fefd7c3e4d4768b9f9130399f',1,'Xdf::Stream']]], + ['stream_5fmap_5f_42',['stream_map_',['../class_xdf.html#a4a3b1aadac1f7fa4def94e9eae31fbd7',1,'Xdf']]], + ['streams_5f_43',['streams_',['../class_xdf.html#adeff1db8c45308d12d7786805eeaad9b',1,'Xdf']]], + ['sync_5ftimestamps_44',['sync_timestamps',['../class_xdf.html#a0b5e111d11282d4ff30020ca35446bd8',1,'Xdf']]] ]; diff --git a/docs/html/search/all_c.html b/docs/html/search/all_c.html index 4ca7bb9..39fc49b 100644 --- a/docs/html/search/all_c.html +++ b/docs/html/search/all_c.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_c.js b/docs/html/search/all_c.js index 4866ed0..ef9bca5 100644 --- a/docs/html/search/all_c.js +++ b/docs/html/search/all_c.js @@ -1,11 +1,7 @@ var searchData= [ - ['sample_5fcount',['sample_count',['../struct_xdf_1_1_stream.html#a329234a46df00cd51a67a7f4f637c08a',1,'Xdf::Stream']]], - ['sampleratemap',['sampleRateMap',['../class_xdf.html#add8aceaf68ad49b708f4df29f439778d',1,'Xdf']]], - ['sampling_5finterval',['sampling_interval',['../struct_xdf_1_1_stream.html#a49bbcb0c3130c3efef27ece47084b327',1,'Xdf::Stream']]], - ['stream',['Stream',['../struct_xdf_1_1_stream.html',1,'Xdf']]], - ['streamfooter',['streamFooter',['../struct_xdf_1_1_stream.html#aecd1fdf80d421e2362eeee58b31d4e11',1,'Xdf::Stream']]], - ['streamheader',['streamHeader',['../struct_xdf_1_1_stream.html#a2dff1924d1f7de075df08c4001201d63',1,'Xdf::Stream']]], - ['streammap',['streamMap',['../class_xdf.html#aa02e5a435186cdabbaf2487068c53dbc',1,'Xdf']]], - ['streams',['streams',['../class_xdf.html#acc12687ca26e8352afb960d459c5947a',1,'Xdf']]] + ['time_5fseries_45',['time_series',['../struct_xdf_1_1_stream.html#adfdeb5f6220da9fe671d3f37e27ed0bb',1,'Xdf::Stream']]], + ['timestamps_46',['timestamps',['../struct_xdf_1_1_stream.html#a20a2258af3bdffb13c6001a73da12428',1,'Xdf::Stream']]], + ['total_5flen_5f_47',['total_len_',['../class_xdf.html#a46c39c451c44431846046a5bcc354787',1,'Xdf']]], + ['type_48',['type',['../struct_xdf_1_1_stream.html#a7e5aa085e48de871ea6661651b28e097',1,'Xdf::Stream']]] ]; diff --git a/docs/html/search/all_d.html b/docs/html/search/all_d.html index fedf606..cc470e5 100644 --- a/docs/html/search/all_d.html +++ b/docs/html/search/all_d.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_d.js b/docs/html/search/all_d.js index 79c8cc5..35dbeba 100644 --- a/docs/html/search/all_d.js +++ b/docs/html/search/all_d.js @@ -1,8 +1,5 @@ var searchData= [ - ['time_5fseries',['time_series',['../struct_xdf_1_1_stream.html#adfdeb5f6220da9fe671d3f37e27ed0bb',1,'Xdf::Stream']]], - ['time_5fstamps',['time_stamps',['../struct_xdf_1_1_stream.html#a3f05ffb18a1feb56c248c391a69f104b',1,'Xdf::Stream']]], - ['totalch',['totalCh',['../class_xdf.html#a9b4fc485a140ba5020a48ca5fa2e45ea',1,'Xdf']]], - ['totallen',['totalLen',['../class_xdf.html#ac0b5d7d53fb28832594718cc16f65184',1,'Xdf']]], - ['type',['type',['../struct_xdf_1_1_stream.html#a7e5aa085e48de871ea6661651b28e097',1,'Xdf::Stream']]] + ['user_5fadded_5fstream_5f_49',['user_added_stream_',['../class_xdf.html#ad90637b4ad2bdb13ecabac25fab44836',1,'Xdf']]], + ['user_5fcreated_5fevents_5f_50',['user_created_events_',['../class_xdf.html#aa420a5824343786c9602a7bac77d1e28',1,'Xdf']]] ]; diff --git a/docs/html/search/all_e.html b/docs/html/search/all_e.html index 9b78086..57cce76 100644 --- a/docs/html/search/all_e.html +++ b/docs/html/search/all_e.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_e.js b/docs/html/search/all_e.js index fc8fdee..1251acd 100644 --- a/docs/html/search/all_e.js +++ b/docs/html/search/all_e.js @@ -1,5 +1,4 @@ var searchData= [ - ['useraddedstream',['userAddedStream',['../class_xdf.html#a83d5309d854b1052fa575b539a69c58d',1,'Xdf']]], - ['usercreatedevents',['userCreatedEvents',['../class_xdf.html#a7b1496a8667d67b90836696a1e2da618',1,'Xdf']]] + ['version_5f_51',['version_',['../class_xdf.html#a0d6728f813bab52c7c325d211b6e521f',1,'Xdf']]] ]; diff --git a/docs/html/search/all_f.html b/docs/html/search/all_f.html index 3bf97c6..ac1e704 100644 --- a/docs/html/search/all_f.html +++ b/docs/html/search/all_f.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/all_f.js b/docs/html/search/all_f.js index e683aa5..48a8da2 100644 --- a/docs/html/search/all_f.js +++ b/docs/html/search/all_f.js @@ -1,4 +1,4 @@ var searchData= [ - ['version',['version',['../class_xdf.html#a1d7401eb1557b2f34ac0ff4b9f79d04f',1,'Xdf']]] + ['write_5fevents_5fto_5fxdf_52',['write_events_to_xdf',['../class_xdf.html#a991b6c33acf78389826b123a53e106a0',1,'Xdf']]] ]; diff --git a/docs/html/search/classes_0.html b/docs/html/search/classes_0.html index 2e45b2c..5b441a3 100644 --- a/docs/html/search/classes_0.html +++ b/docs/html/search/classes_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/classes_0.js b/docs/html/search/classes_0.js index f828873..b053d1c 100644 --- a/docs/html/search/classes_0.js +++ b/docs/html/search/classes_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['stream',['Stream',['../struct_xdf_1_1_stream.html',1,'Xdf']]] + ['stream_55',['Stream',['../struct_xdf_1_1_stream.html',1,'Xdf']]] ]; diff --git a/docs/html/search/classes_1.html b/docs/html/search/classes_1.html index 5f1bc63..0ecc9f7 100644 --- a/docs/html/search/classes_1.html +++ b/docs/html/search/classes_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/classes_1.js b/docs/html/search/classes_1.js index 0d5965a..6aeb4ed 100644 --- a/docs/html/search/classes_1.js +++ b/docs/html/search/classes_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['xdf',['Xdf',['../class_xdf.html',1,'']]] + ['xdf_56',['Xdf',['../class_xdf.html',1,'']]] ]; diff --git a/docs/html/search/files_0.html b/docs/html/search/files_0.html index 63c6ce0..182d7eb 100644 --- a/docs/html/search/files_0.html +++ b/docs/html/search/files_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/files_0.js b/docs/html/search/files_0.js index 66a27ec..64d2055 100644 --- a/docs/html/search/files_0.js +++ b/docs/html/search/files_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['readme_2emd',['README.md',['../_r_e_a_d_m_e_8md.html',1,'']]] + ['xdf_2eh_57',['xdf.h',['../xdf_8h.html',1,'']]] ]; diff --git a/docs/html/search/functions_0.html b/docs/html/search/functions_0.html index 03cae5d..4fcbb9c 100644 --- a/docs/html/search/functions_0.html +++ b/docs/html/search/functions_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/functions_0.js b/docs/html/search/functions_0.js index e8f97bc..ffa69cb 100644 --- a/docs/html/search/functions_0.js +++ b/docs/html/search/functions_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['adjusttotallength',['adjustTotalLength',['../class_xdf.html#aa7dc1ef8c04216d703604bf868146428',1,'Xdf']]] + ['adjust_5ftotal_5flength_58',['adjust_total_length',['../class_xdf.html#ae19b9ae0ee92b8c93fc3fd5be2d2d97f',1,'Xdf']]] ]; diff --git a/docs/html/search/functions_1.html b/docs/html/search/functions_1.html index 5d7a2e3..9b0e1f0 100644 --- a/docs/html/search/functions_1.html +++ b/docs/html/search/functions_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/functions_1.js b/docs/html/search/functions_1.js index 4ca8aaf..c342a1a 100644 --- a/docs/html/search/functions_1.js +++ b/docs/html/search/functions_1.js @@ -1,5 +1,5 @@ var searchData= [ - ['calctotallength',['calcTotalLength',['../class_xdf.html#a75ef15a72071fe0d36ef6311214518fe',1,'Xdf']]], - ['createlabels',['createLabels',['../class_xdf.html#ad98829202c9ae64505c9ecc7796c8ddc',1,'Xdf']]] + ['calculate_5ftotal_5flength_59',['calculate_total_length',['../class_xdf.html#a72175fdbb081994f05b388e5ba92c903',1,'Xdf']]], + ['create_5flabels_60',['create_labels',['../class_xdf.html#ab81f7f275ab38269d76be6ad0fdc9e29',1,'Xdf']]] ]; diff --git a/docs/html/search/functions_2.html b/docs/html/search/functions_2.html index c21af16..eb51f80 100644 --- a/docs/html/search/functions_2.html +++ b/docs/html/search/functions_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/functions_2.js b/docs/html/search/functions_2.js index f7362ff..9e8c5c1 100644 --- a/docs/html/search/functions_2.js +++ b/docs/html/search/functions_2.js @@ -1,4 +1,4 @@ var searchData= [ - ['detrend',['detrend',['../class_xdf.html#a4d2c5859af84542a15a80c906465f4e3',1,'Xdf']]] + ['detrend_61',['detrend',['../class_xdf.html#a4d2c5859af84542a15a80c906465f4e3',1,'Xdf']]] ]; diff --git a/docs/html/search/functions_3.html b/docs/html/search/functions_3.html index e6f4744..e53b9d0 100644 --- a/docs/html/search/functions_3.html +++ b/docs/html/search/functions_3.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/functions_3.js b/docs/html/search/functions_3.js index c480870..515eba9 100644 --- a/docs/html/search/functions_3.js +++ b/docs/html/search/functions_3.js @@ -1,4 +1,4 @@ var searchData= [ - ['freeuptimestamps',['freeUpTimeStamps',['../class_xdf.html#a12332c25006e2c6d71883c368c3c1f61',1,'Xdf']]] + ['free_5fup_5ftimestamps_62',['free_up_timestamps',['../class_xdf.html#a957461547bca42a5314dafaaf307c1ee',1,'Xdf']]] ]; diff --git a/docs/html/search/functions_4.html b/docs/html/search/functions_4.html index 9ae34ff..d049621 100644 --- a/docs/html/search/functions_4.html +++ b/docs/html/search/functions_4.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/functions_4.js b/docs/html/search/functions_4.js index 7a68cf0..f94d321 100644 --- a/docs/html/search/functions_4.js +++ b/docs/html/search/functions_4.js @@ -1,4 +1,4 @@ var searchData= [ - ['load_5fxdf',['load_xdf',['../class_xdf.html#a993e94535d6d9e544a64ffbbb2bb4e8c',1,'Xdf']]] + ['load_5fxdf_63',['load_xdf',['../class_xdf.html#a993e94535d6d9e544a64ffbbb2bb4e8c',1,'Xdf']]] ]; diff --git a/docs/html/search/functions_5.html b/docs/html/search/functions_5.html index 54f53d0..342487b 100644 --- a/docs/html/search/functions_5.html +++ b/docs/html/search/functions_5.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/functions_5.js b/docs/html/search/functions_5.js index f8577d5..f47f55c 100644 --- a/docs/html/search/functions_5.js +++ b/docs/html/search/functions_5.js @@ -1,4 +1,4 @@ var searchData= [ - ['resample',['resample',['../class_xdf.html#a67c5890ac84f257e91bdb93dcbe958ae',1,'Xdf']]] + ['resample_64',['resample',['../class_xdf.html#a4ef5de06800e56726b6ce4a50ffdb0b4',1,'Xdf']]] ]; diff --git a/docs/html/search/functions_6.html b/docs/html/search/functions_6.html index c7bc6fb..4bf3bd6 100644 --- a/docs/html/search/functions_6.html +++ b/docs/html/search/functions_6.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/functions_6.js b/docs/html/search/functions_6.js index 63ddc8e..e00e45b 100644 --- a/docs/html/search/functions_6.js +++ b/docs/html/search/functions_6.js @@ -1,4 +1,4 @@ var searchData= [ - ['writeeventstoxdf',['writeEventsToXDF',['../class_xdf.html#a072e657d7620d61080a15a215c691210',1,'Xdf']]] + ['sync_5ftimestamps_65',['sync_timestamps',['../class_xdf.html#a0b5e111d11282d4ff30020ca35446bd8',1,'Xdf']]] ]; diff --git a/docs/html/search/functions_7.html b/docs/html/search/functions_7.html index 7f10e2b..d7ad9dd 100644 --- a/docs/html/search/functions_7.html +++ b/docs/html/search/functions_7.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/functions_7.js b/docs/html/search/functions_7.js index 02ca204..0f71f76 100644 --- a/docs/html/search/functions_7.js +++ b/docs/html/search/functions_7.js @@ -1,4 +1,4 @@ var searchData= [ - ['xdf',['Xdf',['../class_xdf.html#a7900b5a4f3792b9d59a5d43db821607e',1,'Xdf']]] + ['write_5fevents_5fto_5fxdf_66',['write_events_to_xdf',['../class_xdf.html#a991b6c33acf78389826b123a53e106a0',1,'Xdf']]] ]; diff --git a/docs/html/search/functions_8.html b/docs/html/search/functions_8.html index 347734a..8600cab 100644 --- a/docs/html/search/functions_8.html +++ b/docs/html/search/functions_8.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/functions_8.js b/docs/html/search/functions_8.js index 02ca204..ed3c370 100644 --- a/docs/html/search/functions_8.js +++ b/docs/html/search/functions_8.js @@ -1,4 +1,4 @@ var searchData= [ - ['xdf',['Xdf',['../class_xdf.html#a7900b5a4f3792b9d59a5d43db821607e',1,'Xdf']]] + ['xdf_67',['Xdf',['../class_xdf.html#a7900b5a4f3792b9d59a5d43db821607e',1,'Xdf']]] ]; diff --git a/docs/html/search/mag_sel.png b/docs/html/search/mag_sel.png index 81f6040a2092402b4d98f9ffa8855d12a0d4ca17..39c0ed52a25dd9d080ee0d42ae6c6042bdfa04d7 100644 GIT binary patch delta 387 zcmdnYa*=t0qy!5C1A|rTQ#&BVlJ4m1$iT3%pZiZD>qIj>9tNf)Z+91l|Ly%}_D@ul zsAn(n^mS!_#KX=lBk2D&{60|65lM6-Px1V)%FZ&RBYX~=GOWPWxZh<9+s(!r~e-Dn&F(J7joYq z)l&8Vdty#vcB0OmiB?q{_kF5^+l}W}R~ek~dmFbhU{|SDOj*f>4|Dl@%X_EZYArBb z&|I6VJJ#f9jJl9)78&qol`;+ E09^HzBLDyZ delta 506 zcmV865@y005ATEwumu010qNS#tmY3ljhU3ljkVnw%JsF)n`rxk*Gp zRCwCtl)H)|K@^6++7>zxx&tqG15pu7)IiiXFflOc2k;dXd>%13GZAy?Rz!q0=|E6a z6vV)&ZBS~G9oe0kbqyw1*gvY`{Pop2oKq#FlzgXt@Xh-7fxh>}`Fxg>$%N%{$!4=5 znM{(;=c!aG1Ofr^Do{u%Ih}t_axfTRS=J{*wOXaoXb=nr#mgB^r&BD;B9%%}DwW7& zGOSiBX0sWS$%IHGLcLypy=2?A0VtQtR4NrTO%tI|NGgiLdcDTBZR+(pqtQtA`~AmZ z!!W4TYT{E~!8ritsi(lkxR<1ql~bQ*wKt@eOE?ecoPmc!wY`F#GRDI5;d>2%O_ zT>y+mqmLK-4)i=v?shvCiv^D3u;1^A$K#~aX>8l(bUG1@MrpU(59rej0X)x>uIu7? z9=F>KpU;P)C|oWVdc9H}$K#P$EJmx-CDR w>wnMinOxVEhr@yU{Z2NUeXZpG=lgma09mNIXv$B;rvLx|07*qoM6N<$g8jzt3IG5A diff --git a/docs/html/search/nomatches.html b/docs/html/search/nomatches.html index b1ded27..4377320 100644 --- a/docs/html/search/nomatches.html +++ b/docs/html/search/nomatches.html @@ -1,4 +1,4 @@ - + diff --git a/docs/html/search/pages_0.html b/docs/html/search/pages_0.html index d0102ff..ca7755f 100644 --- a/docs/html/search/pages_0.html +++ b/docs/html/search/pages_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/pages_0.js b/docs/html/search/pages_0.js index 25e9578..d47789f 100644 --- a/docs/html/search/pages_0.js +++ b/docs/html/search/pages_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['libxdf',['libxdf',['../md__c_1__users__yida__lin__documents__git_hub_libxdf_libxdf__r_e_a_d_m_e.html',1,'']]] + ['libxdf_20_2d_20a_20c_2b_2b_20library_20for_20loading_20_3ca_20href_3d_22https_3a_2f_2fgithub_2ecom_2fsccn_2fxdf_2fwiki_2fspecifications_22_20title_3d_22extensible_20data_20format_22_3exdf_3c_2fa_3e_20files_110',['Libxdf - a C++ library for loading <a href="https://github.com/sccn/xdf/wiki/Specifications" title="Extensible Data Format">XDF</a> files',['../md__r_e_a_d_m_e.html',1,'']]] ]; diff --git a/docs/html/search/search.js b/docs/html/search/search.js index dedce3b..ff2b8c8 100644 --- a/docs/html/search/search.js +++ b/docs/html/search/search.js @@ -1,3 +1,27 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ function convertToId(search) { var result = ''; @@ -177,10 +201,9 @@ function SearchBox(name, resultsPath, inFrame, label) } return; } - else if (window.frames.MSearchResults.searchResults) + else { - var elem = window.frames.MSearchResults.searchResults.NavNext(0); - if (elem) elem.focus(); + window.frames.MSearchResults.postMessage("take_focus", "*"); } } else if (e.keyCode==27) // Escape out of the search field @@ -788,4 +811,4 @@ function init_search() } searchBox.OnSelectItem(0); } - +/* @license-end */ diff --git a/docs/html/search/search_l.png b/docs/html/search/search_l.png index c872f4da4a01d0754f923e6c94fd8159c0621bd1..fd5f7daa41a4c79b4ae9bea5aa7bdfb94e14084b 100644 GIT binary patch delta 490 zcmcb^vYlmuqy!5C1A|rTQ#&BVlJ4m1$iT3%pZiZD>qIj>9tNf)Z+91l|Ly%}_D@ul zsAn(n^mS!_#KX=lBk2D&{5}H%qn4+OV~EE2-brV@oB~DMzW1v2cBy@1;GO-&?&6Y~ zW{oDf18$B2lAZ#+TwkXx5}KGW%Q0X<<5h);bqD4*s<~D5&%3JN__k|%zOPw(Dc}7@ z-4ptmhf6B&&b!_FjBE9pn*uC5&60xesh+<(kE_1GagvF-8H=anvo~dTmJ2zopr03(~h8~^|S delta 547 zcmV+;0^I$#1l$CW865@y005ATEwumu010qNS#tmY3ljhU3ljkVnw%JsF)n`r;z>k7 zRCwB~R6VQOP#AvB$vH7i{6H{96zot$7cZT<7246EF5Np6N}+$IbiG6Wg#87A+NFaX z+=_^xM1#gCtshC=E{%9^uQX_%?YwXvo{#q&MnpJ8uh(O?ZRc&~_1%^SsPxGh+H0ARIRr6-fgr(&`AvRbVopU=ZE3`i-#IY(T(03h1! zHlI$XuT0Z?QLoowSr&9%hm;bRKr9vulZf8dYBk-mEEt9XAp|Z3_dI{ESuU5KManqm zxCT53f<~cGcyz6@BcYV?X(p55QD*n|()axbFP@uoRaLW*RmK>?FuWV`8P(_JTuM0x za9oSH>v7gH5q0+a{n6^xr4Z4#^?DtIVF)6+o={Pgua4vV-0gPwAK-~Z;>U8i{O&jo zeBVD>zu$Ij!bYR#AUxE%gx1-^Km_jxcFjAyeMMJ1h6Nkljt z4md6I&Tj)?DTMgwd7j(v_urRFrN_}zR8Fdh=h=-k9M$rFl_8(j zC{hPbXF zRCwB?)W514K@j&X?z2*SxFI6-@HT2E2K=9X9%PbEK*!TBw&g( zDMC;|A)uGlRkOS9vd-?zNs%bR4d$w+ox_iFnE8fvIvv7^5<(>Te12Li7C)9srCzmK z{ZcNM{YIl9j{DePFgOWiS%!ZkNe~2q@H}s`*=&ATmUUaJ)!sCl&0hz|_x+QQl=6Uu zVTk2&N#pTY#&P_?w(aMRQc9$0iYSV(SS&Cc4u$Kw?`yT%O{>+4 zG{)E|2aGW&iUJ~nuIn%i1G!udhGD2u%BS=B{Aa)4f2H7o#TWx)44QwYp-?EGQmLR` zuWJBatk>&D4~C9GRaIe{CMuN*Y}>YiAb55*w8!?7RjXAdgm|nRU-P-8>pCpUg0Abk z1Egu%*;6Ts0@E~^VHnGcRy)T2PIh+{L`2}63nKceT!Tm{5r*N0h`wJn(Qdbc=XpI< zRejI}C8Z?JIZY;$MYn(3eL_S~E?G$kf%STwOsCU#LWpkwpzRN{EIZ`sU-={YlWop9 zR;!g54u_wDAb8zwx6^y+C!%`@5g|=eaLy6Ov2fB#XE uB-n1ZVH8E5Ip=Q~W4DguM8|!<2LNApMvO2l*qs0X002ovPDBK*LSTZi=Kr7o diff --git a/docs/html/search/searchdata.js b/docs/html/search/searchdata.js index 3ca3a76..354eec4 100644 --- a/docs/html/search/searchdata.js +++ b/docs/html/search/searchdata.js @@ -1,13 +1,12 @@ var indexSectionsWithContent = { - 0: "abcdefilmnorstuvwx", + 0: "acdefilmnorstuvwx", 1: "sx", - 2: "rx", - 3: "acdflrwx", + 2: "x", + 3: "acdflrswx", 4: "cdefilmnostuv", 5: "e", - 6: "b", - 7: "l" + 6: "l" }; var indexSectionNames = @@ -18,8 +17,7 @@ var indexSectionNames = 3: "functions", 4: "variables", 5: "typedefs", - 6: "defines", - 7: "pages" + 6: "pages" }; var indexSectionLabels = @@ -30,7 +28,6 @@ var indexSectionLabels = 3: "Functions", 4: "Variables", 5: "Typedefs", - 6: "Macros", - 7: "Pages" + 6: "Pages" }; diff --git a/docs/html/search/typedefs_0.html b/docs/html/search/typedefs_0.html index 3a58062..43353ee 100644 --- a/docs/html/search/typedefs_0.html +++ b/docs/html/search/typedefs_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/typedefs_0.js b/docs/html/search/typedefs_0.js index 8a339a1..fd74851 100644 --- a/docs/html/search/typedefs_0.js +++ b/docs/html/search/typedefs_0.js @@ -1,5 +1,5 @@ var searchData= [ - ['eventname',['eventName',['../class_xdf.html#a4e3322abfe4d533d6b7a96cbbea7271a',1,'Xdf']]], - ['eventtimestamp',['eventTimeStamp',['../class_xdf.html#a1fbf3d641262cc1daade33eca1789990',1,'Xdf']]] + ['event_5fname_5f_108',['event_name_',['../class_xdf.html#a57eb7fdd01251b7613a7d106625ff019',1,'Xdf']]], + ['event_5ftimestamp_5f_109',['event_timestamp_',['../class_xdf.html#a4cf524f9428b9438b70cb17ea3f2d547',1,'Xdf']]] ]; diff --git a/docs/html/search/variables_0.html b/docs/html/search/variables_0.html index 164aa54..9ce246b 100644 --- a/docs/html/search/variables_0.html +++ b/docs/html/search/variables_0.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_0.js b/docs/html/search/variables_0.js index 5e0ccf2..5b2a5ac 100644 --- a/docs/html/search/variables_0.js +++ b/docs/html/search/variables_0.js @@ -1,9 +1,10 @@ var searchData= [ - ['channel_5fcount',['channel_count',['../struct_xdf_1_1_stream.html#ab8fb7c3d645305e84f90d919f698082c',1,'Xdf::Stream']]], - ['channel_5fformat',['channel_format',['../struct_xdf_1_1_stream.html#ad7b61b077e247ba57a18c182e285d0ad',1,'Xdf::Stream']]], - ['channels',['channels',['../struct_xdf_1_1_stream.html#a71d987a538d0819cdbd58120d1a79ef5',1,'Xdf::Stream']]], - ['clock_5foffsets',['clock_offsets',['../struct_xdf_1_1_stream.html#a6f6328f0746591a3a471048b6b9bd258',1,'Xdf::Stream']]], - ['clock_5ftimes',['clock_times',['../struct_xdf_1_1_stream.html#a6bc91dcf23e551a9adbc415b562f3a79',1,'Xdf::Stream']]], - ['clock_5fvalues',['clock_values',['../struct_xdf_1_1_stream.html#a988989603854812cb693e56ff352a753',1,'Xdf::Stream']]] + ['channel_5fcount_68',['channel_count',['../struct_xdf_1_1_stream.html#ab8fb7c3d645305e84f90d919f698082c',1,'Xdf::Stream']]], + ['channel_5fcount_5f_69',['channel_count_',['../class_xdf.html#afb6d47c75ebc215eb14aaf9e80133a7f',1,'Xdf']]], + ['channel_5fformat_70',['channel_format',['../struct_xdf_1_1_stream.html#ad7b61b077e247ba57a18c182e285d0ad',1,'Xdf::Stream']]], + ['channels_71',['channels',['../struct_xdf_1_1_stream.html#a71d987a538d0819cdbd58120d1a79ef5',1,'Xdf::Stream']]], + ['clock_5foffsets_72',['clock_offsets',['../struct_xdf_1_1_stream.html#a6f6328f0746591a3a471048b6b9bd258',1,'Xdf::Stream']]], + ['clock_5ftimes_73',['clock_times',['../struct_xdf_1_1_stream.html#a6bc91dcf23e551a9adbc415b562f3a79',1,'Xdf::Stream']]], + ['clock_5fvalues_74',['clock_values',['../struct_xdf_1_1_stream.html#a988989603854812cb693e56ff352a753',1,'Xdf::Stream']]] ]; diff --git a/docs/html/search/variables_1.html b/docs/html/search/variables_1.html index 857fbbd..5802cec 100644 --- a/docs/html/search/variables_1.html +++ b/docs/html/search/variables_1.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_1.js b/docs/html/search/variables_1.js index f2ae8ee..f67d0e9 100644 --- a/docs/html/search/variables_1.js +++ b/docs/html/search/variables_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['dictionary',['dictionary',['../class_xdf.html#a26a2b517f020dc9f188c2277c76add85',1,'Xdf']]] + ['dictionary_5f_75',['dictionary_',['../class_xdf.html#a37903ef2145466774f7bb57dd72fb428',1,'Xdf']]] ]; diff --git a/docs/html/search/variables_2.html b/docs/html/search/variables_2.html index 35233e3..00291e5 100644 --- a/docs/html/search/variables_2.html +++ b/docs/html/search/variables_2.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_2.js b/docs/html/search/variables_2.js index 19ed5b6..369aa4e 100644 --- a/docs/html/search/variables_2.js +++ b/docs/html/search/variables_2.js @@ -1,6 +1,7 @@ var searchData= [ - ['effective_5fsample_5frate',['effective_sample_rate',['../struct_xdf_1_1_stream.html#abeb1d2eb26a46eac34a478f04f5143d6',1,'Xdf::Stream']]], - ['eventmap',['eventMap',['../class_xdf.html#a45004fc495cad33768fae80b996a68db',1,'Xdf']]], - ['eventtype',['eventType',['../class_xdf.html#a4acb87e86380bf7266976cd6c4cb3826',1,'Xdf']]] + ['effective_5fsampling_5frate_76',['effective_sampling_rate',['../struct_xdf_1_1_stream.html#a97a11401e85fd9f64a5601b15bbc7820',1,'Xdf::Stream']]], + ['effective_5fsampling_5frates_5f_77',['effective_sampling_rates_',['../class_xdf.html#a21852b079ed18afa0117d67755a2c68d',1,'Xdf']]], + ['event_5fmap_5f_78',['event_map_',['../class_xdf.html#ad92266c3c43f6a508d43040090479726',1,'Xdf']]], + ['event_5ftype_5f_79',['event_type_',['../class_xdf.html#a6a98e5d14a159cc9b24460f2441d6b4e',1,'Xdf']]] ]; diff --git a/docs/html/search/variables_3.html b/docs/html/search/variables_3.html index e45e613..0e5389b 100644 --- a/docs/html/search/variables_3.html +++ b/docs/html/search/variables_3.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_3.js b/docs/html/search/variables_3.js index 792c548..58980ad 100644 --- a/docs/html/search/variables_3.js +++ b/docs/html/search/variables_3.js @@ -1,5 +1,6 @@ var searchData= [ - ['fileheader',['fileHeader',['../class_xdf.html#a1e46bbbf31121fb394aa8cf5c10d10b0',1,'Xdf']]], - ['first_5ftimestamp',['first_timestamp',['../struct_xdf_1_1_stream.html#a22a44cb3cd533ea668f9bb20dbc299de',1,'Xdf::Stream']]] + ['file_5feffective_5fsampling_5frate_5f_80',['file_effective_sampling_rate_',['../class_xdf.html#a4e36c1e1588711d7d09d2aa26f800f2c',1,'Xdf']]], + ['file_5fheader_5f_81',['file_header_',['../class_xdf.html#abb8518a32a84995d60648d1c0fdd6428',1,'Xdf']]], + ['first_5ftimestamp_82',['first_timestamp',['../struct_xdf_1_1_stream.html#a22a44cb3cd533ea668f9bb20dbc299de',1,'Xdf::Stream']]] ]; diff --git a/docs/html/search/variables_4.html b/docs/html/search/variables_4.html index 97ec255..789a86b 100644 --- a/docs/html/search/variables_4.html +++ b/docs/html/search/variables_4.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_4.js b/docs/html/search/variables_4.js index 136d71c..9a3c597 100644 --- a/docs/html/search/variables_4.js +++ b/docs/html/search/variables_4.js @@ -1,4 +1,4 @@ var searchData= [ - ['info',['info',['../struct_xdf_1_1_stream.html#a732d62cf3216a3bd4990625b0eb723cf',1,'Xdf::Stream']]] + ['info_83',['info',['../struct_xdf_1_1_stream.html#adb53bf4089d3169c9ea89a9767b4ad11',1,'Xdf::Stream']]] ]; diff --git a/docs/html/search/variables_5.html b/docs/html/search/variables_5.html index d77fa84..c7873eb 100644 --- a/docs/html/search/variables_5.html +++ b/docs/html/search/variables_5.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_5.js b/docs/html/search/variables_5.js index 54688db..2b8346a 100644 --- a/docs/html/search/variables_5.js +++ b/docs/html/search/variables_5.js @@ -1,5 +1,5 @@ var searchData= [ - ['labels',['labels',['../class_xdf.html#a250d6f79d0333887393eab248fee3c93',1,'Xdf']]], - ['last_5ftimestamp',['last_timestamp',['../struct_xdf_1_1_stream.html#a9e05df342a36187ae492c75f10fc7713',1,'Xdf::Stream::last_timestamp()'],['../struct_xdf_1_1_stream.html#ab61b638cf490354db62fb7da999750cf',1,'Xdf::Stream::last_timestamp()']]] + ['labels_5f_84',['labels_',['../class_xdf.html#a3a41f6cf908b5e6aa4e83f801b5d245d',1,'Xdf']]], + ['last_5ftimestamp_85',['last_timestamp',['../struct_xdf_1_1_stream.html#a9e05df342a36187ae492c75f10fc7713',1,'Xdf::Stream']]] ]; diff --git a/docs/html/search/variables_6.html b/docs/html/search/variables_6.html index c656bb6..a588588 100644 --- a/docs/html/search/variables_6.html +++ b/docs/html/search/variables_6.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_6.js b/docs/html/search/variables_6.js index 1a931e0..5d5944a 100644 --- a/docs/html/search/variables_6.js +++ b/docs/html/search/variables_6.js @@ -1,8 +1,8 @@ var searchData= [ - ['majsr',['majSR',['../class_xdf.html#ac65175994e0e2eeec4dd2f4688cd2040',1,'Xdf']]], - ['maxsr',['maxSR',['../class_xdf.html#a3cb480731a20caa480e3e6744acb562c',1,'Xdf']]], - ['maxts',['maxTS',['../class_xdf.html#a6874a847c980f296ebbcf703fa48096a',1,'Xdf']]], - ['measured_5fsrate',['measured_srate',['../struct_xdf_1_1_stream.html#a9c1fbac049f7c15225de9fe9713abc0a',1,'Xdf::Stream']]], - ['mints',['minTS',['../class_xdf.html#a44da046e191b2ae90b9bfe4de8d58ea3',1,'Xdf']]] + ['major_5fsampling_5frate_5f_86',['major_sampling_rate_',['../class_xdf.html#a89b8115372c91f34e985acd673d502da',1,'Xdf']]], + ['max_5fsampling_5frate_5f_87',['max_sampling_rate_',['../class_xdf.html#a73ea312db24b43eff063c4d223f15d5d',1,'Xdf']]], + ['max_5ftimestamp_5f_88',['max_timestamp_',['../class_xdf.html#abda66058170e3fdae48b28339bbad2a6',1,'Xdf']]], + ['measured_5fsampling_5frate_89',['measured_sampling_rate',['../struct_xdf_1_1_stream.html#abd08634894478bb304c209e5bbdcabb4',1,'Xdf::Stream']]], + ['min_5ftimestamp_5f_90',['min_timestamp_',['../class_xdf.html#a2f24970506cdd71c7de9b1f01162d36c',1,'Xdf']]] ]; diff --git a/docs/html/search/variables_7.html b/docs/html/search/variables_7.html index 8aac836..b09b295 100644 --- a/docs/html/search/variables_7.html +++ b/docs/html/search/variables_7.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_7.js b/docs/html/search/variables_7.js index aee204e..853b89c 100644 --- a/docs/html/search/variables_7.js +++ b/docs/html/search/variables_7.js @@ -1,5 +1,5 @@ var searchData= [ - ['name',['name',['../struct_xdf_1_1_stream.html#a112e1dcc0e4b7f9583755366da8c3c64',1,'Xdf::Stream']]], - ['nominal_5fsrate',['nominal_srate',['../struct_xdf_1_1_stream.html#a17696fc2ee37c1d79601fac1736deb35',1,'Xdf::Stream']]] + ['name_91',['name',['../struct_xdf_1_1_stream.html#a112e1dcc0e4b7f9583755366da8c3c64',1,'Xdf::Stream']]], + ['nominal_5fsrate_92',['nominal_srate',['../struct_xdf_1_1_stream.html#a17696fc2ee37c1d79601fac1736deb35',1,'Xdf::Stream']]] ]; diff --git a/docs/html/search/variables_8.html b/docs/html/search/variables_8.html index a74c6ca..a479f8e 100644 --- a/docs/html/search/variables_8.html +++ b/docs/html/search/variables_8.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_8.js b/docs/html/search/variables_8.js index eaf8cb6..b9c76e2 100644 --- a/docs/html/search/variables_8.js +++ b/docs/html/search/variables_8.js @@ -1,4 +1,4 @@ var searchData= [ - ['offsets',['offsets',['../class_xdf.html#a1a2b080f29080a5c521de907769d9419',1,'Xdf']]] + ['offsets_5f_93',['offsets_',['../class_xdf.html#a640243fd0bf0ed9f80ca8cd6c2c447f1',1,'Xdf']]] ]; diff --git a/docs/html/search/variables_9.html b/docs/html/search/variables_9.html index 3968526..97cc440 100644 --- a/docs/html/search/variables_9.html +++ b/docs/html/search/variables_9.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_9.js b/docs/html/search/variables_9.js index 078595c..ef391bf 100644 --- a/docs/html/search/variables_9.js +++ b/docs/html/search/variables_9.js @@ -1,10 +1,10 @@ var searchData= [ - ['sample_5fcount',['sample_count',['../struct_xdf_1_1_stream.html#a329234a46df00cd51a67a7f4f637c08a',1,'Xdf::Stream']]], - ['sampleratemap',['sampleRateMap',['../class_xdf.html#add8aceaf68ad49b708f4df29f439778d',1,'Xdf']]], - ['sampling_5finterval',['sampling_interval',['../struct_xdf_1_1_stream.html#a49bbcb0c3130c3efef27ece47084b327',1,'Xdf::Stream']]], - ['streamfooter',['streamFooter',['../struct_xdf_1_1_stream.html#aecd1fdf80d421e2362eeee58b31d4e11',1,'Xdf::Stream']]], - ['streamheader',['streamHeader',['../struct_xdf_1_1_stream.html#a2dff1924d1f7de075df08c4001201d63',1,'Xdf::Stream']]], - ['streammap',['streamMap',['../class_xdf.html#aa02e5a435186cdabbaf2487068c53dbc',1,'Xdf']]], - ['streams',['streams',['../class_xdf.html#acc12687ca26e8352afb960d459c5947a',1,'Xdf']]] + ['sample_5fcount_94',['sample_count',['../struct_xdf_1_1_stream.html#a329234a46df00cd51a67a7f4f637c08a',1,'Xdf::Stream']]], + ['sampling_5finterval_95',['sampling_interval',['../struct_xdf_1_1_stream.html#a1cac0dbcbe6756cd02b662feae416ba1',1,'Xdf::Stream']]], + ['sampling_5frate_5fmap_5f_96',['sampling_rate_map_',['../class_xdf.html#ae6086c443d6ea7b8940f652edb20aaef',1,'Xdf']]], + ['stream_5ffooter_97',['stream_footer',['../struct_xdf_1_1_stream.html#a9f3e86932b7937d1ebeaa896bc7b6a12',1,'Xdf::Stream']]], + ['stream_5fheader_98',['stream_header',['../struct_xdf_1_1_stream.html#a2fcba64fefd7c3e4d4768b9f9130399f',1,'Xdf::Stream']]], + ['stream_5fmap_5f_99',['stream_map_',['../class_xdf.html#a4a3b1aadac1f7fa4def94e9eae31fbd7',1,'Xdf']]], + ['streams_5f_100',['streams_',['../class_xdf.html#adeff1db8c45308d12d7786805eeaad9b',1,'Xdf']]] ]; diff --git a/docs/html/search/variables_a.html b/docs/html/search/variables_a.html index ce54923..0107448 100644 --- a/docs/html/search/variables_a.html +++ b/docs/html/search/variables_a.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_a.js b/docs/html/search/variables_a.js index 79c8cc5..bde7961 100644 --- a/docs/html/search/variables_a.js +++ b/docs/html/search/variables_a.js @@ -1,8 +1,7 @@ var searchData= [ - ['time_5fseries',['time_series',['../struct_xdf_1_1_stream.html#adfdeb5f6220da9fe671d3f37e27ed0bb',1,'Xdf::Stream']]], - ['time_5fstamps',['time_stamps',['../struct_xdf_1_1_stream.html#a3f05ffb18a1feb56c248c391a69f104b',1,'Xdf::Stream']]], - ['totalch',['totalCh',['../class_xdf.html#a9b4fc485a140ba5020a48ca5fa2e45ea',1,'Xdf']]], - ['totallen',['totalLen',['../class_xdf.html#ac0b5d7d53fb28832594718cc16f65184',1,'Xdf']]], - ['type',['type',['../struct_xdf_1_1_stream.html#a7e5aa085e48de871ea6661651b28e097',1,'Xdf::Stream']]] + ['time_5fseries_101',['time_series',['../struct_xdf_1_1_stream.html#adfdeb5f6220da9fe671d3f37e27ed0bb',1,'Xdf::Stream']]], + ['timestamps_102',['timestamps',['../struct_xdf_1_1_stream.html#a20a2258af3bdffb13c6001a73da12428',1,'Xdf::Stream']]], + ['total_5flen_5f_103',['total_len_',['../class_xdf.html#a46c39c451c44431846046a5bcc354787',1,'Xdf']]], + ['type_104',['type',['../struct_xdf_1_1_stream.html#a7e5aa085e48de871ea6661651b28e097',1,'Xdf::Stream']]] ]; diff --git a/docs/html/search/variables_b.html b/docs/html/search/variables_b.html index 4825aed..e5b2fd9 100644 --- a/docs/html/search/variables_b.html +++ b/docs/html/search/variables_b.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_b.js b/docs/html/search/variables_b.js index fc8fdee..0df5560 100644 --- a/docs/html/search/variables_b.js +++ b/docs/html/search/variables_b.js @@ -1,5 +1,5 @@ var searchData= [ - ['useraddedstream',['userAddedStream',['../class_xdf.html#a83d5309d854b1052fa575b539a69c58d',1,'Xdf']]], - ['usercreatedevents',['userCreatedEvents',['../class_xdf.html#a7b1496a8667d67b90836696a1e2da618',1,'Xdf']]] + ['user_5fadded_5fstream_5f_105',['user_added_stream_',['../class_xdf.html#ad90637b4ad2bdb13ecabac25fab44836',1,'Xdf']]], + ['user_5fcreated_5fevents_5f_106',['user_created_events_',['../class_xdf.html#aa420a5824343786c9602a7bac77d1e28',1,'Xdf']]] ]; diff --git a/docs/html/search/variables_c.html b/docs/html/search/variables_c.html index 40b9b9a..f3e9989 100644 --- a/docs/html/search/variables_c.html +++ b/docs/html/search/variables_c.html @@ -1,7 +1,7 @@ - + - + @@ -11,15 +11,25 @@
    Loading...
    Searching...
    No Matches
    diff --git a/docs/html/search/variables_c.js b/docs/html/search/variables_c.js index e683aa5..b211079 100644 --- a/docs/html/search/variables_c.js +++ b/docs/html/search/variables_c.js @@ -1,4 +1,4 @@ var searchData= [ - ['version',['version',['../class_xdf.html#a1d7401eb1557b2f34ac0ff4b9f79d04f',1,'Xdf']]] + ['version_5f_107',['version_',['../class_xdf.html#a0d6728f813bab52c7c325d211b6e521f',1,'Xdf']]] ]; diff --git a/docs/html/struct_xdf_1_1_stream-members.html b/docs/html/struct_xdf_1_1_stream-members.html index c931197..6ca30e5 100644 --- a/docs/html/struct_xdf_1_1_stream-members.html +++ b/docs/html/struct_xdf_1_1_stream-members.html @@ -1,21 +1,14 @@ - + - + -libxdf: Member List +Libxdf: Member List - - - - - @@ -28,44 +21,31 @@ -
    libxdf -  0.92 +
    Libxdf
    -
    A static C++ library for loading XDF files
    +
    A C++ library for loading XDF files
    - + +/* @license-end */ - -
    - -
    -
    -
    - -
    + +
    - - + diff --git a/docs/html/struct_xdf_1_1_stream.html b/docs/html/struct_xdf_1_1_stream.html index 688138a..5119af5 100644 --- a/docs/html/struct_xdf_1_1_stream.html +++ b/docs/html/struct_xdf_1_1_stream.html @@ -1,21 +1,14 @@ - + - + -libxdf: Xdf::Stream Class Reference +Libxdf: Xdf::Stream Class Reference - - - - - @@ -28,44 +21,31 @@ -
    libxdf -  0.92 +
    Libxdf
    -
    A static C++ library for loading XDF files
    +
    A C++ library for loading XDF files
    - + +/* @license-end */ - -
    - -
    -
    -
    - -
    + +
    Public Attributes | @@ -94,15 +79,14 @@

    Public Attributes

    std::vector< std::vector< float > > time_series - A 2D vector which stores the time series of a stream. Each row represents a channel. More...
      -std::vector< float > time_stamps -  -std::string streamHeader -  -std::string streamFooter -  -struct { +std::vector< double > timestamps +  +std::string stream_header +  +std::string stream_footer +  +struct {    int   channel_count      double   nominal_srate @@ -123,26 +107,24 @@      int   sample_count   -   double   measured_srate -  -   double   effective_sample_rate -  -} info -  -float last_timestamp { 0 } -  -float sampling_interval -  +   double   measured_sampling_rate +  +   double   effective_sampling_rate = 0 +  +} info +  +double sampling_interval +  std::vector< double > clock_times   std::vector< double > clock_values  

    Detailed Description

    -

    XDF files uses stream as the unit to store data. An XDF file usually contains multiple streams, while each of them may contain one or more channels. The Stream class provides a handy way to store all the meta-data, time-series, time-stamps and all other information of a single stream from an XDF file.

    +

    XDF files uses stream as the unit to store data. An XDF file usually contains multiple streams, each of which may contain one or more channels. The Stream struct stores meta-data, time series, timetamps and other information of a stream.

    Member Data Documentation

    -

    § channel_count

    +

    ◆ channel_count

    -

    § channel_format

    +

    ◆ channel_format

    -

    § channels

    +

    ◆ channels

    -

    § clock_offsets

    +

    ◆ clock_offsets

    -

    § clock_times

    +

    ◆ clock_times

    -

    § clock_values

    +

    ◆ clock_values

    - -

    § effective_sample_rate

    + +

    ◆ effective_sampling_rate

    - +
    double Xdf::Stream::effective_sample_ratedouble Xdf::Stream::effective_sampling_rate = 0
    -

    Effective sample rate.

    +

    Effective sampling rate.

    -

    § first_timestamp

    +

    ◆ first_timestamp

    - -

    § info

    + +

    ◆ info

    - +
    struct { ... } Xdf::Stream::infostruct { ... } Xdf::Stream::info
    @@ -277,52 +259,38 @@

    -

    § last_timestamp [1/2]

    - -
    -
    - - - - -
    double Xdf::Stream::last_timestamp
    -
    -

    Last time stamp of the stream.

    - -
    -
    - -

    § last_timestamp [2/2]

    +

    ◆ last_timestamp

    - +
    float Xdf::Stream::last_timestamp { 0 }double Xdf::Stream::last_timestamp {0}
    +

    Last timestamp of the stream.

    For temporary use while loading the vector

    - -

    § measured_srate

    + +

    ◆ measured_sampling_rate

    - +
    double Xdf::Stream::measured_sratedouble Xdf::Stream::measured_sampling_rate
    -

    Measured sample rate of the stream.

    +

    Measured sampling rate of the stream.

    -

    § name

    +

    ◆ name

    -

    § nominal_srate

    +

    ◆ nominal_srate

    -

    § sample_count

    +

    ◆ sample_count

    @@ -366,53 +334,53 @@

    -

    § sampling_interval

    + +

    ◆ sampling_interval

    - +
    float Xdf::Stream::sampling_intervaldouble Xdf::Stream::sampling_interval
    -

    If srate > 0, sampling_interval = 1/srate; otherwise 0

    +

    sampling_interval = 1/sampling_rate if sampling_rate > 0, otherwise 0

    - -

    § streamFooter

    + +

    ◆ stream_footer

    - +
    std::string Xdf::Stream::streamFooterstd::string Xdf::Stream::stream_footer
    -

    Raw XDF of stream footer chunk.

    +

    Raw XML of stream footer chunk.

    - -

    § streamHeader

    + +

    ◆ stream_header

    - +
    std::string Xdf::Stream::streamHeaderstd::string Xdf::Stream::stream_header
    -

    Raw XDF of stream header chunk.

    +

    Raw XML of stream header chunk.

    -

    § time_series

    +

    ◆ time_series

    - -

    § time_stamps

    + +

    ◆ timestamps

    - +
    std::vector<float> Xdf::Stream::time_stampsstd::vector<double> Xdf::Stream::timestamps
    -

    A vector to store time stamps.

    +

    Stores the timestamps.

    -

    § type

    +

    ◆ type


    The documentation for this class was generated from the following file:

    -
    - + diff --git a/docs/html/tabs.css b/docs/html/tabs.css index a28614b..85a0cd5 100644 --- a/docs/html/tabs.css +++ b/docs/html/tabs.css @@ -1 +1 @@ -.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#doc-content{overflow:auto;display:block;padding:0;margin:0;-webkit-overflow-scrolling:touch}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace!important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0!important;-webkit-border-radius:0;border-radius:0!important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px!important;-webkit-border-radius:5px;border-radius:5px!important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0!important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px!important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} \ No newline at end of file +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace!important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0!important;-webkit-border-radius:0;border-radius:0!important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px!important;-webkit-border-radius:5px;border-radius:5px!important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0!important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px!important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} \ No newline at end of file diff --git a/docs/html/xdf_8h.html b/docs/html/xdf_8h.html index 1773f04..2997d83 100644 --- a/docs/html/xdf_8h.html +++ b/docs/html/xdf_8h.html @@ -1,21 +1,14 @@ - + - + -libxdf: C:/Users/Yida Lin/Documents/GitHub/libxdf/libxdf/xdf.h File Reference +Libxdf: xdf.h File Reference - - - - - @@ -28,44 +21,31 @@ -
    libxdf -  0.92 +
    Libxdf
    -
    A static C++ library for loading XDF files
    +
    A C++ library for loading XDF files
    - + +/* @license-end */ -

    -
    - -
    -
    -
    - -
    +
    @@ -107,15 +88,11 @@

    Detailed Description

    The header file of Xdf class.

    -
    - + diff --git a/docs/html/xdf_8h_source.html b/docs/html/xdf_8h_source.html index 9837577..6aea66c 100644 --- a/docs/html/xdf_8h_source.html +++ b/docs/html/xdf_8h_source.html @@ -1,21 +1,14 @@ - + - + -libxdf: C:/Users/Yida Lin/Documents/GitHub/libxdf/libxdf/xdf.h Source File +Libxdf: xdf.h Source File - - - - - @@ -28,44 +21,32 @@ -
    libxdf -  0.92 +
    Libxdf
    -
    A static C++ library for loading XDF files
    +
    A C++ library for loading XDF files
    - + +/* @license-end */
    -
    - -
    -
    -
    - -
    xdf.h
    -Go to the documentation of this file.
    1 //libxdf is a static C++ library to load XDF files
    2 //Copyright (C) 2017 Yida Lin
    3 
    4 //This program is free software: you can redistribute it and/or modify
    5 //it under the terms of the GNU General Public License as published by
    6 //the Free Software Foundation, either version 3 of the License, or
    7 //(at your option) any later version.
    8 
    9 //This program is distributed in the hope that it will be useful,
    10 //but WITHOUT ANY WARRANTY; without even the implied warranty of
    11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12 //GNU General Public License for more details.
    13 
    14 //You should have received a copy of the GNU General Public License
    15 //along with this program. If not, see <http://www.gnu.org/licenses/>.
    16 //If you have questions, contact author at ITAL_FAZIOLI@hotmail.com
    17 
    22 #ifndef XDF_H
    23 #define XDF_H
    24 
    25 #include <string>
    26 #include <vector>
    27 #include <map>
    28 #include <set>
    29 
    37 class Xdf
    38 {
    39 public:
    41  Xdf();
    42 
    43  //subclass for single streams
    53  struct Stream
    54  {
    56  std::vector<std::vector<float> > time_series;
    57  std::vector<float> time_stamps;
    58  std::string streamHeader;
    59  std::string streamFooter;
    61  struct
    62  {
    64  double nominal_srate;
    65  std::string name;
    66  std::string type;
    67  std::string channel_format;
    69  std::vector<std::map<std::string, std::string> > channels;
    71  std::vector<std::pair<double, double> > clock_offsets;
    73  double first_timestamp;
    74  double last_timestamp;
    76  double measured_srate;
    78  } info;
    80  float last_timestamp{ 0 };
    82  std::vector<double> clock_times;
    83  std::vector<double> clock_values;
    84  };
    85 
    86  //XDF properties=================================================================================
    87 
    88  std::vector<Stream> streams;
    89  float version;
    91  uint64_t totalLen = 0;
    94  float minTS = 0;
    95  float maxTS = 0;
    96  size_t totalCh = 0;
    97  int majSR = 0;
    98  int maxSR = 0;
    99  std::vector<int> streamMap;
    107  typedef std::string eventName;
    113  typedef float eventTimeStamp;
    114 
    115  std::vector<std::pair<std::pair<eventName, eventTimeStamp>, int> > eventMap;
    117  std::vector<std::string> dictionary;
    118  std::vector<uint16_t> eventType;
    119  std::vector<std::string> labels;
    120  std::set<double> sampleRateMap;
    121  std::vector<float> offsets;
    123  std::string fileHeader;
    124  int userAddedStream { 0 };
    127  std::vector<std::pair<std::string, double> > userCreatedEvents;
    129  //Public Functions==============================================================================================
    130 
    142  void adjustTotalLength();
    143 
    154  void calcTotalLength(int sampleRate);
    155 
    160  void createLabels();
    161 
    174  void detrend();
    175 
    186  void freeUpTimeStamps();
    187 
    193  int load_xdf(std::string filename);
    194 
    200  void resample(int userSrate);
    201 
    208  int writeEventsToXDF(std::string file_path);
    209 
    210  //Private Functions: Not intended to be used by external programs======================================
    211 
    212 private:
    213 
    217  void calcEffectiveSrate();
    218 
    229  void calcTotalChannel();
    230 
    251  void findMajSR();
    252 
    259  void findMinMax();
    260 
    267  void getHighestSampleRate();
    268 
    274  void loadDictionary();
    275 
    281  void loadSampleRateMap();
    282 
    292  uint64_t readLength(std::ifstream &file);
    293 };
    294 
    295 #endif // XDF_H
    std::string eventName
    Used as std::vector<std::pair<std::pair<eventName, eventTimeStamp>, int> > in eventMap.
    Definition: xdf.h:107
    -
    double measured_srate
    Definition: xdf.h:76
    -
    std::vector< std::string > dictionary
    Definition: xdf.h:117
    -
    double last_timestamp
    Definition: xdf.h:74
    -
    std::vector< double > clock_values
    Definition: xdf.h:83
    -
    void freeUpTimeStamps()
    Delete the time stamps vectors when no longer needed to release some memory.
    Definition: xdf.cpp:760
    -
    std::vector< std::pair< std::string, double > > userCreatedEvents
    Definition: xdf.h:127
    -
    int userAddedStream
    Definition: xdf.h:124
    -
    int majSR
    Definition: xdf.h:97
    -
    size_t totalCh
    Definition: xdf.h:96
    -
    float minTS
    Definition: xdf.h:94
    -
    std::string streamFooter
    Definition: xdf.h:59
    -
    std::vector< uint16_t > eventType
    Definition: xdf.h:118
    -
    std::vector< double > clock_times
    Definition: xdf.h:82
    -
    Definition: xdf.h:53
    -
    float maxTS
    Definition: xdf.h:95
    -
    void detrend()
    Subtract the entire channel by its mean.
    Definition: xdf.cpp:803
    -
    std::vector< std::vector< float > > time_series
    A 2D vector which stores the time series of a stream. Each row represents a channel.
    Definition: xdf.h:56
    -
    std::string type
    Definition: xdf.h:66
    -
    std::vector< Stream > streams
    Definition: xdf.h:88
    -
    void adjustTotalLength()
    Adjust totalLen to avoid possible deviation.
    Definition: xdf.cpp:776
    -
    std::string name
    Definition: xdf.h:65
    -
    int writeEventsToXDF(std::string file_path)
    writeEventsToXDF
    Definition: xdf.cpp:851
    -
    std::vector< std::pair< std::pair< eventName, eventTimeStamp >, int > > eventMap
    Definition: xdf.h:115
    -
    float eventTimeStamp
    Used as std::vector<std::pair<std::pair<eventName, eventTimeStamp>, int> > in eventMap.
    Definition: xdf.h:113
    -
    Definition: xdf.h:37
    -
    void createLabels()
    Create labels for each channel and store them in labels vector.
    Definition: xdf.cpp:940
    -
    void resample(int userSrate)
    Resample all streams and channel to a chosen sample rate.
    Definition: xdf.cpp:537
    -
    int channel_count
    Definition: xdf.h:63
    -
    Xdf()
    Default constructor with no parameter.
    Definition: xdf.cpp:30
    -
    std::vector< std::string > labels
    Definition: xdf.h:119
    -
    int maxSR
    Definition: xdf.h:98
    -
    std::string channel_format
    Definition: xdf.h:67
    -
    double first_timestamp
    Definition: xdf.h:73
    -
    struct Xdf::Stream::@0 info
    -
    std::set< double > sampleRateMap
    Definition: xdf.h:120
    -
    std::vector< int > streamMap
    Definition: xdf.h:99
    -
    float sampling_interval
    Definition: xdf.h:81
    -
    float version
    Definition: xdf.h:89
    -
    std::vector< float > offsets
    Definition: xdf.h:121
    -
    double effective_sample_rate
    Definition: xdf.h:77
    -
    uint64_t totalLen
    Definition: xdf.h:91
    -
    void calcTotalLength(int sampleRate)
    Calculate the globle length (in samples).
    Definition: xdf.cpp:755
    -
    int load_xdf(std::string filename)
    The main function of loading an XDF file.
    Definition: xdf.cpp:34
    -
    int sample_count
    Definition: xdf.h:75
    -
    std::string fileHeader
    Definition: xdf.h:123
    -
    std::vector< std::pair< double, double > > clock_offsets
    Definition: xdf.h:71
    -
    std::string streamHeader
    Definition: xdf.h:58
    -
    std::vector< std::map< std::string, std::string > > channels
    Definition: xdf.h:69
    -
    std::vector< float > time_stamps
    Definition: xdf.h:57
    -
    double nominal_srate
    Definition: xdf.h:64
    +Go to the documentation of this file.
    1 //libxdf is a static C++ library to load XDF files
    +
    2 //Copyright (C) 2017 Yida Lin
    +
    3 
    +
    4 //This program is free software: you can redistribute it and/or modify
    +
    5 //it under the terms of the GNU General Public License as published by
    +
    6 //the Free Software Foundation, either version 3 of the License, or
    +
    7 //(at your option) any later version.
    +
    8 
    +
    9 //This program is distributed in the hope that it will be useful,
    +
    10 //but WITHOUT ANY WARRANTY; without even the implied warranty of
    +
    11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    +
    12 //GNU General Public License for more details.
    +
    13 
    +
    14 //You should have received a copy of the GNU General Public License
    +
    15 //along with this program. If not, see <http://www.gnu.org/licenses/>.
    +
    16 //If you have questions, contact author at yida.lin@outlook.com
    +
    17 
    +
    22 #ifndef XDF_H
    +
    23 #define XDF_H
    +
    24 
    +
    25 #include <string>
    +
    26 #include <vector>
    +
    27 #include <map>
    +
    28 #include <set>
    +
    29 
    +
    37 class Xdf
    +
    38 {
    +
    39 public:
    +
    41  Xdf();
    +
    42 
    +
    50  struct Stream
    +
    51  {
    +
    52  std::vector<std::vector<float>> time_series;
    +
    53  std::vector<double> timestamps;
    +
    54  std::string stream_header;
    +
    55  std::string stream_footer;
    +
    57  struct
    +
    58  {
    + +
    60  double nominal_srate;
    +
    61  std::string name;
    +
    62  std::string type;
    +
    63  std::string channel_format;
    +
    65  std::vector<std::map<std::string, std::string>> channels;
    +
    66  std::vector<std::pair<double, double> > clock_offsets;
    +
    68  double first_timestamp;
    +
    69  double last_timestamp;
    + + + +
    73  } info;
    +
    75  double last_timestamp{0};
    + +
    77  std::vector<double> clock_times;
    +
    78  std::vector<double> clock_values;
    +
    79  };
    +
    80 
    +
    81  std::vector<Stream> streams_;
    +
    82  float version_;
    +
    84  uint64_t total_len_ = 0;
    +
    86  double min_timestamp_ = 0;
    +
    87  double max_timestamp_ = 0;
    +
    88  size_t channel_count_ = 0;
    + + +
    91  std::vector<double> effective_sampling_rates_;
    + +
    93  std::vector<int> stream_map_;
    +
    99  typedef std::string event_name_;
    +
    104  typedef double event_timestamp_;
    +
    105 
    +
    106  std::vector<std::pair<std::pair<event_name_, event_timestamp_>, int>> event_map_;
    +
    107  std::vector<std::string> dictionary_;
    +
    108  std::vector<uint16_t> event_type_;
    +
    109  std::vector<std::string> labels_;
    +
    110  std::set<double> sampling_rate_map_;
    +
    111  std::vector<float> offsets_;
    +
    113  std::string file_header_;
    + +
    115  std::vector<std::pair<std::string, double> > user_created_events_;
    +
    128  void adjust_total_length();
    +
    129 
    +
    139  void calculate_total_length(int sampling_rate);
    +
    140 
    +
    145  void create_labels();
    +
    146 
    +
    158  void detrend();
    +
    159 
    +
    170  void free_up_timestamps();
    +
    171 
    +
    176  int load_xdf(std::string filename);
    +
    177 
    +
    183  void resample(int sampling_rate);
    +
    184 
    +
    188  void sync_timestamps();
    +
    189 
    +
    195  int write_events_to_xdf(std::string file_path);
    +
    196 
    +
    197 private:
    +
    198 
    +
    202  void calculate_effective_sampling_rate();
    +
    203 
    +
    212  void calculate_channel_count();
    +
    213 
    +
    226  void find_major_sampling_rate();
    +
    227 
    +
    233  void find_max_sampling_rate();
    +
    234 
    +
    241  void find_min_max_time_stamps();
    +
    242 
    +
    248  void load_dictionary();
    +
    249 
    +
    255  void load_sampling_rate_map();
    +
    256 
    +
    267  uint64_t read_length(std::ifstream &file);
    +
    268 
    +
    284  template<typename T> T read_bin(std::istream& is, T* obj = nullptr);
    +
    285 };
    +
    286 
    +
    287 #endif // XDF_H
    -
    +
    void free_up_timestamps()
    Deletes Stream::time_stamps when no longer needed (to release memory).
    Definition: xdf.cpp:826
    +
    std::string channel_format
    Definition: xdf.h:63
    +
    Definition: xdf.h:38
    +
    int major_sampling_rate_
    Definition: xdf.h:89
    +
    int channel_count
    Definition: xdf.h:59
    +
    void resample(int sampling_rate)
    Resamples all streams and channels to sampling_rate.
    Definition: xdf.cpp:621
    +
    std::set< double > sampling_rate_map_
    Definition: xdf.h:110
    +
    std::vector< std::string > labels_
    Definition: xdf.h:109
    +
    std::vector< Stream > streams_
    Definition: xdf.h:81
    +
    double first_timestamp
    Definition: xdf.h:68
    +
    void sync_timestamps()
    Sync the timestamps.
    Definition: xdf.cpp:534
    +
    void detrend()
    Subtracts all data in a channel by the mean.
    Definition: xdf.cpp:870
    +
    struct Xdf::Stream::@0 info
    +
    double event_timestamp_
    An alias of double type used on event timestamps.
    Definition: xdf.h:104
    +
    void calculate_total_length(int sampling_rate)
    Calculates the global length (in samples).
    Definition: xdf.cpp:821
    +
    std::vector< std::pair< std::pair< event_name_, event_timestamp_ >, int > > event_map_
    Definition: xdf.h:106
    +
    float version_
    Definition: xdf.h:82
    +
    double effective_sampling_rate
    Definition: xdf.h:72
    +
    std::vector< std::pair< std::string, double > > user_created_events_
    Definition: xdf.h:115
    +
    std::vector< double > effective_sampling_rates_
    Definition: xdf.h:91
    +
    std::vector< double > timestamps
    Definition: xdf.h:53
    +
    int max_sampling_rate_
    Definition: xdf.h:90
    +
    std::vector< std::pair< double, double > > clock_offsets
    Definition: xdf.h:66
    +
    std::vector< std::map< std::string, std::string > > channels
    Definition: xdf.h:65
    +
    Xdf()
    Default constructor with no parameter.
    Definition: xdf.cpp:32
    +
    int load_xdf(std::string filename)
    Loads an XDF file.
    Definition: xdf.cpp:36
    +
    void create_labels()
    Creates labels for each channel and stores them in labels_.
    Definition: xdf.cpp:1010
    +
    int sample_count
    Definition: xdf.h:70
    +
    std::vector< float > offsets_
    Definition: xdf.h:111
    +
    std::string event_name_
    An alias of std::string type used on event names.
    Definition: xdf.h:99
    +
    double nominal_srate
    Definition: xdf.h:60
    +
    Definition: xdf.h:51
    +
    double last_timestamp
    Definition: xdf.h:69
    +
    std::string stream_header
    Definition: xdf.h:54
    +
    double max_timestamp_
    Definition: xdf.h:87
    +
    std::vector< double > clock_values
    Definition: xdf.h:78
    +
    double sampling_interval
    Definition: xdf.h:76
    +
    double measured_sampling_rate
    Definition: xdf.h:71
    +
    double file_effective_sampling_rate_
    Definition: xdf.h:92
    +
    std::string stream_footer
    Definition: xdf.h:55
    +
    std::vector< int > stream_map_
    Definition: xdf.h:93
    +
    uint64_t total_len_
    Definition: xdf.h:84
    +
    int write_events_to_xdf(std::string file_path)
    Writes events to the XDF file. Used when user added markups and/or events in SigViewer,...
    Definition: xdf.cpp:921
    +
    std::vector< std::string > dictionary_
    Definition: xdf.h:107
    +
    void adjust_total_length()
    Adjusts total_len_ to avoid possible deviation.
    Definition: xdf.cpp:843
    +
    std::vector< std::vector< float > > time_series
    Definition: xdf.h:52
    +
    std::vector< uint16_t > event_type_
    Definition: xdf.h:108
    +
    std::string type
    Definition: xdf.h:62
    +
    std::vector< double > clock_times
    Definition: xdf.h:77
    +
    size_t channel_count_
    Definition: xdf.h:88
    +
    std::string file_header_
    Definition: xdf.h:113
    +
    double min_timestamp_
    Definition: xdf.h:86
    +
    std::string name
    Definition: xdf.h:61
    +
    int user_added_stream_
    Definition: xdf.h:114
    - + diff --git a/docs/latex/annotated.tex b/docs/latex/annotated.tex new file mode 100644 index 0000000..871b474 --- /dev/null +++ b/docs/latex/annotated.tex @@ -0,0 +1,5 @@ +\doxysection{Class List} +Here are the classes, structs, unions and interfaces with brief descriptions\+:\begin{DoxyCompactList} +\item\contentsline{section}{\mbox{\hyperlink{struct_xdf_1_1_stream}{Xdf\+::\+Stream}} }{\pageref{struct_xdf_1_1_stream}}{} +\item\contentsline{section}{\mbox{\hyperlink{class_xdf}{Xdf}} }{\pageref{class_xdf}}{} +\end{DoxyCompactList} diff --git a/docs/latex/class_xdf.tex b/docs/latex/class_xdf.tex new file mode 100644 index 0000000..801a6a7 --- /dev/null +++ b/docs/latex/class_xdf.tex @@ -0,0 +1,360 @@ +\hypertarget{class_xdf}{}\doxysection{Xdf Class Reference} +\label{class_xdf}\index{Xdf@{Xdf}} + + +{\ttfamily \#include $<$xdf.\+h$>$} + +\doxysubsection*{Classes} +\begin{DoxyCompactItemize} +\item +class \mbox{\hyperlink{struct_xdf_1_1_stream}{Stream}} +\end{DoxyCompactItemize} +\doxysubsection*{Public Types} +\begin{DoxyCompactItemize} +\item +typedef std\+::string \mbox{\hyperlink{class_xdf_a57eb7fdd01251b7613a7d106625ff019}{event\+\_\+name\+\_\+}} +\begin{DoxyCompactList}\small\item\em An alias of std\+::string type used on event names. \end{DoxyCompactList}\item +typedef double \mbox{\hyperlink{class_xdf_a4cf524f9428b9438b70cb17ea3f2d547}{event\+\_\+timestamp\+\_\+}} +\begin{DoxyCompactList}\small\item\em An alias of double type used on event timestamps. \end{DoxyCompactList}\end{DoxyCompactItemize} +\doxysubsection*{Public Member Functions} +\begin{DoxyCompactItemize} +\item +\mbox{\Hypertarget{class_xdf_a7900b5a4f3792b9d59a5d43db821607e}\label{class_xdf_a7900b5a4f3792b9d59a5d43db821607e}} +\mbox{\hyperlink{class_xdf_a7900b5a4f3792b9d59a5d43db821607e}{Xdf}} () +\begin{DoxyCompactList}\small\item\em Default constructor with no parameter. \end{DoxyCompactList}\item +void \mbox{\hyperlink{class_xdf_ae19b9ae0ee92b8c93fc3fd5be2d2d97f}{adjust\+\_\+total\+\_\+length}} () +\begin{DoxyCompactList}\small\item\em Adjusts {\ttfamily total\+\_\+len\+\_\+} to avoid possible deviation. \end{DoxyCompactList}\item +void \mbox{\hyperlink{class_xdf_a72175fdbb081994f05b388e5ba92c903}{calculate\+\_\+total\+\_\+length}} (int sampling\+\_\+rate) +\begin{DoxyCompactList}\small\item\em Calculates the global length (in samples). \end{DoxyCompactList}\item +void \mbox{\hyperlink{class_xdf_ab81f7f275ab38269d76be6ad0fdc9e29}{create\+\_\+labels}} () +\begin{DoxyCompactList}\small\item\em Creates labels for each channel and stores them in {\ttfamily labels\+\_\+}. \end{DoxyCompactList}\item +void \mbox{\hyperlink{class_xdf_a4d2c5859af84542a15a80c906465f4e3}{detrend}} () +\begin{DoxyCompactList}\small\item\em Subtracts all data in a channel by the mean. \end{DoxyCompactList}\item +void \mbox{\hyperlink{class_xdf_a957461547bca42a5314dafaaf307c1ee}{free\+\_\+up\+\_\+timestamps}} () +\begin{DoxyCompactList}\small\item\em Deletes {\ttfamily Stream\+::time\+\_\+stamps} when no longer needed (to release memory). \end{DoxyCompactList}\item +int \mbox{\hyperlink{class_xdf_a993e94535d6d9e544a64ffbbb2bb4e8c}{load\+\_\+xdf}} (std\+::string filename) +\begin{DoxyCompactList}\small\item\em Loads an X\+DF file. \end{DoxyCompactList}\item +void \mbox{\hyperlink{class_xdf_a4ef5de06800e56726b6ce4a50ffdb0b4}{resample}} (int sampling\+\_\+rate) +\begin{DoxyCompactList}\small\item\em Resamples all streams and channels to {\ttfamily sampling\+\_\+rate}. \end{DoxyCompactList}\item +\mbox{\Hypertarget{class_xdf_a0b5e111d11282d4ff30020ca35446bd8}\label{class_xdf_a0b5e111d11282d4ff30020ca35446bd8}} +void \mbox{\hyperlink{class_xdf_a0b5e111d11282d4ff30020ca35446bd8}{sync\+\_\+timestamps}} () +\begin{DoxyCompactList}\small\item\em Sync the timestamps. \end{DoxyCompactList}\item +\mbox{\Hypertarget{class_xdf_a991b6c33acf78389826b123a53e106a0}\label{class_xdf_a991b6c33acf78389826b123a53e106a0}} +int \mbox{\hyperlink{class_xdf_a991b6c33acf78389826b123a53e106a0}{write\+\_\+events\+\_\+to\+\_\+xdf}} (std\+::string file\+\_\+path) +\begin{DoxyCompactList}\small\item\em Writes events to the X\+DF file. Used when user added markups and/or events in Sig\+Viewer, this method stores the newly created events to the X\+DF file in a new stream. \end{DoxyCompactList}\end{DoxyCompactItemize} +\doxysubsection*{Public Attributes} +\begin{DoxyCompactItemize} +\item +std\+::vector$<$ \mbox{\hyperlink{struct_xdf_1_1_stream}{Stream}} $>$ \mbox{\hyperlink{class_xdf_adeff1db8c45308d12d7786805eeaad9b}{streams\+\_\+}} +\item +float \mbox{\hyperlink{class_xdf_a0d6728f813bab52c7c325d211b6e521f}{version\+\_\+}} +\item +uint64\+\_\+t \mbox{\hyperlink{class_xdf_a46c39c451c44431846046a5bcc354787}{total\+\_\+len\+\_\+}} = 0 +\item +double \mbox{\hyperlink{class_xdf_a2f24970506cdd71c7de9b1f01162d36c}{min\+\_\+timestamp\+\_\+}} = 0 +\item +double \mbox{\hyperlink{class_xdf_abda66058170e3fdae48b28339bbad2a6}{max\+\_\+timestamp\+\_\+}} = 0 +\item +size\+\_\+t \mbox{\hyperlink{class_xdf_afb6d47c75ebc215eb14aaf9e80133a7f}{channel\+\_\+count\+\_\+}} = 0 +\item +int \mbox{\hyperlink{class_xdf_a89b8115372c91f34e985acd673d502da}{major\+\_\+sampling\+\_\+rate\+\_\+}} = 0 +\item +int \mbox{\hyperlink{class_xdf_a73ea312db24b43eff063c4d223f15d5d}{max\+\_\+sampling\+\_\+rate\+\_\+}} = 0 +\item +std\+::vector$<$ double $>$ \mbox{\hyperlink{class_xdf_a21852b079ed18afa0117d67755a2c68d}{effective\+\_\+sampling\+\_\+rates\+\_\+}} +\item +double \mbox{\hyperlink{class_xdf_a4e36c1e1588711d7d09d2aa26f800f2c}{file\+\_\+effective\+\_\+sampling\+\_\+rate\+\_\+}} = 0 +\item +std\+::vector$<$ int $>$ \mbox{\hyperlink{class_xdf_a4a3b1aadac1f7fa4def94e9eae31fbd7}{stream\+\_\+map\+\_\+}} +\item +std\+::vector$<$ std\+::pair$<$ std\+::pair$<$ \mbox{\hyperlink{class_xdf_a57eb7fdd01251b7613a7d106625ff019}{event\+\_\+name\+\_\+}}, \mbox{\hyperlink{class_xdf_a4cf524f9428b9438b70cb17ea3f2d547}{event\+\_\+timestamp\+\_\+}} $>$, int $>$ $>$ \mbox{\hyperlink{class_xdf_ad92266c3c43f6a508d43040090479726}{event\+\_\+map\+\_\+}} +\item +std\+::vector$<$ std\+::string $>$ \mbox{\hyperlink{class_xdf_a37903ef2145466774f7bb57dd72fb428}{dictionary\+\_\+}} +\item +std\+::vector$<$ uint16\+\_\+t $>$ \mbox{\hyperlink{class_xdf_a6a98e5d14a159cc9b24460f2441d6b4e}{event\+\_\+type\+\_\+}} +\item +std\+::vector$<$ std\+::string $>$ \mbox{\hyperlink{class_xdf_a3a41f6cf908b5e6aa4e83f801b5d245d}{labels\+\_\+}} +\item +std\+::set$<$ double $>$ \mbox{\hyperlink{class_xdf_ae6086c443d6ea7b8940f652edb20aaef}{sampling\+\_\+rate\+\_\+map\+\_\+}} +\item +std\+::vector$<$ float $>$ \mbox{\hyperlink{class_xdf_a640243fd0bf0ed9f80ca8cd6c2c447f1}{offsets\+\_\+}} +\item +std\+::string \mbox{\hyperlink{class_xdf_abb8518a32a84995d60648d1c0fdd6428}{file\+\_\+header\+\_\+}} +\item +int \mbox{\hyperlink{class_xdf_ad90637b4ad2bdb13ecabac25fab44836}{user\+\_\+added\+\_\+stream\+\_\+}} \{0\} +\item +std\+::vector$<$ std\+::pair$<$ std\+::string, double $>$ $>$ \mbox{\hyperlink{class_xdf_aa420a5824343786c9602a7bac77d1e28}{user\+\_\+created\+\_\+events\+\_\+}} +\end{DoxyCompactItemize} + + +\doxysubsection{Detailed Description} +\mbox{\hyperlink{class_xdf}{Xdf}} class stores the data of an X\+DF file. It contains methods to read X\+DF files, store the data, and additional functionalities such as resampling etc. + +\doxysubsection{Member Typedef Documentation} +\mbox{\Hypertarget{class_xdf_a57eb7fdd01251b7613a7d106625ff019}\label{class_xdf_a57eb7fdd01251b7613a7d106625ff019}} +\index{Xdf@{Xdf}!event\_name\_@{event\_name\_}} +\index{event\_name\_@{event\_name\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{event\_name\_}{event\_name\_}} +{\footnotesize\ttfamily typedef std\+::string \mbox{\hyperlink{class_xdf_a57eb7fdd01251b7613a7d106625ff019}{Xdf\+::event\+\_\+name\+\_\+}}} + + + +An alias of std\+::string type used on event names. + +\begin{DoxySeeAlso}{See also} +event\+Map +\end{DoxySeeAlso} +\mbox{\Hypertarget{class_xdf_a4cf524f9428b9438b70cb17ea3f2d547}\label{class_xdf_a4cf524f9428b9438b70cb17ea3f2d547}} +\index{Xdf@{Xdf}!event\_timestamp\_@{event\_timestamp\_}} +\index{event\_timestamp\_@{event\_timestamp\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{event\_timestamp\_}{event\_timestamp\_}} +{\footnotesize\ttfamily typedef double \mbox{\hyperlink{class_xdf_a4cf524f9428b9438b70cb17ea3f2d547}{Xdf\+::event\+\_\+timestamp\+\_\+}}} + + + +An alias of double type used on event timestamps. + +\begin{DoxySeeAlso}{See also} +event\+Map +\end{DoxySeeAlso} + + +\doxysubsection{Member Function Documentation} +\mbox{\Hypertarget{class_xdf_ae19b9ae0ee92b8c93fc3fd5be2d2d97f}\label{class_xdf_ae19b9ae0ee92b8c93fc3fd5be2d2d97f}} +\index{Xdf@{Xdf}!adjust\_total\_length@{adjust\_total\_length}} +\index{adjust\_total\_length@{adjust\_total\_length}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{adjust\_total\_length()}{adjust\_total\_length()}} +{\footnotesize\ttfamily void Xdf\+::adjust\+\_\+total\+\_\+length (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})} + + + +Adjusts {\ttfamily total\+\_\+len\+\_\+} to avoid possible deviation. + +{\ttfamily total\+\_\+len\+\_\+} is calculated by multiplying the difference between {\ttfamily max\+\_\+timestamp\+\_\+} and {\ttfamily min\+\_\+timestamp\+\_\+} by {\ttfamily major\+\_\+sampling\+\_\+rate\+\_\+}. However, this can be inaccurate. In case any channel is longer than {\ttfamily total\+\_\+len\+\_\+}, this function will make {\ttfamily total\+\_\+len\+\_\+} match the length of that channel. + +\begin{DoxySeeAlso}{See also} +\mbox{\hyperlink{class_xdf_a46c39c451c44431846046a5bcc354787}{total\+\_\+len\+\_\+}}, \mbox{\hyperlink{class_xdf_a89b8115372c91f34e985acd673d502da}{major\+\_\+sampling\+\_\+rate\+\_\+}}, \mbox{\hyperlink{class_xdf_a72175fdbb081994f05b388e5ba92c903}{calculate\+\_\+total\+\_\+length()}} +\end{DoxySeeAlso} +\mbox{\Hypertarget{class_xdf_a72175fdbb081994f05b388e5ba92c903}\label{class_xdf_a72175fdbb081994f05b388e5ba92c903}} +\index{Xdf@{Xdf}!calculate\_total\_length@{calculate\_total\_length}} +\index{calculate\_total\_length@{calculate\_total\_length}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{calculate\_total\_length()}{calculate\_total\_length()}} +{\footnotesize\ttfamily void Xdf\+::calculate\+\_\+total\+\_\+length (\begin{DoxyParamCaption}\item[{int}]{sampling\+\_\+rate }\end{DoxyParamCaption})} + + + +Calculates the global length (in samples). + +This is calculated by multiplying the rage from {\ttfamily min\+\_\+timestamp\+\_\+} to {\ttfamily max\+\_\+timestamp\+\_\+} across all channels by {\ttfamily sampling\+\_\+rate}. + + +\begin{DoxyParams}{Parameters} +{\em sampling\+\_\+rate} & The sampling rate used to calculate the total length. \\ +\hline +\end{DoxyParams} +\mbox{\Hypertarget{class_xdf_ab81f7f275ab38269d76be6ad0fdc9e29}\label{class_xdf_ab81f7f275ab38269d76be6ad0fdc9e29}} +\index{Xdf@{Xdf}!create\_labels@{create\_labels}} +\index{create\_labels@{create\_labels}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{create\_labels()}{create\_labels()}} +{\footnotesize\ttfamily void Xdf\+::create\+\_\+labels (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})} + + + +Creates labels for each channel and stores them in {\ttfamily labels\+\_\+}. + +\begin{DoxySeeAlso}{See also} +\mbox{\hyperlink{class_xdf_a3a41f6cf908b5e6aa4e83f801b5d245d}{labels\+\_\+}}, \mbox{\hyperlink{class_xdf_a640243fd0bf0ed9f80ca8cd6c2c447f1}{offsets\+\_\+}} +\end{DoxySeeAlso} +\mbox{\Hypertarget{class_xdf_a4d2c5859af84542a15a80c906465f4e3}\label{class_xdf_a4d2c5859af84542a15a80c906465f4e3}} +\index{Xdf@{Xdf}!detrend@{detrend}} +\index{detrend@{detrend}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{detrend()}{detrend()}} +{\footnotesize\ttfamily void Xdf\+::detrend (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})} + + + +Subtracts all data in a channel by the mean. + +Sig\+Viewer displays both the channel signals as well as the zero baseline. When the mean of a channel is too high or too low it becomes difficult to see the fluctuation. Subtracting the entire channel by its mean makes the signals fluctuate around the zero baseline, thus having better visual effect. The mean of each channel times {\ttfamily -\/1} is stored in {\ttfamily offsets\+\_\+}. + +\begin{DoxySeeAlso}{See also} +\mbox{\hyperlink{class_xdf_a640243fd0bf0ed9f80ca8cd6c2c447f1}{offsets\+\_\+}} +\end{DoxySeeAlso} +\mbox{\Hypertarget{class_xdf_a957461547bca42a5314dafaaf307c1ee}\label{class_xdf_a957461547bca42a5314dafaaf307c1ee}} +\index{Xdf@{Xdf}!free\_up\_timestamps@{free\_up\_timestamps}} +\index{free\_up\_timestamps@{free\_up\_timestamps}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{free\_up\_timestamps()}{free\_up\_timestamps()}} +{\footnotesize\ttfamily void Xdf\+::free\+\_\+up\+\_\+timestamps (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})} + + + +Deletes {\ttfamily Stream\+::time\+\_\+stamps} when no longer needed (to release memory). + +Sig\+Viewer doesn\textquotesingle{}t demand time stamps to display signals except irregular sampling rate channels, events, and the min timestamp of each channel (used to determine where does a channel start when putting all streams together). Hence {\ttfamily Stream\+::time\+\_\+stamps} can be deleted when no longer needed to free up the memory. \mbox{\Hypertarget{class_xdf_a993e94535d6d9e544a64ffbbb2bb4e8c}\label{class_xdf_a993e94535d6d9e544a64ffbbb2bb4e8c}} +\index{Xdf@{Xdf}!load\_xdf@{load\_xdf}} +\index{load\_xdf@{load\_xdf}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{load\_xdf()}{load\_xdf()}} +{\footnotesize\ttfamily int Xdf\+::load\+\_\+xdf (\begin{DoxyParamCaption}\item[{std\+::string}]{filename }\end{DoxyParamCaption})} + + + +Loads an X\+DF file. + + +\begin{DoxyParams}{Parameters} +{\em filename} & The complete path to the target file. \\ +\hline +\end{DoxyParams} +\mbox{\Hypertarget{class_xdf_a4ef5de06800e56726b6ce4a50ffdb0b4}\label{class_xdf_a4ef5de06800e56726b6ce4a50ffdb0b4}} +\index{Xdf@{Xdf}!resample@{resample}} +\index{resample@{resample}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{resample()}{resample()}} +{\footnotesize\ttfamily void Xdf\+::resample (\begin{DoxyParamCaption}\item[{int}]{sampling\+\_\+rate }\end{DoxyParamCaption})} + + + +Resamples all streams and channels to {\ttfamily sampling\+\_\+rate}. + + +\begin{DoxyParams}{Parameters} +{\em $<$tt$>$sampling\+\_\+rate$<$/tt$>$} & in general should be between 1 and the highest sampling rate of the current file. \\ +\hline +\end{DoxyParams} + + +\doxysubsection{Member Data Documentation} +\mbox{\Hypertarget{class_xdf_afb6d47c75ebc215eb14aaf9e80133a7f}\label{class_xdf_afb6d47c75ebc215eb14aaf9e80133a7f}} +\index{Xdf@{Xdf}!channel\_count\_@{channel\_count\_}} +\index{channel\_count\_@{channel\_count\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{channel\_count\_}{channel\_count\_}} +{\footnotesize\ttfamily size\+\_\+t Xdf\+::channel\+\_\+count\+\_\+ = 0} + +The total number of channels. \mbox{\Hypertarget{class_xdf_a37903ef2145466774f7bb57dd72fb428}\label{class_xdf_a37903ef2145466774f7bb57dd72fb428}} +\index{Xdf@{Xdf}!dictionary\_@{dictionary\_}} +\index{dictionary\_@{dictionary\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{dictionary\_}{dictionary\_}} +{\footnotesize\ttfamily std\+::vector$<$std\+::string$>$ Xdf\+::dictionary\+\_\+} + +Stores unique event types with no repetitions. \begin{DoxySeeAlso}{See also} +\mbox{\hyperlink{class_xdf_ad92266c3c43f6a508d43040090479726}{event\+\_\+map\+\_\+}} +\end{DoxySeeAlso} +\mbox{\Hypertarget{class_xdf_a21852b079ed18afa0117d67755a2c68d}\label{class_xdf_a21852b079ed18afa0117d67755a2c68d}} +\index{Xdf@{Xdf}!effective\_sampling\_rates\_@{effective\_sampling\_rates\_}} +\index{effective\_sampling\_rates\_@{effective\_sampling\_rates\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{effective\_sampling\_rates\_}{effective\_sampling\_rates\_}} +{\footnotesize\ttfamily std\+::vector$<$double$>$ Xdf\+::effective\+\_\+sampling\+\_\+rates\+\_\+} + +Effective sampling rates of streams. \mbox{\Hypertarget{class_xdf_ad92266c3c43f6a508d43040090479726}\label{class_xdf_ad92266c3c43f6a508d43040090479726}} +\index{Xdf@{Xdf}!event\_map\_@{event\_map\_}} +\index{event\_map\_@{event\_map\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{event\_map\_}{event\_map\_}} +{\footnotesize\ttfamily std\+::vector$<$std\+::pair$<$std\+::pair$<$\mbox{\hyperlink{class_xdf_a57eb7fdd01251b7613a7d106625ff019}{event\+\_\+name\+\_\+}}, \mbox{\hyperlink{class_xdf_a4cf524f9428b9438b70cb17ea3f2d547}{event\+\_\+timestamp\+\_\+}}$>$, int$>$ $>$ Xdf\+::event\+\_\+map\+\_\+} + +Stores all events across all streams. \mbox{\Hypertarget{class_xdf_a6a98e5d14a159cc9b24460f2441d6b4e}\label{class_xdf_a6a98e5d14a159cc9b24460f2441d6b4e}} +\index{Xdf@{Xdf}!event\_type\_@{event\_type\_}} +\index{event\_type\_@{event\_type\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{event\_type\_}{event\_type\_}} +{\footnotesize\ttfamily std\+::vector$<$uint16\+\_\+t$>$ Xdf\+::event\+\_\+type\+\_\+} + +Stores events by their indices in the dictionary.\begin{DoxySeeAlso}{See also} +\mbox{\hyperlink{class_xdf_a37903ef2145466774f7bb57dd72fb428}{dictionary\+\_\+}}, \mbox{\hyperlink{class_xdf_ad92266c3c43f6a508d43040090479726}{event\+\_\+map\+\_\+}} +\end{DoxySeeAlso} +\mbox{\Hypertarget{class_xdf_a4e36c1e1588711d7d09d2aa26f800f2c}\label{class_xdf_a4e36c1e1588711d7d09d2aa26f800f2c}} +\index{Xdf@{Xdf}!file\_effective\_sampling\_rate\_@{file\_effective\_sampling\_rate\_}} +\index{file\_effective\_sampling\_rate\_@{file\_effective\_sampling\_rate\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{file\_effective\_sampling\_rate\_}{file\_effective\_sampling\_rate\_}} +{\footnotesize\ttfamily double Xdf\+::file\+\_\+effective\+\_\+sampling\+\_\+rate\+\_\+ = 0} + +If effective\+\_\+sampling\+\_\+rates\+\_\+ in all the streams are the same, this is the value. \mbox{\Hypertarget{class_xdf_abb8518a32a84995d60648d1c0fdd6428}\label{class_xdf_abb8518a32a84995d60648d1c0fdd6428}} +\index{Xdf@{Xdf}!file\_header\_@{file\_header\_}} +\index{file\_header\_@{file\_header\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{file\_header\_}{file\_header\_}} +{\footnotesize\ttfamily std\+::string Xdf\+::file\+\_\+header\+\_\+} + +Raw X\+ML of the file header. \mbox{\Hypertarget{class_xdf_a3a41f6cf908b5e6aa4e83f801b5d245d}\label{class_xdf_a3a41f6cf908b5e6aa4e83f801b5d245d}} +\index{Xdf@{Xdf}!labels\_@{labels\_}} +\index{labels\_@{labels\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{labels\_}{labels\_}} +{\footnotesize\ttfamily std\+::vector$<$std\+::string$>$ Xdf\+::labels\+\_\+} + +Stores descriptive labels of each channel. \mbox{\Hypertarget{class_xdf_a89b8115372c91f34e985acd673d502da}\label{class_xdf_a89b8115372c91f34e985acd673d502da}} +\index{Xdf@{Xdf}!major\_sampling\_rate\_@{major\_sampling\_rate\_}} +\index{major\_sampling\_rate\_@{major\_sampling\_rate\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{major\_sampling\_rate\_}{major\_sampling\_rate\_}} +{\footnotesize\ttfamily int Xdf\+::major\+\_\+sampling\+\_\+rate\+\_\+ = 0} + +The sampling rate that was used by the most channels across all streams. \mbox{\Hypertarget{class_xdf_a73ea312db24b43eff063c4d223f15d5d}\label{class_xdf_a73ea312db24b43eff063c4d223f15d5d}} +\index{Xdf@{Xdf}!max\_sampling\_rate\_@{max\_sampling\_rate\_}} +\index{max\_sampling\_rate\_@{max\_sampling\_rate\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{max\_sampling\_rate\_}{max\_sampling\_rate\_}} +{\footnotesize\ttfamily int Xdf\+::max\+\_\+sampling\+\_\+rate\+\_\+ = 0} + +Max sampling rate across all streams. \mbox{\Hypertarget{class_xdf_abda66058170e3fdae48b28339bbad2a6}\label{class_xdf_abda66058170e3fdae48b28339bbad2a6}} +\index{Xdf@{Xdf}!max\_timestamp\_@{max\_timestamp\_}} +\index{max\_timestamp\_@{max\_timestamp\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{max\_timestamp\_}{max\_timestamp\_}} +{\footnotesize\ttfamily double Xdf\+::max\+\_\+timestamp\+\_\+ = 0} + +The max timestamp across all streams. \mbox{\Hypertarget{class_xdf_a2f24970506cdd71c7de9b1f01162d36c}\label{class_xdf_a2f24970506cdd71c7de9b1f01162d36c}} +\index{Xdf@{Xdf}!min\_timestamp\_@{min\_timestamp\_}} +\index{min\_timestamp\_@{min\_timestamp\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{min\_timestamp\_}{min\_timestamp\_}} +{\footnotesize\ttfamily double Xdf\+::min\+\_\+timestamp\+\_\+ = 0} + +The min timestamp across all streams. \mbox{\Hypertarget{class_xdf_a640243fd0bf0ed9f80ca8cd6c2c447f1}\label{class_xdf_a640243fd0bf0ed9f80ca8cd6c2c447f1}} +\index{Xdf@{Xdf}!offsets\_@{offsets\_}} +\index{offsets\_@{offsets\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{offsets\_}{offsets\_}} +{\footnotesize\ttfamily std\+::vector$<$float$>$ Xdf\+::offsets\+\_\+} + +Offsets of each channel after using the {\ttfamily detrend} method. \begin{DoxySeeAlso}{See also} +\mbox{\hyperlink{class_xdf_a4d2c5859af84542a15a80c906465f4e3}{detrend()}} +\end{DoxySeeAlso} +\mbox{\Hypertarget{class_xdf_ae6086c443d6ea7b8940f652edb20aaef}\label{class_xdf_ae6086c443d6ea7b8940f652edb20aaef}} +\index{Xdf@{Xdf}!sampling\_rate\_map\_@{sampling\_rate\_map\_}} +\index{sampling\_rate\_map\_@{sampling\_rate\_map\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{sampling\_rate\_map\_}{sampling\_rate\_map\_}} +{\footnotesize\ttfamily std\+::set$<$double$>$ Xdf\+::sampling\+\_\+rate\+\_\+map\+\_\+} + +Stores sampling rates of all the streams. \mbox{\Hypertarget{class_xdf_a4a3b1aadac1f7fa4def94e9eae31fbd7}\label{class_xdf_a4a3b1aadac1f7fa4def94e9eae31fbd7}} +\index{Xdf@{Xdf}!stream\_map\_@{stream\_map\_}} +\index{stream\_map\_@{stream\_map\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{stream\_map\_}{stream\_map\_}} +{\footnotesize\ttfamily std\+::vector$<$int$>$ Xdf\+::stream\+\_\+map\+\_\+} + +Indexes which channels belong to which stream. The keys are channel numbers, the values are stream numbers. \mbox{\Hypertarget{class_xdf_adeff1db8c45308d12d7786805eeaad9b}\label{class_xdf_adeff1db8c45308d12d7786805eeaad9b}} +\index{Xdf@{Xdf}!streams\_@{streams\_}} +\index{streams\_@{streams\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{streams\_}{streams\_}} +{\footnotesize\ttfamily std\+::vector$<$\mbox{\hyperlink{struct_xdf_1_1_stream}{Stream}}$>$ Xdf\+::streams\+\_\+} + +Stores all streams of the current X\+DF file. \mbox{\Hypertarget{class_xdf_a46c39c451c44431846046a5bcc354787}\label{class_xdf_a46c39c451c44431846046a5bcc354787}} +\index{Xdf@{Xdf}!total\_len\_@{total\_len\_}} +\index{total\_len\_@{total\_len\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{total\_len\_}{total\_len\_}} +{\footnotesize\ttfamily uint64\+\_\+t Xdf\+::total\+\_\+len\+\_\+ = 0} + +The total length is the product of the range between the min timestamp and the max timestamp multiplied by major\+\_\+sampling\+\_\+rate\+\_\+. \mbox{\Hypertarget{class_xdf_ad90637b4ad2bdb13ecabac25fab44836}\label{class_xdf_ad90637b4ad2bdb13ecabac25fab44836}} +\index{Xdf@{Xdf}!user\_added\_stream\_@{user\_added\_stream\_}} +\index{user\_added\_stream\_@{user\_added\_stream\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{user\_added\_stream\_}{user\_added\_stream\_}} +{\footnotesize\ttfamily int Xdf\+::user\+\_\+added\+\_\+stream\+\_\+ \{0\}} + +Used by Sig\+Viewer only\+: if user manually added events in Sig\+Viewer, the events will be stored in a new stream after all current streams with index {\ttfamily user\+\_\+added\+\_\+stream\+\_\+}. \mbox{\Hypertarget{class_xdf_aa420a5824343786c9602a7bac77d1e28}\label{class_xdf_aa420a5824343786c9602a7bac77d1e28}} +\index{Xdf@{Xdf}!user\_created\_events\_@{user\_created\_events\_}} +\index{user\_created\_events\_@{user\_created\_events\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{user\_created\_events\_}{user\_created\_events\_}} +{\footnotesize\ttfamily std\+::vector$<$std\+::pair$<$std\+::string, double$>$ $>$ Xdf\+::user\+\_\+created\+\_\+events\+\_\+} + +Events created by user in Sig\+Viewer. \mbox{\Hypertarget{class_xdf_a0d6728f813bab52c7c325d211b6e521f}\label{class_xdf_a0d6728f813bab52c7c325d211b6e521f}} +\index{Xdf@{Xdf}!version\_@{version\_}} +\index{version\_@{version\_}!Xdf@{Xdf}} +\doxysubsubsection{\texorpdfstring{version\_}{version\_}} +{\footnotesize\ttfamily float Xdf\+::version\+\_\+} + +The version of the X\+DF file. + +The documentation for this class was generated from the following files\+:\begin{DoxyCompactItemize} +\item +\mbox{\hyperlink{xdf_8h}{xdf.\+h}}\item +xdf.\+cpp\end{DoxyCompactItemize} diff --git a/docs/latex/doxygen.sty b/docs/latex/doxygen.sty new file mode 100644 index 0000000..78a5254 --- /dev/null +++ b/docs/latex/doxygen.sty @@ -0,0 +1,576 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{doxygen} + +% Packages used by this style file +\RequirePackage{alltt} +%%\RequirePackage{array} %% moved to refman.tex due to workaround for LaTex 2019 version and unmaintained tabu package +\RequirePackage{calc} +\RequirePackage{float} +%%\RequirePackage{ifthen} %% moved to refman.tex due to workaround for LaTex 2019 version and unmaintained tabu package +\RequirePackage{verbatim} +\RequirePackage[table]{xcolor} +\RequirePackage{longtable_doxygen} +\RequirePackage{tabu_doxygen} +\RequirePackage{fancyvrb} +\RequirePackage{tabularx} +\RequirePackage{multirow} +\RequirePackage{hanging} +\RequirePackage{ifpdf} +\RequirePackage{adjustbox} +\RequirePackage{amssymb} +\RequirePackage{stackengine} +\RequirePackage[normalem]{ulem} % for strikeout, but don't modify emphasis + +%---------- Internal commands used in this style file ---------------- + +\newcommand{\ensurespace}[1]{% + \begingroup% + \setlength{\dimen@}{#1}% + \vskip\z@\@plus\dimen@% + \penalty -100\vskip\z@\@plus -\dimen@% + \vskip\dimen@% + \penalty 9999% + \vskip -\dimen@% + \vskip\z@skip% hide the previous |\vskip| from |\addvspace| + \endgroup% +} + +\newcommand{\DoxyHorRuler}[1]{% + \setlength{\parskip}{0ex plus 0ex minus 0ex}% + \ifthenelse{#1=0}% + {% + \hrule% + }% + {% + \hrulefilll% + }% +} +\newcommand{\DoxyLabelFont}{} +\newcommand{\entrylabel}[1]{% + {% + \parbox[b]{\labelwidth-4pt}{% + \makebox[0pt][l]{\DoxyLabelFont#1}% + \vspace{1.5\baselineskip}% + }% + }% +} + +\newenvironment{DoxyDesc}[1]{% + \ensurespace{4\baselineskip}% + \begin{list}{}{% + \settowidth{\labelwidth}{20pt}% + %\setlength{\parsep}{0pt}% + \setlength{\itemsep}{0pt}% + \setlength{\leftmargin}{\labelwidth+\labelsep}% + \renewcommand{\makelabel}{\entrylabel}% + }% + \item[#1]% +}{% + \end{list}% +} + +\newsavebox{\xrefbox} +\newlength{\xreflength} +\newcommand{\xreflabel}[1]{% + \sbox{\xrefbox}{#1}% + \setlength{\xreflength}{\wd\xrefbox}% + \ifthenelse{\xreflength>\labelwidth}{% + \begin{minipage}{\textwidth}% + \setlength{\parindent}{0pt}% + \hangindent=15pt\bfseries #1\vspace{1.2\itemsep}% + \end{minipage}% + }{% + \parbox[b]{\labelwidth}{\makebox[0pt][l]{\textbf{#1}}}% + }% +} + +%---------- Commands used by doxygen LaTeX output generator ---------- + +% Used by
     ... 
    +\newenvironment{DoxyPre}{% + \small% + \begin{alltt}% +}{% + \end{alltt}% + \normalsize% +} +% Necessary for redefining not defined characters, i.e. "Replacement Character" in tex output. +\newlength{\CodeWidthChar} +\newlength{\CodeHeightChar} +\settowidth{\CodeWidthChar}{?} +\settoheight{\CodeHeightChar}{?} +% Necessary for hanging indent +\newlength{\DoxyCodeWidth} + +\newcommand\DoxyCodeLine[1]{\hangpara{\DoxyCodeWidth}{1}{#1}\par} + +\newcommand\NiceSpace{% + \discretionary{}{\kern\fontdimen2\font}{\kern\fontdimen2\font}% +} + +% Used by @code ... @endcode +\newenvironment{DoxyCode}[1]{% + \par% + \scriptsize% + \normalfont\ttfamily% + \rightskip0pt plus 1fil% + \settowidth{\DoxyCodeWidth}{000000}% + \settowidth{\CodeWidthChar}{?}% + \settoheight{\CodeHeightChar}{?}% + \setlength{\parskip}{0ex plus 0ex minus 0ex}% + \ifthenelse{\equal{#1}{0}} + { + {\lccode`~32 \lowercase{\global\let~}\NiceSpace}\obeyspaces% + } + { + {\lccode`~32 \lowercase{\global\let~}}\obeyspaces% + } + +}{% + \normalfont% + \normalsize% + \settowidth{\CodeWidthChar}{?}% + \settoheight{\CodeHeightChar}{?}% +} + +% Redefining not defined characters, i.e. "Replacement Character" in tex output. +\def\ucr{\adjustbox{width=\CodeWidthChar,height=\CodeHeightChar}{\stackinset{c}{}{c}{-.2pt}{% + \textcolor{white}{\sffamily\bfseries\small ?}}{% + \rotatebox{45}{$\blacksquare$}}}} + +% Used by @example, @include, @includelineno and @dontinclude +\newenvironment{DoxyCodeInclude}[1]{% + \DoxyCode{#1}% +}{% + \endDoxyCode% +} + +% Used by @verbatim ... @endverbatim +\newenvironment{DoxyVerb}{% + \footnotesize% + \verbatim% +}{% + \endverbatim% + \normalsize% +} + +% Used by @verbinclude +\newenvironment{DoxyVerbInclude}{% + \DoxyVerb% +}{% + \endDoxyVerb% +} + +% Used by numbered lists (using '-#' or
      ...
    ) +\newenvironment{DoxyEnumerate}{% + \enumerate% +}{% + \endenumerate% +} + +% Used by bullet lists (using '-', @li, @arg, or
      ...
    ) +\newenvironment{DoxyItemize}{% + \itemize% +}{% + \enditemize% +} + +% Used by description lists (using
    ...
    ) +\newenvironment{DoxyDescription}{% + \description% +}{% + \enddescription% +} + +% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc +% (only if caption is specified) +\newenvironment{DoxyImage}{% + \begin{figure}[H]% + \begin{center}% +}{% + \end{center}% + \end{figure}% +} + +% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc +% (only if no caption is specified) +\newenvironment{DoxyImageNoCaption}{% + \begin{center}% +}{% + \end{center}% +} + +% Used by @image +% (only if inline is specified) +\newenvironment{DoxyInlineImage}{% +}{% +} + +% Used by @attention +\newenvironment{DoxyAttention}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @author and @authors +\newenvironment{DoxyAuthor}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @date +\newenvironment{DoxyDate}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @invariant +\newenvironment{DoxyInvariant}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @note +\newenvironment{DoxyNote}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @post +\newenvironment{DoxyPostcond}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @pre +\newenvironment{DoxyPrecond}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @copyright +\newenvironment{DoxyCopyright}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @remark +\newenvironment{DoxyRemark}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @return and @returns +\newenvironment{DoxyReturn}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @since +\newenvironment{DoxySince}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @see +\newenvironment{DoxySeeAlso}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @version +\newenvironment{DoxyVersion}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @warning +\newenvironment{DoxyWarning}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @internal +\newenvironment{DoxyInternal}[1]{% + \paragraph*{#1}% +}{% +} + +% Used by @par and @paragraph +\newenvironment{DoxyParagraph}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by parameter lists +\newenvironment{DoxyParams}[2][]{% + \tabulinesep=1mm% + \par% + \ifthenelse{\equal{#1}{}}% + {\begin{longtabu*}spread 0pt [l]{|X[-1,l]|X[-1,l]|}}% name + description + {\ifthenelse{\equal{#1}{1}}% + {\begin{longtabu*}spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + name + desc + {\begin{longtabu*}spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + type + name + desc + } + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used for fields of simple structs +\newenvironment{DoxyFields}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|X[-1,l]|}% + \multicolumn{3}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{3}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used for fields simple class style enums +\newenvironment{DoxyEnumFields}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used for parameters within a detailed function description +\newenvironment{DoxyParamCaption}{% + \renewcommand{\item}[2][]{\\ \hspace*{2.0cm} ##1 {\em ##2}}% +}{% +} + +% Used by return value lists +\newenvironment{DoxyRetVals}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used by exception lists +\newenvironment{DoxyExceptions}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used by template parameter lists +\newenvironment{DoxyTemplParams}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used for member lists +\newenvironment{DoxyCompactItemize}{% + \begin{itemize}% + \setlength{\itemsep}{-3pt}% + \setlength{\parsep}{0pt}% + \setlength{\topsep}{0pt}% + \setlength{\partopsep}{0pt}% +}{% + \end{itemize}% +} + +% Used for member descriptions +\newenvironment{DoxyCompactList}{% + \begin{list}{}{% + \setlength{\leftmargin}{0.5cm}% + \setlength{\itemsep}{0pt}% + \setlength{\parsep}{0pt}% + \setlength{\topsep}{0pt}% + \renewcommand{\makelabel}{\hfill}% + }% +}{% + \end{list}% +} + +% Used for reference lists (@bug, @deprecated, @todo, etc.) +\newenvironment{DoxyRefList}{% + \begin{list}{}{% + \setlength{\labelwidth}{10pt}% + \setlength{\leftmargin}{\labelwidth}% + \addtolength{\leftmargin}{\labelsep}% + \renewcommand{\makelabel}{\xreflabel}% + }% +}{% + \end{list}% +} + +% Used by @bug, @deprecated, @todo, etc. +\newenvironment{DoxyRefDesc}[1]{% + \begin{list}{}{% + \renewcommand\makelabel[1]{\textbf{##1}}% + \settowidth\labelwidth{\makelabel{#1}}% + \setlength\leftmargin{\labelwidth+\labelsep}% + }% +}{% + \end{list}% +} + +% Used by parameter lists and simple sections +\newenvironment{Desc} +{\begin{list}{}{% + \settowidth{\labelwidth}{20pt}% + \setlength{\parsep}{0pt}% + \setlength{\itemsep}{0pt}% + \setlength{\leftmargin}{\labelwidth+\labelsep}% + \renewcommand{\makelabel}{\entrylabel}% + } +}{% + \end{list}% +} + +% Used by tables +\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}% +\newenvironment{TabularC}[1]% +{\tabulinesep=1mm +\begin{longtabu*}spread 0pt [c]{*#1{|X[-1]}|}}% +{\end{longtabu*}\par}% + +\newenvironment{TabularNC}[1]% +{\begin{tabu}spread 0pt [l]{*#1{|X[-1]}|}}% +{\end{tabu}\par}% + +% Used for member group headers +\newenvironment{Indent}{% + \begin{list}{}{% + \setlength{\leftmargin}{0.5cm}% + }% + \item[]\ignorespaces% +}{% + \unskip% + \end{list}% +} + +% Used when hyperlinks are turned off +\newcommand{\doxyref}[3]{% + \textbf{#1} (\textnormal{#2}\,\pageref{#3})% +} + +% Used to link to a table when hyperlinks are turned on +\newcommand{\doxytablelink}[2]{% + \ref{#1}% +} + +% Used to link to a table when hyperlinks are turned off +\newcommand{\doxytableref}[3]{% + \ref{#3}% +} + +% Used by @addindex +\newcommand{\lcurly}{\{} +\newcommand{\rcurly}{\}} + +% Colors used for syntax highlighting +\definecolor{comment}{rgb}{0.5,0.0,0.0} +\definecolor{keyword}{rgb}{0.0,0.5,0.0} +\definecolor{keywordtype}{rgb}{0.38,0.25,0.125} +\definecolor{keywordflow}{rgb}{0.88,0.5,0.0} +\definecolor{preprocessor}{rgb}{0.5,0.38,0.125} +\definecolor{stringliteral}{rgb}{0.0,0.125,0.25} +\definecolor{charliteral}{rgb}{0.0,0.5,0.5} +\definecolor{vhdldigit}{rgb}{1.0,0.0,1.0} +\definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43} +\definecolor{vhdllogic}{rgb}{1.0,0.0,0.0} +\definecolor{vhdlchar}{rgb}{0.0,0.0,0.0} + +% Color used for table heading +\newcommand{\tableheadbgcolor}{lightgray}% + +% Version of hypertarget with correct landing location +\newcommand{\Hypertarget}[1]{\Hy@raisedlink{\hypertarget{#1}{}}} + +% possibility to have sections etc. be within the margins +% unfortunately had to copy part of book.cls and add \raggedright +\makeatletter +\newcommand\doxysection{\@startsection {section}{1}{\z@}% + {-3.5ex \@plus -1ex \@minus -.2ex}% + {2.3ex \@plus.2ex}% + {\raggedright\normalfont\Large\bfseries}} +\newcommand\doxysubsection{\@startsection{subsection}{2}{\z@}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {1.5ex \@plus .2ex}% + {\raggedright\normalfont\large\bfseries}} +\newcommand\doxysubsubsection{\@startsection{subsubsection}{3}{\z@}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {1.5ex \@plus .2ex}% + {\raggedright\normalfont\normalsize\bfseries}} +\newcommand\doxyparagraph{\@startsection{paragraph}{4}{\z@}% + {3.25ex \@plus1ex \@minus.2ex}% + {-1em}% + {\raggedright\normalfont\normalsize\bfseries}} +\newcommand\doxysubparagraph{\@startsection{subparagraph}{5}{\parindent}% + {3.25ex \@plus1ex \@minus .2ex}% + {-1em}% + {\raggedright\normalfont\normalsize\bfseries}} +\makeatother +% Define caption that is also suitable in a table +\makeatletter +\def\doxyfigcaption{% +\refstepcounter{figure}% +\@dblarg{\@caption{figure}}} +\makeatother diff --git a/docs/latex/files.tex b/docs/latex/files.tex new file mode 100644 index 0000000..56fd679 --- /dev/null +++ b/docs/latex/files.tex @@ -0,0 +1,4 @@ +\doxysection{File List} +Here is a list of all documented files with brief descriptions\+:\begin{DoxyCompactList} +\item\contentsline{section}{\mbox{\hyperlink{xdf_8h}{xdf.\+h}} \\*The header file of \mbox{\hyperlink{class_xdf}{Xdf}} class }{\pageref{xdf_8h}}{} +\end{DoxyCompactList} diff --git a/docs/latex/longtable_doxygen.sty b/docs/latex/longtable_doxygen.sty new file mode 100644 index 0000000..a0eb314 --- /dev/null +++ b/docs/latex/longtable_doxygen.sty @@ -0,0 +1,448 @@ +%% +%% This is file `longtable.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% longtable.dtx (with options: `package') +%% +%% This is a generated file. +%% +%% The source is maintained by the LaTeX Project team and bug +%% reports for it can be opened at http://latex-project.org/bugs.html +%% (but please observe conditions on bug reports sent to that address!) +%% +%% Copyright 1993-2016 +%% The LaTeX3 Project and any individual authors listed elsewhere +%% in this file. +%% +%% This file was generated from file(s) of the Standard LaTeX `Tools Bundle'. +%% -------------------------------------------------------------------------- +%% +%% It may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3c +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This file may only be distributed together with a copy of the LaTeX +%% `Tools Bundle'. You may however distribute the LaTeX `Tools Bundle' +%% without such generated files. +%% +%% The list of all files belonging to the LaTeX `Tools Bundle' is +%% given in the file `manifest.txt'. +%% +%% File: longtable.dtx Copyright (C) 1990-2001 David Carlisle +\NeedsTeXFormat{LaTeX2e}[1995/06/01] +\ProvidesPackage{longtable_doxygen} + [2014/10/28 v4.11 Multi-page Table package (DPC) - frozen version for doxygen] +\def\LT@err{\PackageError{longtable}} +\def\LT@warn{\PackageWarning{longtable}} +\def\LT@final@warn{% + \AtEndDocument{% + \LT@warn{Table \@width s have changed. Rerun LaTeX.\@gobbletwo}}% + \global\let\LT@final@warn\relax} +\DeclareOption{errorshow}{% + \def\LT@warn{\PackageInfo{longtable}}} +\DeclareOption{pausing}{% + \def\LT@warn#1{% + \LT@err{#1}{This is not really an error}}} +\DeclareOption{set}{} +\DeclareOption{final}{} +\ProcessOptions +\newskip\LTleft \LTleft=\fill +\newskip\LTright \LTright=\fill +\newskip\LTpre \LTpre=\bigskipamount +\newskip\LTpost \LTpost=\bigskipamount +\newcount\LTchunksize \LTchunksize=20 +\let\c@LTchunksize\LTchunksize +\newdimen\LTcapwidth \LTcapwidth=4in +\newbox\LT@head +\newbox\LT@firsthead +\newbox\LT@foot +\newbox\LT@lastfoot +\newcount\LT@cols +\newcount\LT@rows +\newcounter{LT@tables} +\newcounter{LT@chunks}[LT@tables] +\ifx\c@table\undefined + \newcounter{table} + \def\fnum@table{\tablename~\thetable} +\fi +\ifx\tablename\undefined + \def\tablename{Table} +\fi +\newtoks\LT@p@ftn +\mathchardef\LT@end@pen=30000 +\def\longtable{% + \par + \ifx\multicols\@undefined + \else + \ifnum\col@number>\@ne + \@twocolumntrue + \fi + \fi + \if@twocolumn + \LT@err{longtable not in 1-column mode}\@ehc + \fi + \begingroup + \@ifnextchar[\LT@array{\LT@array[x]}} +\def\LT@array[#1]#2{% + \refstepcounter{table}\stepcounter{LT@tables}% + \if l#1% + \LTleft\z@ \LTright\fill + \else\if r#1% + \LTleft\fill \LTright\z@ + \else\if c#1% + \LTleft\fill \LTright\fill + \fi\fi\fi + \let\LT@mcol\multicolumn + \let\LT@@tabarray\@tabarray + \let\LT@@hl\hline + \def\@tabarray{% + \let\hline\LT@@hl + \LT@@tabarray}% + \let\\\LT@tabularcr\let\tabularnewline\\% + \def\newpage{\noalign{\break}}% + \def\pagebreak{\noalign{\ifnum`}=0\fi\@testopt{\LT@no@pgbk-}4}% + \def\nopagebreak{\noalign{\ifnum`}=0\fi\@testopt\LT@no@pgbk4}% + \let\hline\LT@hline \let\kill\LT@kill\let\caption\LT@caption + \@tempdima\ht\strutbox + \let\@endpbox\LT@endpbox + \ifx\extrarowheight\@undefined + \let\@acol\@tabacol + \let\@classz\@tabclassz \let\@classiv\@tabclassiv + \def\@startpbox{\vtop\LT@startpbox}% + \let\@@startpbox\@startpbox + \let\@@endpbox\@endpbox + \let\LT@LL@FM@cr\@tabularcr + \else + \advance\@tempdima\extrarowheight + \col@sep\tabcolsep + \let\@startpbox\LT@startpbox\let\LT@LL@FM@cr\@arraycr + \fi + \setbox\@arstrutbox\hbox{\vrule + \@height \arraystretch \@tempdima + \@depth \arraystretch \dp \strutbox + \@width \z@}% + \let\@sharp##\let\protect\relax + \begingroup + \@mkpream{#2}% + \xdef\LT@bchunk{% + \global\advance\c@LT@chunks\@ne + \global\LT@rows\z@\setbox\z@\vbox\bgroup + \LT@setprevdepth + \tabskip\LTleft \noexpand\halign to\hsize\bgroup + \tabskip\z@ \@arstrut \@preamble \tabskip\LTright \cr}% + \endgroup + \expandafter\LT@nofcols\LT@bchunk&\LT@nofcols + \LT@make@row + \m@th\let\par\@empty + \everycr{}\lineskip\z@\baselineskip\z@ + \LT@bchunk} +\def\LT@no@pgbk#1[#2]{\penalty #1\@getpen{#2}\ifnum`{=0\fi}} +\def\LT@start{% + \let\LT@start\endgraf + \endgraf\penalty\z@\vskip\LTpre + \dimen@\pagetotal + \advance\dimen@ \ht\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi + \advance\dimen@ \dp\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi + \advance\dimen@ \ht\LT@foot + \dimen@ii\vfuzz + \vfuzz\maxdimen + \setbox\tw@\copy\z@ + \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox + \setbox\tw@\vbox{\unvbox\tw@}% + \vfuzz\dimen@ii + \advance\dimen@ \ht + \ifdim\ht\@arstrutbox>\ht\tw@\@arstrutbox\else\tw@\fi + \advance\dimen@\dp + \ifdim\dp\@arstrutbox>\dp\tw@\@arstrutbox\else\tw@\fi + \advance\dimen@ -\pagegoal + \ifdim \dimen@>\z@\vfil\break\fi + \global\@colroom\@colht + \ifvoid\LT@foot\else + \advance\vsize-\ht\LT@foot + \global\advance\@colroom-\ht\LT@foot + \dimen@\pagegoal\advance\dimen@-\ht\LT@foot\pagegoal\dimen@ + \maxdepth\z@ + \fi + \ifvoid\LT@firsthead\copy\LT@head\else\box\LT@firsthead\fi\nobreak + \output{\LT@output}} +\def\endlongtable{% + \crcr + \noalign{% + \let\LT@entry\LT@entry@chop + \xdef\LT@save@row{\LT@save@row}}% + \LT@echunk + \LT@start + \unvbox\z@ + \LT@get@widths + \if@filesw + {\let\LT@entry\LT@entry@write\immediate\write\@auxout{% + \gdef\expandafter\noexpand + \csname LT@\romannumeral\c@LT@tables\endcsname + {\LT@save@row}}}% + \fi + \ifx\LT@save@row\LT@@save@row + \else + \LT@warn{Column \@width s have changed\MessageBreak + in table \thetable}% + \LT@final@warn + \fi + \endgraf\penalty -\LT@end@pen + \endgroup + \global\@mparbottom\z@ + \pagegoal\vsize + \endgraf\penalty\z@\addvspace\LTpost + \ifvoid\footins\else\insert\footins{}\fi} +\def\LT@nofcols#1&{% + \futurelet\@let@token\LT@n@fcols} +\def\LT@n@fcols{% + \advance\LT@cols\@ne + \ifx\@let@token\LT@nofcols + \expandafter\@gobble + \else + \expandafter\LT@nofcols + \fi} +\def\LT@tabularcr{% + \relax\iffalse{\fi\ifnum0=`}\fi + \@ifstar + {\def\crcr{\LT@crcr\noalign{\nobreak}}\let\cr\crcr + \LT@t@bularcr}% + {\LT@t@bularcr}} +\let\LT@crcr\crcr +\let\LT@setprevdepth\relax +\def\LT@t@bularcr{% + \global\advance\LT@rows\@ne + \ifnum\LT@rows=\LTchunksize + \gdef\LT@setprevdepth{% + \prevdepth\z@\global + \global\let\LT@setprevdepth\relax}% + \expandafter\LT@xtabularcr + \else + \ifnum0=`{}\fi + \expandafter\LT@LL@FM@cr + \fi} +\def\LT@xtabularcr{% + \@ifnextchar[\LT@argtabularcr\LT@ntabularcr} +\def\LT@ntabularcr{% + \ifnum0=`{}\fi + \LT@echunk + \LT@start + \unvbox\z@ + \LT@get@widths + \LT@bchunk} +\def\LT@argtabularcr[#1]{% + \ifnum0=`{}\fi + \ifdim #1>\z@ + \unskip\@xargarraycr{#1}% + \else + \@yargarraycr{#1}% + \fi + \LT@echunk + \LT@start + \unvbox\z@ + \LT@get@widths + \LT@bchunk} +\def\LT@echunk{% + \crcr\LT@save@row\cr\egroup + \global\setbox\@ne\lastbox + \unskip + \egroup} +\def\LT@entry#1#2{% + \ifhmode\@firstofone{&}\fi\omit + \ifnum#1=\c@LT@chunks + \else + \kern#2\relax + \fi} +\def\LT@entry@chop#1#2{% + \noexpand\LT@entry + {\ifnum#1>\c@LT@chunks + 1}{0pt% + \else + #1}{#2% + \fi}} +\def\LT@entry@write{% + \noexpand\LT@entry^^J% + \@spaces} +\def\LT@kill{% + \LT@echunk + \LT@get@widths + \expandafter\LT@rebox\LT@bchunk} +\def\LT@rebox#1\bgroup{% + #1\bgroup + \unvbox\z@ + \unskip + \setbox\z@\lastbox} +\def\LT@blank@row{% + \xdef\LT@save@row{\expandafter\LT@build@blank + \romannumeral\number\LT@cols 001 }} +\def\LT@build@blank#1{% + \if#1m% + \noexpand\LT@entry{1}{0pt}% + \expandafter\LT@build@blank + \fi} +\def\LT@make@row{% + \global\expandafter\let\expandafter\LT@save@row + \csname LT@\romannumeral\c@LT@tables\endcsname + \ifx\LT@save@row\relax + \LT@blank@row + \else + {\let\LT@entry\or + \if!% + \ifcase\expandafter\expandafter\expandafter\LT@cols + \expandafter\@gobble\LT@save@row + \or + \else + \relax + \fi + !% + \else + \aftergroup\LT@blank@row + \fi}% + \fi} +\let\setlongtables\relax +\def\LT@get@widths{% + \setbox\tw@\hbox{% + \unhbox\@ne + \let\LT@old@row\LT@save@row + \global\let\LT@save@row\@empty + \count@\LT@cols + \loop + \unskip + \setbox\tw@\lastbox + \ifhbox\tw@ + \LT@def@row + \advance\count@\m@ne + \repeat}% + \ifx\LT@@save@row\@undefined + \let\LT@@save@row\LT@save@row + \fi} +\def\LT@def@row{% + \let\LT@entry\or + \edef\@tempa{% + \ifcase\expandafter\count@\LT@old@row + \else + {1}{0pt}% + \fi}% + \let\LT@entry\relax + \xdef\LT@save@row{% + \LT@entry + \expandafter\LT@max@sel\@tempa + \LT@save@row}} +\def\LT@max@sel#1#2{% + {\ifdim#2=\wd\tw@ + #1% + \else + \number\c@LT@chunks + \fi}% + {\the\wd\tw@}} +\def\LT@hline{% + \noalign{\ifnum0=`}\fi + \penalty\@M + \futurelet\@let@token\LT@@hline} +\def\LT@@hline{% + \ifx\@let@token\hline + \global\let\@gtempa\@gobble + \gdef\LT@sep{\penalty-\@medpenalty\vskip\doublerulesep}% + \else + \global\let\@gtempa\@empty + \gdef\LT@sep{\penalty-\@lowpenalty\vskip-\arrayrulewidth}% + \fi + \ifnum0=`{\fi}% + \multispan\LT@cols + \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr + \noalign{\LT@sep}% + \multispan\LT@cols + \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr + \noalign{\penalty\@M}% + \@gtempa} +\def\LT@caption{% + \noalign\bgroup + \@ifnextchar[{\egroup\LT@c@ption\@firstofone}\LT@capti@n} +\def\LT@c@ption#1[#2]#3{% + \LT@makecaption#1\fnum@table{#3}% + \def\@tempa{#2}% + \ifx\@tempa\@empty\else + {\let\\\space + \addcontentsline{lot}{table}{\protect\numberline{\thetable}{#2}}}% + \fi} +\def\LT@capti@n{% + \@ifstar + {\egroup\LT@c@ption\@gobble[]}% + {\egroup\@xdblarg{\LT@c@ption\@firstofone}}} +\def\LT@makecaption#1#2#3{% + \LT@mcol\LT@cols c{\hbox to\z@{\hss\parbox[t]\LTcapwidth{% + \sbox\@tempboxa{#1{#2: }#3}% + \ifdim\wd\@tempboxa>\hsize + #1{#2: }#3% + \else + \hbox to\hsize{\hfil\box\@tempboxa\hfil}% + \fi + \endgraf\vskip\baselineskip}% + \hss}}} +\def\LT@output{% + \ifnum\outputpenalty <-\@Mi + \ifnum\outputpenalty > -\LT@end@pen + \LT@err{floats and marginpars not allowed in a longtable}\@ehc + \else + \setbox\z@\vbox{\unvbox\@cclv}% + \ifdim \ht\LT@lastfoot>\ht\LT@foot + \dimen@\pagegoal + \advance\dimen@-\ht\LT@lastfoot + \ifdim\dimen@<\ht\z@ + \setbox\@cclv\vbox{\unvbox\z@\copy\LT@foot\vss}% + \@makecol + \@outputpage + \setbox\z@\vbox{\box\LT@head}% + \fi + \fi + \global\@colroom\@colht + \global\vsize\@colht + \vbox + {\unvbox\z@\box\ifvoid\LT@lastfoot\LT@foot\else\LT@lastfoot\fi}% + \fi + \else + \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT@foot\vss}% + \@makecol + \@outputpage + \global\vsize\@colroom + \copy\LT@head\nobreak + \fi} +\def\LT@end@hd@ft#1{% + \LT@echunk + \ifx\LT@start\endgraf + \LT@err + {Longtable head or foot not at start of table}% + {Increase LTchunksize}% + \fi + \setbox#1\box\z@ + \LT@get@widths + \LT@bchunk} +\def\endfirsthead{\LT@end@hd@ft\LT@firsthead} +\def\endhead{\LT@end@hd@ft\LT@head} +\def\endfoot{\LT@end@hd@ft\LT@foot} +\def\endlastfoot{\LT@end@hd@ft\LT@lastfoot} +\def\LT@startpbox#1{% + \bgroup + \let\@footnotetext\LT@p@ftntext + \setlength\hsize{#1}% + \@arrayparboxrestore + \vrule \@height \ht\@arstrutbox \@width \z@} +\def\LT@endpbox{% + \@finalstrut\@arstrutbox + \egroup + \the\LT@p@ftn + \global\LT@p@ftn{}% + \hfil} +\def\LT@p@ftntext#1{% + \edef\@tempa{\the\LT@p@ftn\noexpand\footnotetext[\the\c@footnote]}% + \global\LT@p@ftn\expandafter{\@tempa{#1}}}% + +\@namedef{ver@longtable.sty}{2014/10/28 v4.11 Multi-page Table package (DPC) - frozen version for doxygen} +\endinput +%% +%% End of file `longtable.sty'. diff --git a/docs/latex/make.bat b/docs/latex/make.bat new file mode 100644 index 0000000..55e79ba --- /dev/null +++ b/docs/latex/make.bat @@ -0,0 +1,31 @@ +set Dir_Old=%cd% +cd /D %~dp0 + +del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf + +set LATEX_CMD=pdflatex +%LATEX_CMD% refman +echo ---- +makeindex refman.idx +echo ---- +%LATEX_CMD% refman + +setlocal enabledelayedexpansion +set count=8 +:repeat +set content=X +for /F "tokens=*" %%T in ( 'findstr /C:"Rerun LaTeX" refman.log' ) do set content="%%~T" +if !content! == X for /F "tokens=*" %%T in ( 'findstr /C:"Rerun to get cross-references right" refman.log' ) do set content="%%~T" +if !content! == X goto :skip +set /a count-=1 +if !count! EQU 0 goto :skip + +echo ---- +%LATEX_CMD% refman +goto :repeat +:skip +endlocal +makeindex refman.idx +%LATEX_CMD% refman +cd /D %Dir_Old% +set Dir_Old= diff --git a/docs/latex/md__r_e_a_d_m_e.tex b/docs/latex/md__r_e_a_d_m_e.tex new file mode 100644 index 0000000..39e42cf --- /dev/null +++ b/docs/latex/md__r_e_a_d_m_e.tex @@ -0,0 +1,79 @@ + +\begin{DoxyItemize} +\item \href{\#intro}{\texttt{ Introduction}} +\item \href{\#download}{\texttt{ Download}} +\item \href{\#quick}{\texttt{ Quick-\/\+Start Guide}} +\item \href{\#doc}{\texttt{ Documentation}} +\item \href{\#support}{\texttt{ Support}} +\end{DoxyItemize}\hypertarget{md__r_e_a_d_m_e_autotoc_md1}{}\doxysection{$<$a name=\char`\"{}intro\char`\"{}$>$$<$/a$>$\+Introduction}\label{md__r_e_a_d_m_e_autotoc_md1} +Libxdf is a cross-\/platform C++ library for loading multi-\/modal, multi-\/rate signals stored in \href{https://github.com/sccn/xdf/wiki/Specifications}{\texttt{ X\+DF}} files. Libxdf is used in the biosignal viewing application \href{https://github.com/cbrnr/sigviewer}{\texttt{ Sig\+Viewer}}. It can also be integrated into other C++ applications. + +Libxdf is open-\/source, free, and actively maintained.\hypertarget{md__r_e_a_d_m_e_autotoc_md2}{}\doxysection{$<$a name=\char`\"{}download\char`\"{}$>$$<$/a$>$\+Download}\label{md__r_e_a_d_m_e_autotoc_md2} + +\begin{DoxyItemize} +\item \href{https://github.com/Yida-Lin/libxdf/archive/0.94.zip}{\texttt{ Source code (zip)}} +\item \href{https://github.com/Yida-Lin/libxdf/archive/0.94.tar.gz}{\texttt{ Source code (tar.\+gz)}} +\item \href{https://github.com/Yida-Lin/libxdf/releases}{\texttt{ Pre-\/built binaries}} +\end{DoxyItemize}\hypertarget{md__r_e_a_d_m_e_autotoc_md3}{}\doxysection{$<$a name=\char`\"{}quick\char`\"{}$>$$<$/a$>$\+Quick-\/\+Start Guide}\label{md__r_e_a_d_m_e_autotoc_md3} +\hypertarget{md__r_e_a_d_m_e_autotoc_md4}{}\doxysubsection{Building libxdf}\label{md__r_e_a_d_m_e_autotoc_md4} +Libxdf can be conveniently built either using {\ttfamily qmake} or {\ttfamily cmake}. Configuration files for both build tools are included with the source. + +{\ttfamily cmake} builds a static library by default, but you can build a shared library by setting the \href{https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html}{\texttt{ {\ttfamily B\+U\+I\+L\+D\+\_\+\+S\+H\+A\+R\+E\+D\+\_\+\+L\+I\+BS}}} variable (e.\+g. {\ttfamily -\/D\+B\+U\+I\+L\+D\+\_\+\+S\+H\+A\+R\+E\+D\+\_\+\+L\+I\+BS=ON}).\hypertarget{md__r_e_a_d_m_e_autotoc_md5}{}\doxysubsection{Use in conjunction with $<$a href=\char`\"{}https\+://github.\+com/cbrnr/sigviewer\char`\"{}$>$\+Sig\+Viewer$<$/a$>$}\label{md__r_e_a_d_m_e_autotoc_md5} +Libxdf is a built-\/in component of \href{https://github.com/cbrnr/sigviewer}{\texttt{ Sig\+Viewer}}. If you wish to build Sig\+Viewer from source, follow these steps\+: + + +\begin{DoxyEnumerate} +\item Download {\ttfamily \mbox{\hyperlink{xdf_8h}{xdf.\+h}}} and {\ttfamily libxdf.\+a} from the \href{https://github.com/Yida-Lin/libxdf/releases}{\texttt{ release}} page. +\item Copy {\ttfamily \mbox{\hyperlink{xdf_8h}{xdf.\+h}}} into {\ttfamily sigviewer/external/include} +\item Copy {\ttfamily libxdf.\+a} into {\ttfamily sigviewer/external/lib} +\item Build and run Sigviewer +\end{DoxyEnumerate} + + + +Example\+: Sig\+Viewer using {\itshape libxdf} to display signals in an X\+DF file.\hypertarget{md__r_e_a_d_m_e_autotoc_md6}{}\doxysubsection{Use in other C++ applications}\label{md__r_e_a_d_m_e_autotoc_md6} + +\begin{DoxyEnumerate} +\item Build libxdf from source or use a pre-\/built binary release +\item Instantiate an object of the {\ttfamily \mbox{\hyperlink{class_xdf}{Xdf}}} class and call the {\ttfamily load\+\_\+xdf} method. +\end{DoxyEnumerate} + +Example\+: + + +\begin{DoxyCode}{0} +\DoxyCodeLine{ \{C++\}} +\DoxyCodeLine{\#include "xdf.h"} +\DoxyCodeLine{} +\DoxyCodeLine{Xdf xdf;} +\DoxyCodeLine{xdf.load\_xdf("C:/example.xdf");} +\end{DoxyCode} + + +To resample the signals, e.\+g. to 100Hz\+: + + +\begin{DoxyCode}{0} +\DoxyCodeLine{ \{C++\}} +\DoxyCodeLine{xdf.resample(100);} +\end{DoxyCode} + + +The methods in libxdf must be called following a certain order. For instance, if you call the {\ttfamily detrend} method before you load any data, it will cause undefined behavior. + +The recommended order is shown here. Only {\ttfamily load\+\_\+xdf} is mandatory. + + +\begin{DoxyCode}{0} +\DoxyCodeLine{ \{C++\}} +\DoxyCodeLine{xdf.load\_xdf(std::string filepath);} +\DoxyCodeLine{xdf.detrend();} +\DoxyCodeLine{xdf.create\_labels();} +\DoxyCodeLine{xdf.resample(int sampling\_rate);} +\DoxyCodeLine{xdf.free\_up\_time\_stamps();} +\end{DoxyCode} + + +Libxdf depends on third party libraries \href{http://pugixml.org/}{\texttt{ Pugixml v1.\+8}} for X\+ML parsing and \href{http://audio-smarc.sourceforge.net/}{\texttt{ Smarc}} for resampling.\hypertarget{md__r_e_a_d_m_e_autotoc_md7}{}\doxysection{$<$a name=\char`\"{}doc\char`\"{}$>$$<$/a$>$ Documentation}\label{md__r_e_a_d_m_e_autotoc_md7} +\href{docs/html/class_xdf.html}{\texttt{ Documentation}} was generated via \href{http://www.stack.nl/~dimitri/doxygen/index.html}{\texttt{ Doxygen}}.\hypertarget{md__r_e_a_d_m_e_autotoc_md8}{}\doxysection{$<$a name=\char`\"{}support\char`\"{}$>$$<$/a$>$\+Support}\label{md__r_e_a_d_m_e_autotoc_md8} +\href{mailto:yl3842@columbia.edu}{\texttt{ Email author}} or report a new \href{https://github.com/Yida-Lin/libxdf/issues}{\texttt{ issue}}. \ No newline at end of file diff --git a/docs/latex/refman.tex b/docs/latex/refman.tex new file mode 100644 index 0000000..2083b30 --- /dev/null +++ b/docs/latex/refman.tex @@ -0,0 +1,197 @@ +\let\mypdfximage\pdfximage\def\pdfximage{\immediate\mypdfximage}\documentclass[twoside]{book} + +%% moved from doxygen.sty due to workaround for LaTex 2019 version and unmaintained tabu package +\usepackage{ifthen} +\ifx\requestedLaTeXdate\undefined +\usepackage{array} +\else +\usepackage{array}[=2016-10-06] +\fi +%% +% Packages required by doxygen +\usepackage{fixltx2e} +\usepackage{calc} +\usepackage{doxygen} +\usepackage{graphicx} +\usepackage[utf8]{inputenc} +\usepackage{makeidx} +\usepackage{multicol} +\usepackage{multirow} +\PassOptionsToPackage{warn}{textcomp} +\usepackage{textcomp} +\usepackage[nointegrals]{wasysym} +\usepackage[table]{xcolor} +\usepackage{ifpdf,ifxetex} + +% Font selection +\usepackage[T1]{fontenc} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\usepackage{amssymb} +\usepackage{sectsty} +\renewcommand{\familydefault}{\sfdefault} +\allsectionsfont{% + \fontseries{bc}\selectfont% + \color{darkgray}% +} +\renewcommand{\DoxyLabelFont}{% + \fontseries{bc}\selectfont% + \color{darkgray}% +} +\newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}} + +% Arguments of doxygenemoji: +% 1) '::' form of the emoji, already "LaTeX"-escaped +% 2) file with the name of the emoji without the .png extension +% in case image exist use this otherwise use the '::' form +\newcommand{\doxygenemoji}[2]{% + \IfFileExists{./#2.png}{\raisebox{-0.1em}{\includegraphics[height=0.9em]{./#2.png}}}{#1}% +} +% Page & text layout +\usepackage{geometry} +\geometry{% + a4paper,% + top=2.5cm,% + bottom=2.5cm,% + left=2.5cm,% + right=2.5cm% +} +\tolerance=750 +\hfuzz=15pt +\hbadness=750 +\setlength{\emergencystretch}{15pt} +\setlength{\parindent}{0cm} +\newcommand{\doxynormalparskip}{\setlength{\parskip}{3ex plus 2ex minus 2ex}} +\newcommand{\doxytocparskip}{\setlength{\parskip}{1ex plus 0ex minus 0ex}} +\doxynormalparskip +\makeatletter +\renewcommand{\paragraph}{% + \@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@parafont% + }% +} +\renewcommand{\subparagraph}{% + \@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@subparafont% + }% +} +\makeatother + +\makeatletter +\newcommand\hrulefilll{\leavevmode\leaders\hrule\hskip 0pt plus 1filll\kern\z@} +\makeatother + +% Headers & footers +\usepackage{fancyhdr} +\pagestyle{fancyplain} +\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}} +\fancyhead[CE]{\fancyplain{}{}} +\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}} +\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}} +\fancyhead[CO]{\fancyplain{}{}} +\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}} +\fancyfoot[LE]{\fancyplain{}{}} +\fancyfoot[CE]{\fancyplain{}{}} +\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }} +\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }} +\fancyfoot[CO]{\fancyplain{}{}} +\fancyfoot[RO]{\fancyplain{}{}} +\renewcommand{\footrulewidth}{0.4pt} +\renewcommand{\chaptermark}[1]{% + \markboth{#1}{}% +} +\renewcommand{\sectionmark}[1]{% + \markright{\thesection\ #1}% +} + +% Indices & bibliography +\usepackage{natbib} +\usepackage[titles]{tocloft} +\setcounter{tocdepth}{3} +\setcounter{secnumdepth}{5} +\makeindex + +\usepackage{newunicodechar} + \newunicodechar{⁻}{${}^{-}$}% Superscript minus + \newunicodechar{²}{${}^{2}$}% Superscript two + \newunicodechar{³}{${}^{3}$}% Superscript three + +% Hyperlinks (required, but should be loaded last) +\ifpdf + \usepackage[pdftex,pagebackref=true]{hyperref} +\else + \ifxetex + \usepackage[pagebackref=true]{hyperref} + \else + \usepackage[ps2pdf,pagebackref=true]{hyperref} + \fi +\fi + +\hypersetup{% + colorlinks=true,% + linkcolor=blue,% + citecolor=blue,% + unicode% +} + +% Custom commands +\newcommand{\clearemptydoublepage}{% + \newpage{\pagestyle{empty}\cleardoublepage}% +} + +\usepackage{caption} +\captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top} + +\usepackage{etoc} +\etocsettocstyle{\doxytocparskip}{\doxynormalparskip} +\renewcommand{\numberline}[1]{#1~} +%===== C O N T E N T S ===== + +\begin{document} + +% Titlepage & ToC +\hypersetup{pageanchor=false, + bookmarksnumbered=true, + pdfencoding=unicode + } +\pagenumbering{alph} +\begin{titlepage} +\vspace*{7cm} +\begin{center}% +{\Large Libxdf }\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.8.18}\\ +\end{center} +\end{titlepage} +\clearemptydoublepage +\pagenumbering{roman} +\tableofcontents +\clearemptydoublepage +\pagenumbering{arabic} +\hypersetup{pageanchor=true} + +%--- Begin generated contents --- +\chapter{Libxdf -\/ a C++ library for loading $<$a href=\char`\"{}https\+://github.\+com/sccn/xdf/wiki/\+Specifications\char`\"{} title=\char`\"{}\+Extensible Data Format\char`\"{}$>$X\+DF$<$/a$>$ files} +\label{md__r_e_a_d_m_e} +\Hypertarget{md__r_e_a_d_m_e} +\input{md__r_e_a_d_m_e} +\chapter{Class Index} +\input{annotated} +\chapter{File Index} +\input{files} +\chapter{Class Documentation} +\input{struct_xdf_1_1_stream} +\input{class_xdf} +\chapter{File Documentation} +\input{xdf_8h} +%--- End generated contents --- + +% Index +\backmatter +\newpage +\phantomsection +\clearemptydoublepage +\addcontentsline{toc}{chapter}{\indexname} +\printindex + +\end{document} diff --git a/docs/latex/struct_xdf_1_1_stream.tex b/docs/latex/struct_xdf_1_1_stream.tex new file mode 100644 index 0000000..3e6b024 --- /dev/null +++ b/docs/latex/struct_xdf_1_1_stream.tex @@ -0,0 +1,174 @@ +\hypertarget{struct_xdf_1_1_stream}{}\doxysection{Xdf\+::Stream Class Reference} +\label{struct_xdf_1_1_stream}\index{Xdf::Stream@{Xdf::Stream}} + + +{\ttfamily \#include $<$xdf.\+h$>$} + +\doxysubsection*{Public Attributes} +\begin{DoxyCompactItemize} +\item +std\+::vector$<$ std\+::vector$<$ float $>$ $>$ \mbox{\hyperlink{struct_xdf_1_1_stream_adfdeb5f6220da9fe671d3f37e27ed0bb}{time\+\_\+series}} +\item +std\+::vector$<$ double $>$ \mbox{\hyperlink{struct_xdf_1_1_stream_a20a2258af3bdffb13c6001a73da12428}{timestamps}} +\item +std\+::string \mbox{\hyperlink{struct_xdf_1_1_stream_a2fcba64fefd7c3e4d4768b9f9130399f}{stream\+\_\+header}} +\item +std\+::string \mbox{\hyperlink{struct_xdf_1_1_stream_a9f3e86932b7937d1ebeaa896bc7b6a12}{stream\+\_\+footer}} +\item +\begin{tabbing} +xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=\kill +struct \{\\ +\>int \mbox{\hyperlink{struct_xdf_1_1_stream_ab8fb7c3d645305e84f90d919f698082c}{channel\_count}}\\ +\>double \mbox{\hyperlink{struct_xdf_1_1_stream_a17696fc2ee37c1d79601fac1736deb35}{nominal\_srate}}\\ +\>std::string \mbox{\hyperlink{struct_xdf_1_1_stream_a112e1dcc0e4b7f9583755366da8c3c64}{name}}\\ +\>std::string \mbox{\hyperlink{struct_xdf_1_1_stream_a7e5aa085e48de871ea6661651b28e097}{type}}\\ +\>std::string \mbox{\hyperlink{struct_xdf_1_1_stream_ad7b61b077e247ba57a18c182e285d0ad}{channel\_format}}\\ +\>std::vector$<$ std::map$<$ std::string, std::string $>$ $>$ \mbox{\hyperlink{struct_xdf_1_1_stream_a71d987a538d0819cdbd58120d1a79ef5}{channels}}\\ +\>std::vector$<$ std::pair$<$ double, double $>$ $>$ \mbox{\hyperlink{struct_xdf_1_1_stream_a6f6328f0746591a3a471048b6b9bd258}{clock\_offsets}}\\ +\>double \mbox{\hyperlink{struct_xdf_1_1_stream_a22a44cb3cd533ea668f9bb20dbc299de}{first\_timestamp}}\\ +\>double \mbox{\hyperlink{struct_xdf_1_1_stream_a9e05df342a36187ae492c75f10fc7713}{last\_timestamp}}\\ +\>int \mbox{\hyperlink{struct_xdf_1_1_stream_a329234a46df00cd51a67a7f4f637c08a}{sample\_count}}\\ +\>double \mbox{\hyperlink{struct_xdf_1_1_stream_abd08634894478bb304c209e5bbdcabb4}{measured\_sampling\_rate}}\\ +\>double \mbox{\hyperlink{struct_xdf_1_1_stream_a97a11401e85fd9f64a5601b15bbc7820}{effective\_sampling\_rate}} = 0\\ +\} \mbox{\hyperlink{struct_xdf_1_1_stream_adb53bf4089d3169c9ea89a9767b4ad11}{info}}\\ + +\end{tabbing}\item +double \mbox{\hyperlink{struct_xdf_1_1_stream_a1cac0dbcbe6756cd02b662feae416ba1}{sampling\+\_\+interval}} +\item +std\+::vector$<$ double $>$ \mbox{\hyperlink{struct_xdf_1_1_stream_a6bc91dcf23e551a9adbc415b562f3a79}{clock\+\_\+times}} +\item +std\+::vector$<$ double $>$ \mbox{\hyperlink{struct_xdf_1_1_stream_a988989603854812cb693e56ff352a753}{clock\+\_\+values}} +\end{DoxyCompactItemize} + + +\doxysubsection{Detailed Description} +X\+DF files uses stream as the unit to store data. An X\+DF file usually contains multiple streams, each of which may contain one or more channels. The \mbox{\hyperlink{struct_xdf_1_1_stream}{Stream}} struct stores meta-\/data, time series, timetamps and other information of a stream. + +\doxysubsection{Member Data Documentation} +\mbox{\Hypertarget{struct_xdf_1_1_stream_ab8fb7c3d645305e84f90d919f698082c}\label{struct_xdf_1_1_stream_ab8fb7c3d645305e84f90d919f698082c}} +\index{Xdf::Stream@{Xdf::Stream}!channel\_count@{channel\_count}} +\index{channel\_count@{channel\_count}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{channel\_count}{channel\_count}} +{\footnotesize\ttfamily int Xdf\+::\+Stream\+::channel\+\_\+count} + +Number of channels in the current stream \mbox{\Hypertarget{struct_xdf_1_1_stream_ad7b61b077e247ba57a18c182e285d0ad}\label{struct_xdf_1_1_stream_ad7b61b077e247ba57a18c182e285d0ad}} +\index{Xdf::Stream@{Xdf::Stream}!channel\_format@{channel\_format}} +\index{channel\_format@{channel\_format}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{channel\_format}{channel\_format}} +{\footnotesize\ttfamily std\+::string Xdf\+::\+Stream\+::channel\+\_\+format} + +The channel format of the current stream. \mbox{\Hypertarget{struct_xdf_1_1_stream_a71d987a538d0819cdbd58120d1a79ef5}\label{struct_xdf_1_1_stream_a71d987a538d0819cdbd58120d1a79ef5}} +\index{Xdf::Stream@{Xdf::Stream}!channels@{channels}} +\index{channels@{channels}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{channels}{channels}} +{\footnotesize\ttfamily std\+::vector$<$std\+::map$<$std\+::string, std\+::string$>$ $>$ Xdf\+::\+Stream\+::channels} + +Stores the metadata of the channels of the current stream. \mbox{\Hypertarget{struct_xdf_1_1_stream_a6f6328f0746591a3a471048b6b9bd258}\label{struct_xdf_1_1_stream_a6f6328f0746591a3a471048b6b9bd258}} +\index{Xdf::Stream@{Xdf::Stream}!clock\_offsets@{clock\_offsets}} +\index{clock\_offsets@{clock\_offsets}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{clock\_offsets}{clock\_offsets}} +{\footnotesize\ttfamily std\+::vector$<$std\+::pair$<$double, double$>$ $>$ Xdf\+::\+Stream\+::clock\+\_\+offsets} + +Stores the clock offsets from the Clock\+Offset chunk. \mbox{\Hypertarget{struct_xdf_1_1_stream_a6bc91dcf23e551a9adbc415b562f3a79}\label{struct_xdf_1_1_stream_a6bc91dcf23e551a9adbc415b562f3a79}} +\index{Xdf::Stream@{Xdf::Stream}!clock\_times@{clock\_times}} +\index{clock\_times@{clock\_times}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{clock\_times}{clock\_times}} +{\footnotesize\ttfamily std\+::vector$<$double$>$ Xdf\+::\+Stream\+::clock\+\_\+times} + +Stores the clock times from clock offset chunks. \mbox{\Hypertarget{struct_xdf_1_1_stream_a988989603854812cb693e56ff352a753}\label{struct_xdf_1_1_stream_a988989603854812cb693e56ff352a753}} +\index{Xdf::Stream@{Xdf::Stream}!clock\_values@{clock\_values}} +\index{clock\_values@{clock\_values}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{clock\_values}{clock\_values}} +{\footnotesize\ttfamily std\+::vector$<$double$>$ Xdf\+::\+Stream\+::clock\+\_\+values} + +Stores the clock values from clock offset chunks. \mbox{\Hypertarget{struct_xdf_1_1_stream_a97a11401e85fd9f64a5601b15bbc7820}\label{struct_xdf_1_1_stream_a97a11401e85fd9f64a5601b15bbc7820}} +\index{Xdf::Stream@{Xdf::Stream}!effective\_sampling\_rate@{effective\_sampling\_rate}} +\index{effective\_sampling\_rate@{effective\_sampling\_rate}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{effective\_sampling\_rate}{effective\_sampling\_rate}} +{\footnotesize\ttfamily double Xdf\+::\+Stream\+::effective\+\_\+sampling\+\_\+rate = 0} + +Effective sampling rate. \mbox{\Hypertarget{struct_xdf_1_1_stream_a22a44cb3cd533ea668f9bb20dbc299de}\label{struct_xdf_1_1_stream_a22a44cb3cd533ea668f9bb20dbc299de}} +\index{Xdf::Stream@{Xdf::Stream}!first\_timestamp@{first\_timestamp}} +\index{first\_timestamp@{first\_timestamp}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{first\_timestamp}{first\_timestamp}} +{\footnotesize\ttfamily double Xdf\+::\+Stream\+::first\+\_\+timestamp} + +First timestamp of the stream. \mbox{\Hypertarget{struct_xdf_1_1_stream_adb53bf4089d3169c9ea89a9767b4ad11}\label{struct_xdf_1_1_stream_adb53bf4089d3169c9ea89a9767b4ad11}} +\index{Xdf::Stream@{Xdf::Stream}!info@{info}} +\index{info@{info}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{info}{info}} +{\footnotesize\ttfamily struct \{ ... \} Xdf\+::\+Stream\+::info} + +Meta-\/data from the stream header of the current stream. \mbox{\Hypertarget{struct_xdf_1_1_stream_a9e05df342a36187ae492c75f10fc7713}\label{struct_xdf_1_1_stream_a9e05df342a36187ae492c75f10fc7713}} +\index{Xdf::Stream@{Xdf::Stream}!last\_timestamp@{last\_timestamp}} +\index{last\_timestamp@{last\_timestamp}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{last\_timestamp}{last\_timestamp}} +{\footnotesize\ttfamily double Xdf\+::\+Stream\+::last\+\_\+timestamp \{0\}} + +Last timestamp of the stream. + +For temporary use while loading the vector \mbox{\Hypertarget{struct_xdf_1_1_stream_abd08634894478bb304c209e5bbdcabb4}\label{struct_xdf_1_1_stream_abd08634894478bb304c209e5bbdcabb4}} +\index{Xdf::Stream@{Xdf::Stream}!measured\_sampling\_rate@{measured\_sampling\_rate}} +\index{measured\_sampling\_rate@{measured\_sampling\_rate}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{measured\_sampling\_rate}{measured\_sampling\_rate}} +{\footnotesize\ttfamily double Xdf\+::\+Stream\+::measured\+\_\+sampling\+\_\+rate} + +Measured sampling rate of the stream. \mbox{\Hypertarget{struct_xdf_1_1_stream_a112e1dcc0e4b7f9583755366da8c3c64}\label{struct_xdf_1_1_stream_a112e1dcc0e4b7f9583755366da8c3c64}} +\index{Xdf::Stream@{Xdf::Stream}!name@{name}} +\index{name@{name}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{name}{name}} +{\footnotesize\ttfamily std\+::string Xdf\+::\+Stream\+::name} + +The name of the current stream. \mbox{\Hypertarget{struct_xdf_1_1_stream_a17696fc2ee37c1d79601fac1736deb35}\label{struct_xdf_1_1_stream_a17696fc2ee37c1d79601fac1736deb35}} +\index{Xdf::Stream@{Xdf::Stream}!nominal\_srate@{nominal\_srate}} +\index{nominal\_srate@{nominal\_srate}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{nominal\_srate}{nominal\_srate}} +{\footnotesize\ttfamily double Xdf\+::\+Stream\+::nominal\+\_\+srate} + +The nominal sampling rate of the current stream. \mbox{\Hypertarget{struct_xdf_1_1_stream_a329234a46df00cd51a67a7f4f637c08a}\label{struct_xdf_1_1_stream_a329234a46df00cd51a67a7f4f637c08a}} +\index{Xdf::Stream@{Xdf::Stream}!sample\_count@{sample\_count}} +\index{sample\_count@{sample\_count}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{sample\_count}{sample\_count}} +{\footnotesize\ttfamily int Xdf\+::\+Stream\+::sample\+\_\+count} + +Sample count of the stream. \mbox{\Hypertarget{struct_xdf_1_1_stream_a1cac0dbcbe6756cd02b662feae416ba1}\label{struct_xdf_1_1_stream_a1cac0dbcbe6756cd02b662feae416ba1}} +\index{Xdf::Stream@{Xdf::Stream}!sampling\_interval@{sampling\_interval}} +\index{sampling\_interval@{sampling\_interval}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{sampling\_interval}{sampling\_interval}} +{\footnotesize\ttfamily double Xdf\+::\+Stream\+::sampling\+\_\+interval} + +sampling\+\_\+interval = 1/sampling\+\_\+rate if sampling\+\_\+rate $>$ 0, otherwise 0 \mbox{\Hypertarget{struct_xdf_1_1_stream_a9f3e86932b7937d1ebeaa896bc7b6a12}\label{struct_xdf_1_1_stream_a9f3e86932b7937d1ebeaa896bc7b6a12}} +\index{Xdf::Stream@{Xdf::Stream}!stream\_footer@{stream\_footer}} +\index{stream\_footer@{stream\_footer}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{stream\_footer}{stream\_footer}} +{\footnotesize\ttfamily std\+::string Xdf\+::\+Stream\+::stream\+\_\+footer} + +Raw X\+ML of stream footer chunk. \mbox{\Hypertarget{struct_xdf_1_1_stream_a2fcba64fefd7c3e4d4768b9f9130399f}\label{struct_xdf_1_1_stream_a2fcba64fefd7c3e4d4768b9f9130399f}} +\index{Xdf::Stream@{Xdf::Stream}!stream\_header@{stream\_header}} +\index{stream\_header@{stream\_header}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{stream\_header}{stream\_header}} +{\footnotesize\ttfamily std\+::string Xdf\+::\+Stream\+::stream\+\_\+header} + +Raw X\+ML of stream header chunk. \mbox{\Hypertarget{struct_xdf_1_1_stream_adfdeb5f6220da9fe671d3f37e27ed0bb}\label{struct_xdf_1_1_stream_adfdeb5f6220da9fe671d3f37e27ed0bb}} +\index{Xdf::Stream@{Xdf::Stream}!time\_series@{time\_series}} +\index{time\_series@{time\_series}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{time\_series}{time\_series}} +{\footnotesize\ttfamily std\+::vector$<$std\+::vector$<$float$>$ $>$ Xdf\+::\+Stream\+::time\+\_\+series} + +Stores the time series of a stream. Each row represents a channel. \mbox{\Hypertarget{struct_xdf_1_1_stream_a20a2258af3bdffb13c6001a73da12428}\label{struct_xdf_1_1_stream_a20a2258af3bdffb13c6001a73da12428}} +\index{Xdf::Stream@{Xdf::Stream}!timestamps@{timestamps}} +\index{timestamps@{timestamps}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{timestamps}{timestamps}} +{\footnotesize\ttfamily std\+::vector$<$double$>$ Xdf\+::\+Stream\+::timestamps} + +Stores the timestamps. \mbox{\Hypertarget{struct_xdf_1_1_stream_a7e5aa085e48de871ea6661651b28e097}\label{struct_xdf_1_1_stream_a7e5aa085e48de871ea6661651b28e097}} +\index{Xdf::Stream@{Xdf::Stream}!type@{type}} +\index{type@{type}!Xdf::Stream@{Xdf::Stream}} +\doxysubsubsection{\texorpdfstring{type}{type}} +{\footnotesize\ttfamily std\+::string Xdf\+::\+Stream\+::type} + +The type of the current stream. + +The documentation for this class was generated from the following file\+:\begin{DoxyCompactItemize} +\item +\mbox{\hyperlink{xdf_8h}{xdf.\+h}}\end{DoxyCompactItemize} diff --git a/docs/latex/tabu_doxygen.sty b/docs/latex/tabu_doxygen.sty new file mode 100644 index 0000000..3f17d1d --- /dev/null +++ b/docs/latex/tabu_doxygen.sty @@ -0,0 +1,2557 @@ +%% +%% This is file `tabu.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% tabu.dtx (with options: `package') +%% +%% This is a generated file. +%% Copyright (FC) 2010-2011 - lppl +%% +%% tabu : 2011/02/26 v2.8 - tabu : Flexible LaTeX tabulars +%% +%% ********************************************************************************************** +%% \begin{tabu} { preamble } => default target: \linewidth or \linegoal +%% \begin{tabu} to { preamble } => target specified +%% \begin{tabu} spread { preamble } => target relative to the ``natural width'' +%% +%% tabu works in text and in math modes. +%% +%% X columns: automatic width adjustment + horizontal and vertical alignment +%% \begin{tabu} { X[4c] X[1c] X[-2ml] } +%% +%% Horizontal lines and / or leaders: +%% \hline\hline => double horizontal line +%% \firsthline\hline => for nested tabulars +%% \lasthline\hline => for nested tabulars +%% \tabucline[line spec]{column-column} => ``funny'' lines (dash/leader) +%% Automatic lines / leaders : +%% \everyrow{\hline\hline} +%% +%% Vertical lines and / or leaders: +%% \begin{tabu} { |[3pt red] X[4c] X[1c] X[-2ml] |[3pt blue] } +%% \begin{tabu} { |[3pt red] X[4c] X[1c] X[-2ml] |[3pt on 2pt off 4pt blue] } +%% +%% Fixed vertical spacing adjustment: +%% \extrarowheight= \extrarowdepth= +%% or: \extrarowsep= => may be prefixed by \global +%% +%% Dynamic vertical spacing adjustment: +%% \abovetabulinesep= \belowtabulinesep= +%% or: \tabulinesep= => may be prefixed by \global +%% +%% delarray.sty shortcuts: in math and text modes +%% \begin{tabu} .... \({ preamble }\) +%% +%% Algorithms reports: +%% \tracingtabu=1 \tracingtabu=2 +%% +%% ********************************************************************************************** +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% +%% This work consists of the main source file tabu.dtx +%% and the derived files +%% tabu.sty, tabu.pdf, tabu.ins +%% +%% tabu : Flexible LaTeX tabulars +%% lppl copyright 2010-2011 by FC +%% + +\NeedsTeXFormat{LaTeX2e}[2005/12/01] +\ProvidesPackage{tabu_doxygen}[2011/02/26 v2.8 - flexible LaTeX tabulars (FC), frozen version for doxygen] +\RequirePackage{array}[2008/09/09] +\RequirePackage{varwidth}[2009/03/30] +\AtEndOfPackage{\tabu@AtEnd \let\tabu@AtEnd \@undefined} +\let\tabu@AtEnd\@empty +\def\TMP@EnsureCode#1={% + \edef\tabu@AtEnd{\tabu@AtEnd + \catcode#1 \the\catcode#1}% + \catcode#1=% +}% \TMP@EnsureCode +\TMP@EnsureCode 33 = 12 % ! +\TMP@EnsureCode 58 = 12 % : (for siunitx) +\TMP@EnsureCode124 = 12 % | +\TMP@EnsureCode 36 = 3 % $ = math shift +\TMP@EnsureCode 38 = 4 % & = tab alignment character +\TMP@EnsureCode 32 = 10 % space +\TMP@EnsureCode 94 = 7 % ^ +\TMP@EnsureCode 95 = 8 % _ +%% Constants -------------------------------------------------------- +\newcount \c@taburow \def\thetaburow {\number\c@taburow} +\newcount \tabu@nbcols +\newcount \tabu@cnt +\newcount \tabu@Xcol +\let\tabu@start \@tempcnta +\let\tabu@stop \@tempcntb +\newcount \tabu@alloc \tabu@alloc=\m@ne +\newcount \tabu@nested +\def\tabu@alloc@{\global\advance\tabu@alloc \@ne \tabu@nested\tabu@alloc} +\newdimen \tabu@target +\newdimen \tabu@spreadtarget +\newdimen \tabu@naturalX +\newdimen \tabucolX +\let\tabu@DELTA \@tempdimc +\let\tabu@thick \@tempdima +\let\tabu@on \@tempdimb +\let\tabu@off \@tempdimc +\newdimen \tabu@Xsum +\newdimen \extrarowdepth +\newdimen \abovetabulinesep +\newdimen \belowtabulinesep +\newdimen \tabustrutrule \tabustrutrule \z@ +\newtoks \tabu@thebody +\newtoks \tabu@footnotes +\newsavebox \tabu@box +\newsavebox \tabu@arstrutbox +\newsavebox \tabu@hleads +\newsavebox \tabu@vleads +\newif \iftabu@colortbl +\newif \iftabu@siunitx +\newif \iftabu@measuring +\newif \iftabu@spread +\newif \iftabu@negcoef +\newif \iftabu@everyrow +\def\tabu@everyrowtrue {\global\let\iftabu@everyrow \iftrue} +\def\tabu@everyrowfalse{\global\let\iftabu@everyrow \iffalse} +\newif \iftabu@long +\newif \iftabuscantokens +\def\tabu@rescan {\tabu@verbatim \scantokens } +%% Utilities (for internal usage) ----------------------------------- +\def\tabu@gobblespace #1 {#1} +\def\tabu@gobbletoken #1#2{#1} +\def\tabu@gobbleX{\futurelet\@let@token \tabu@gobblex} +\def\tabu@gobblex{\if ^^J\noexpand\@let@token \expandafter\@gobble + \else\ifx \@sptoken\@let@token + \expandafter\tabu@gobblespace\expandafter\tabu@gobbleX + \fi\fi +}% \tabu@gobblex +\def\tabu@X{^^J} +{\obeyspaces +\global\let\tabu@spxiii= % saves an active space (for \ifx) +\gdef\tabu@@spxiii{ }} +\def\tabu@ifenvir {% only for \multicolumn + \expandafter\tabu@if@nvir\csname\@currenvir\endcsname +}% \tabu@ifenvir +\def\tabu@if@nvir #1{\csname @\ifx\tabu#1first\else + \ifx\longtabu#1first\else + second\fi\fi oftwo\endcsname +}% \tabu@ifenvir +\def\tabu@modulo #1#2{\numexpr\ifnum\numexpr#1=\z@ 0\else #1-(#1-(#2-1)/2)/(#2)*(#2)\fi} +{\catcode`\&=3 +\gdef\tabu@strtrim #1{% #1 = control sequence to trim + \ifodd 1\ifx #1\@empty \else \ifx #1\space \else 0\fi \fi + \let\tabu@c@l@r \@empty \let#1\@empty + \else \expandafter \tabu@trimspaces #1\@nnil + \fi +}% \tabu@strtrim +\gdef\tabu@trimspaces #1\@nnil{\let\tabu@c@l@r=#2\tabu@firstspace .#1& }% +\gdef\tabu@firstspace #1#2#3 &{\tabu@lastspace #2#3&} +\gdef\tabu@lastspace #1{\def #3{#1}% + \ifx #3\tabu@c@l@r \def\tabu@c@l@r{\protect\color{#1}}\expandafter\remove@to@nnil \fi + \tabu@trimspaces #1\@nnil} +}% \catcode +\def\tabu@sanitizearg #1#2{{% + \csname \ifcsname if@safe@actives\endcsname % + @safe@activestrue\else + relax\fi \endcsname + \edef#2{#1}\tabu@strtrim#2\@onelevel@sanitize#2% + \expandafter}\expandafter\def\expandafter#2\expandafter{#2}% +}% \tabu@sanitizearg +\def\tabu@textbar #1{\begingroup \endlinechar\m@ne \scantokens{\def\:{|}}% + \expandafter\endgroup \expandafter#1\:% !!! semi simple group !!! +}% \tabu@textbar +\def\tabu@everyrow@bgroup{\iftabu@everyrow \begingroup \else \noalign{\ifnum0=`}\fi \fi} +\def\tabu@everyrow@egroup{% + \iftabu@everyrow \expandafter \endgroup \the\toks@ + \else \ifnum0=`{\fi}% + \fi +}% \tabu@everyrow@egroup +\def\tabu@arstrut {\global\setbox\@arstrutbox \hbox{\vrule + height \arraystretch \dimexpr\ht\strutbox+\extrarowheight + depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth + width \z@}% +}% \tabu@arstrut +\def\tabu@rearstrut {% + \@tempdima \arraystretch\dimexpr\ht\strutbox+\extrarowheight \relax + \@tempdimb \arraystretch\dimexpr\dp\strutbox+\extrarowdepth \relax + \ifodd 1\ifdim \ht\@arstrutbox=\@tempdima + \ifdim \dp\@arstrutbox=\@tempdimb 0 \fi\fi + \tabu@mkarstrut + \fi +}% \tabu@rearstrut +\def\tabu@@DBG #1{\ifdim\tabustrutrule>\z@ \color{#1}\fi} +\def\tabu@DBG@arstrut {\global\setbox\@arstrutbox + \hbox to\z@{\hbox to\z@{\hss + {\tabu@DBG{cyan}\vrule + height \arraystretch \dimexpr\ht\strutbox+\extrarowheight + depth \z@ + width \tabustrutrule}\kern-\tabustrutrule + {\tabu@DBG{pink}\vrule + height \z@ + depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth + width \tabustrutrule}}}% +}% \tabu@DBG@arstrut +\def\tabu@save@decl{\toks\count@ \expandafter{\the\toks\expandafter\count@ + \@nextchar}}% +\def\tabu@savedecl{\ifcat$\d@llarend\else + \let\save@decl \tabu@save@decl \fi % no inversion of tokens in text mode +}% \tabu@savedecl +\def\tabu@finalstrut #1{\unskip\ifhmode\nobreak\fi\vrule height\z@ depth\z@ width\z@} +\newcommand*\tabuDisableCommands {\g@addto@macro\tabu@trialh@@k } +\let\tabu@trialh@@k \@empty +\def\tabu@nowrite #1#{{\afterassignment}\toks@} +\let\tabu@write\write +\let\tabu@immediate\immediate +\def\tabu@WRITE{\begingroup + \def\immediate\write{\aftergroup\endgroup + \tabu@immediate\tabu@write}% +}% \tabu@WRITE +\expandafter\def\expandafter\tabu@GenericError\expandafter{% + \expandafter\tabu@WRITE\GenericError} +\def\tabu@warn{\tabu@WRITE\PackageWarning{tabu}} +\def\tabu@noxfootnote [#1]{\@gobble} +\def\tabu@nocolor #1#{\@gobble} +\newcommand*\tabu@norowcolor[2][]{} +\def\tabu@maybesiunitx #1{\def\tabu@temp{#1}% + \futurelet\@let@token \tabu@m@ybesiunitx} +\def\tabu@m@ybesiunitx #1{\def\tabu@m@ybesiunitx {% + \ifx #1\@let@token \let\tabu@cellleft \@empty \let\tabu@cellright \@empty \fi + \tabu@temp}% \tabu@m@ybesiunitx +}\expandafter\tabu@m@ybesiunitx \csname siunitx_table_collect_begin:Nn\endcsname +\def\tabu@celllalign@def #1{\def\tabu@celllalign{\tabu@maybesiunitx{#1}}}% +%% Fixed vertical spacing adjustment: \extrarowsep ------------------ +\newcommand*\extrarowsep{\edef\tabu@C@extra{\the\numexpr\tabu@C@extra+1}% + \iftabu@everyrow \aftergroup\tabu@Gextra + \else \aftergroup\tabu@n@Gextra + \fi + \@ifnextchar={\tabu@gobbletoken\tabu@extra} \tabu@extra +}% \extrarowsep +\def\tabu@extra {\@ifnextchar_% + {\tabu@gobbletoken{\tabu@setextra\extrarowheight \extrarowdepth}} + {\ifx ^\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setextra\extrarowdepth \extrarowheight}}% + \else \let\tabu@temp \@empty + \afterassignment \tabu@setextrasep \extrarowdepth + \fi \tabu@temp}% +}% \tabu@extra +\def\tabu@setextra #1#2{\def\tabu@temp{\tabu@extr@#1#2}\afterassignment\tabu@temp#2} +\def\tabu@extr@ #1#2{\@ifnextchar^% + {\tabu@gobbletoken{\tabu@setextra\extrarowdepth \extrarowheight}} + {\ifx _\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setextra\extrarowheight \extrarowdepth}}% + \else \let\tabu@temp \@empty + \tabu@Gsave \tabu@G@extra \tabu@C@extra \extrarowheight \extrarowdepth + \fi \tabu@temp}% +}% \tabu@extr@ +\def\tabu@setextrasep {\extrarowheight=\extrarowdepth + \tabu@Gsave \tabu@G@extra \tabu@C@extra \extrarowheight \extrarowdepth +}% \tabu@setextrasep +\def\tabu@Gextra{\ifx \tabu@G@extra\@empty \else {\tabu@Rextra}\fi} +\def\tabu@n@Gextra{\ifx \tabu@G@extra\@empty \else \noalign{\tabu@Rextra}\fi} +\def\tabu@Rextra{\tabu@Grestore \tabu@G@extra \tabu@C@extra} +\let\tabu@C@extra \z@ +\let\tabu@G@extra \@empty +%% Dynamic vertical spacing adjustment: \tabulinesep ---------------- +\newcommand*\tabulinesep{\edef\tabu@C@linesep{\the\numexpr\tabu@C@linesep+1}% + \iftabu@everyrow \aftergroup\tabu@Glinesep + \else \aftergroup\tabu@n@Glinesep + \fi + \@ifnextchar={\tabu@gobbletoken\tabu@linesep} \tabu@linesep +}% \tabulinesep +\def\tabu@linesep {\@ifnextchar_% + {\tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}} + {\ifx ^\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}}% + \else \let\tabu@temp \@empty + \afterassignment \tabu@setlinesep \abovetabulinesep + \fi \tabu@temp}% +}% \tabu@linesep +\def\tabu@setsep #1#2{\def\tabu@temp{\tabu@sets@p#1#2}\afterassignment\tabu@temp#2} +\def\tabu@sets@p #1#2{\@ifnextchar^% + {\tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}} + {\ifx _\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}}% + \else \let\tabu@temp \@empty + \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep + \fi \tabu@temp}% +}% \tabu@sets@p +\def\tabu@setlinesep {\belowtabulinesep=\abovetabulinesep + \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep +}% \tabu@setlinesep +\def\tabu@Glinesep{\ifx \tabu@G@linesep\@empty \else {\tabu@Rlinesep}\fi} +\def\tabu@n@Glinesep{\ifx \tabu@G@linesep\@empty \else \noalign{\tabu@Rlinesep}\fi} +\def\tabu@Rlinesep{\tabu@Grestore \tabu@G@linesep \tabu@C@linesep} +\let\tabu@C@linesep \z@ +\let\tabu@G@linesep \@empty +%% \global\extrarowsep and \global\tabulinesep ------------------- +\def\tabu@Gsave #1#2#3#4{\xdef#1{#1% + \toks#2{\toks\the\currentgrouplevel{\global#3\the#3\global#4\the#4}}}% +}% \tabu@Gsave +\def\tabu@Grestore#1#2{% + \toks#2{}#1\toks\currentgrouplevel\expandafter{\expandafter}\the\toks#2\relax + \ifcat$\the\toks\currentgrouplevel$\else + \global\let#1\@empty \global\let#2\z@ + \the\toks\currentgrouplevel + \fi +}% \tabu@Grestore +%% Setting code for every row --------------------------------------- +\newcommand*\everyrow{\tabu@everyrow@bgroup + \tabu@start \z@ \tabu@stop \z@ \tabu@evrstartstop +}% \everyrow +\def\tabu@evrstartstop {\@ifnextchar^% + {\afterassignment \tabu@evrstartstop \tabu@stop=}% + {\ifx ^\@let@token + \afterassignment\tabu@evrstartstop \tabu@start=% + \else \afterassignment\tabu@everyr@w \toks@ + \fi}% +}% \tabu@evrstartstop +\def\tabu@everyr@w {% + \xdef\tabu@everyrow{% + \noexpand\tabu@everyrowfalse + \let\noalign \relax + \noexpand\tabu@rowfontreset + \iftabu@colortbl \noexpand\tabu@rc@ \fi % \taburowcolors + \let\noexpand\tabu@docline \noexpand\tabu@docline@evr + \the\toks@ + \noexpand\tabu@evrh@@k + \noexpand\tabu@rearstrut + \global\advance\c@taburow \@ne}% + \iftabu@everyrow \toks@\expandafter + {\expandafter\def\expandafter\tabu@evr@L\expandafter{\the\toks@}\ignorespaces}% + \else \xdef\tabu@evr@G{\the\toks@}% + \fi + \tabu@everyrow@egroup +}% \tabu@everyr@w +\def\tabu@evr {\def\tabu@evrh@@k} % for internal use only +\tabu@evr{} +%% line style and leaders ------------------------------------------- +\newcommand*\newtabulinestyle [1]{% + {\@for \@tempa :=#1\do{\expandafter\tabu@newlinestyle \@tempa==\@nil}}% +}% \newtabulinestyle +\def\tabu@newlinestyle #1=#2=#3\@nil{\tabu@getline {#2}% + \tabu@sanitizearg {#1}\@tempa + \ifodd 1\ifx \@tempa\@empty \ifdefined\tabu@linestyle@ 0 \fi\fi + \global\expandafter\let + \csname tabu@linestyle@\@tempa \endcsname =\tabu@thestyle \fi +}% \tabu@newlinestyle +\newcommand*\tabulinestyle [1]{\tabu@everyrow@bgroup \tabu@getline{#1}% + \iftabu@everyrow + \toks@\expandafter{\expandafter \def \expandafter + \tabu@ls@L\expandafter{\tabu@thestyle}\ignorespaces}% + \gdef\tabu@ls@{\tabu@ls@L}% + \else + \global\let\tabu@ls@G \tabu@thestyle + \gdef\tabu@ls@{\tabu@ls@G}% + \fi + \tabu@everyrow@egroup +}% \tabulinestyle +\newcommand*\taburulecolor{\tabu@everyrow@bgroup \tabu@textbar \tabu@rulecolor} +\def\tabu@rulecolor #1{\toks@{}% + \def\tabu@temp #1##1#1{\tabu@ruledrsc{##1}}\@ifnextchar #1% + \tabu@temp + \tabu@rulearc +}% \tabu@rulecolor +\def\tabu@ruledrsc #1{\edef\tabu@temp{#1}\tabu@strtrim\tabu@temp + \ifx \tabu@temp\@empty \def\tabu@temp{\tabu@rule@drsc@ {}{}}% + \else \edef\tabu@temp{\noexpand\tabu@rule@drsc@ {}{\tabu@temp}}% + \fi + \tabu@temp +}% \tabu@ruledrsc@ +\def\tabu@ruledrsc@ #1#{\tabu@rule@drsc@ {#1}} +\def\tabu@rule@drsc@ #1#2{% + \iftabu@everyrow + \ifx \\#1#2\\\toks@{\let\CT@drsc@ \relax}% + \else \toks@{\def\CT@drsc@{\color #1{#2}}}% + \fi + \else + \ifx \\#1#2\\\global\let\CT@drsc@ \relax + \else \gdef\CT@drsc@{\color #1{#2}}% + \fi + \fi + \tabu@rulearc +}% \tabu@rule@drsc@ +\def\tabu@rulearc #1#{\tabu@rule@arc@ {#1}} +\def\tabu@rule@arc@ #1#2{% + \iftabu@everyrow + \ifx \\#1#2\\\toks@\expandafter{\the\toks@ \def\CT@arc@{}}% + \else \toks@\expandafter{\the\toks@ \def\CT@arc@{\color #1{#2}}}% + \fi + \toks@\expandafter{\the\toks@ + \let\tabu@arc@L \CT@arc@ + \let\tabu@drsc@L \CT@drsc@ + \ignorespaces}% + \else + \ifx \\#1#2\\\gdef\CT@arc@{}% + \else \gdef\CT@arc@{\color #1{#2}}% + \fi + \global\let\tabu@arc@G \CT@arc@ + \global\let\tabu@drsc@G \CT@drsc@ + \fi + \tabu@everyrow@egroup +}% \tabu@rule@arc@ +\def\taburowcolors {\tabu@everyrow@bgroup \@testopt \tabu@rowcolors 1} +\def\tabu@rowcolors [#1]#2#{\tabu@rowc@lors{#1}{#2}} +\def\tabu@rowc@lors #1#2#3{% + \toks@{}\@defaultunits \count@ =\number0#2\relax \@nnil + \@defaultunits \tabu@start =\number0#1\relax \@nnil + \ifnum \count@<\tw@ \count@=\tw@ \fi + \advance\tabu@start \m@ne + \ifnum \tabu@start<\z@ \tabu@start \z@ \fi + \tabu@rowcolorseries #3\in@..\in@ \@nnil +}% \tabu@rowcolors +\def\tabu@rowcolorseries #1..#2\in@ #3\@nnil {% + \ifx \in@#1\relax + \iftabu@everyrow \toks@{\def\tabu@rc@{}\let\tabu@rc@L \tabu@rc@}% + \else \gdef\tabu@rc@{}\global\let\tabu@rc@G \tabu@rc@ + \fi + \else + \ifx \\#2\\\tabu@rowcolorserieserror \fi + \tabu@sanitizearg{#1}\tabu@temp + \tabu@sanitizearg{#2}\@tempa + \advance\count@ \m@ne + \iftabu@everyrow + \def\tabu@rc@ ##1##2##3##4{\def\tabu@rc@{% + \ifnum ##2=\c@taburow + \definecolorseries{tabu@rcseries@\the\tabu@nested}{rgb}{last}{##3}{##4}\fi + \ifnum \c@taburow<##2 \else + \ifnum \tabu@modulo {\c@taburow-##2}{##1+1}=\z@ + \resetcolorseries[{##1}]{tabu@rcseries@\the\tabu@nested}\fi + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \rowcolor{tabu@rc@\the\tabu@nested}\fi}% + }\edef\x{\noexpand\tabu@rc@ {\the\count@} + {\the\tabu@start} + {\tabu@temp} + {\@tempa}% + }\x + \toks@\expandafter{\expandafter\def\expandafter\tabu@rc@\expandafter{\tabu@rc@}}% + \toks@\expandafter{\the\toks@ \let\tabu@rc@L \tabu@rc@ \ignorespaces}% + \else % inside \noalign + \definecolorseries{tabu@rcseries@\the\tabu@nested}{rgb}{last}{\tabu@temp}{\@tempa}% + \expandafter\resetcolorseries\expandafter[\the\count@]{tabu@rcseries@\the\tabu@nested}% + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \let\noalign \relax \rowcolor{tabu@rc@\the\tabu@nested}% + \def\tabu@rc@ ##1##2{\gdef\tabu@rc@{% + \ifnum \tabu@modulo {\c@taburow-##2}{##1+1}=\@ne + \resetcolorseries[{##1}]{tabu@rcseries@\the\tabu@nested}\fi + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \rowcolor{tabu@rc@\the\tabu@nested}}% + }\edef\x{\noexpand\tabu@rc@{\the\count@}{\the\c@taburow}}\x + \global\let\tabu@rc@G \tabu@rc@ + \fi + \fi + \tabu@everyrow@egroup +}% \tabu@rowcolorseries +\tabuDisableCommands {\let\tabu@rc@ \@empty } +\def\tabu@rowcolorserieserror {\PackageError{tabu} + {Invalid syntax for \string\taburowcolors + \MessageBreak Please look at the documentation!}\@ehd +}% \tabu@rowcolorserieserror +\newcommand*\tabureset {% + \tabulinesep=\z@ \extrarowsep=\z@ \extratabsurround=\z@ + \tabulinestyle{}\everyrow{}\taburulecolor||{}\taburowcolors{}% +}% \tabureset +%% Parsing the line styles ------------------------------------------ +\def\tabu@getline #1{\begingroup + \csname \ifcsname if@safe@actives\endcsname % + @safe@activestrue\else + relax\fi \endcsname + \edef\tabu@temp{#1}\tabu@sanitizearg{#1}\@tempa + \let\tabu@thestyle \relax + \ifcsname tabu@linestyle@\@tempa \endcsname + \edef\tabu@thestyle{\endgroup + \def\tabu@thestyle{\expandafter\noexpand + \csname tabu@linestyle@\@tempa\endcsname}% + }\tabu@thestyle + \else \expandafter\tabu@definestyle \tabu@temp \@nil + \fi +}% \tabu@getline +\def\tabu@definestyle #1#2\@nil {\endlinechar \m@ne \makeatletter + \tabu@thick \maxdimen \tabu@on \maxdimen \tabu@off \maxdimen + \let\tabu@c@lon \@undefined \let\tabu@c@loff \@undefined + \ifodd 1\ifcat .#1\else\ifcat\relax #1\else 0\fi\fi % catcode 12 or non expandable cs + \def\tabu@temp{\tabu@getparam{thick}}% + \else \def\tabu@temp{\tabu@getparam{thick}\maxdimen}% + \fi + {% + \let\tabu@ \relax + \def\:{\obeyspaces \tabu@oXIII \tabu@commaXIII \edef\:}% (space active \: happy ;-)) + \scantokens{\:{\tabu@temp #1#2 \tabu@\tabu@}}% + \expandafter}\expandafter + \def\expandafter\:\expandafter{\:}% line spec rewritten now ;-) + \def\;{\def\:}% + \scantokens\expandafter{\expandafter\;\expandafter{\:}}% space is now inactive (catcode 10) + \let\tabu@ \tabu@getcolor \:% all arguments are ready now ;-) + \ifdefined\tabu@c@lon \else \let\tabu@c@lon\@empty \fi + \ifx \tabu@c@lon\@empty \def\tabu@c@lon{\CT@arc@}\fi + \ifdefined\tabu@c@loff \else \let\tabu@c@loff \@empty \fi + \ifdim \tabu@on=\maxdimen \ifdim \tabu@off<\maxdimen + \tabu@on \tabulineon \fi\fi + \ifdim \tabu@off=\maxdimen \ifdim \tabu@on<\maxdimen + \tabu@off \tabulineoff \fi\fi + \ifodd 1\ifdim \tabu@off=\maxdimen \ifdim \tabu@on=\maxdimen 0 \fi\fi + \in@true % + \else \in@false % + \fi + \ifdim\tabu@thick=\maxdimen \def\tabu@thick{\arrayrulewidth}% + \else \edef\tabu@thick{\the\tabu@thick}% + \fi + \edef \tabu@thestyle ##1##2{\endgroup + \def\tabu@thestyle{% + \ifin@ \noexpand\tabu@leadersstyle {\tabu@thick} + {\the\tabu@on}{##1} + {\the\tabu@off}{##2}% + \else \noexpand\tabu@rulesstyle + {##1\vrule width \tabu@thick}% + {##1\leaders \hrule height \tabu@thick \hfil}% + \fi}% + }\expandafter \expandafter + \expandafter \tabu@thestyle \expandafter + \expandafter \expandafter + {\expandafter\tabu@c@lon\expandafter}\expandafter{\tabu@c@loff}% +}% \tabu@definestyle +{\catcode`\O=\active \lccode`\O=`\o \catcode`\,=\active + \lowercase{\gdef\tabu@oXIII {\catcode`\o=\active \let O=\tabu@oxiii}} + \gdef\tabu@commaXIII {\catcode`\,=\active \let ,=\space} +}% \catcode +\def\tabu@oxiii #1{% + \ifcase \ifx n#1\z@ \else + \ifx f#1\@ne\else + \tw@ \fi\fi + \expandafter\tabu@onxiii + \or \expandafter\tabu@ofxiii + \else o% + \fi#1}% +\def\tabu@onxiii #1#2{% + \ifcase \ifx !#2\tw@ \else + \ifcat.\noexpand#2\z@ \else + \ifx \tabu@spxiii#2\@ne\else + \tw@ \fi\fi\fi + \tabu@getparam{on}#2\expandafter\@gobble + \or \expandafter\tabu@onxiii % (space is active) + \else o\expandafter\@firstofone + \fi{#1#2}}% +\def\tabu@ofxiii #1#2{% + \ifx #2f\expandafter\tabu@offxiii + \else o\expandafter\@firstofone + \fi{#1#2}} +\def\tabu@offxiii #1#2{% + \ifcase \ifx !#2\tw@ \else + \ifcat.\noexpand#2\z@ \else + \ifx\tabu@spxiii#2\@ne \else + \tw@ \fi\fi\fi + \tabu@getparam{off}#2\expandafter\@gobble + \or \expandafter\tabu@offxiii % (space is active) + \else o\expandafter\@firstofone + \fi{#1#2}} +\def\tabu@getparam #1{\tabu@ \csname tabu@#1\endcsname=} +\def\tabu@getcolor #1{% \tabu@ <- \tabu@getcolor after \edef + \ifx \tabu@#1\else % no more spec + \let\tabu@theparam=#1\afterassignment \tabu@getc@l@r #1\fi +}% \tabu@getcolor +\def\tabu@getc@l@r #1\tabu@ {% + \def\tabu@temp{#1}\tabu@strtrim \tabu@temp + \ifx \tabu@temp\@empty + \else%\ifcsname \string\color@\tabu@temp \endcsname % if the color exists + \ifx \tabu@theparam \tabu@off \let\tabu@c@loff \tabu@c@l@r + \else \let\tabu@c@lon \tabu@c@l@r + \fi + %\else \tabu@warncolour{\tabu@temp}% + \fi%\fi + \tabu@ % next spec +}% \tabu@getc@l@r +\def\tabu@warncolour #1{\PackageWarning{tabu} + {Color #1 is not defined. Default color used}% +}% \tabu@warncolour +\def\tabu@leadersstyle #1#2#3#4#5{\def\tabu@leaders{{#1}{#2}{#3}{#4}{#5}}% + \ifx \tabu@leaders\tabu@leaders@G \else + \tabu@LEADERS{#1}{#2}{#3}{#4}{#5}\fi +}% \tabu@leadersstyle +\def\tabu@rulesstyle #1#2{\let\tabu@leaders \@undefined + \gdef\tabu@thevrule{#1}\gdef\tabu@thehrule{#2}% +}% \tabu@rulesstyle +%% The leaders boxes ------------------------------------------------ +\def\tabu@LEADERS #1#2#3#4#5{%% width, dash, dash color, gap, gap color + {\let\color \tabu@color % => during trials -> \color = \tabu@nocolor + {% % but the leaders boxes should have colors ! + \def\@therule{\vrule}\def\@thick{height}\def\@length{width}% + \def\@box{\hbox}\def\@unbox{\unhbox}\def\@elt{\wd}% + \def\@skip{\hskip}\def\@ss{\hss}\def\tabu@leads{\tabu@hleads}% + \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}% + \global\let\tabu@thehleaders \tabu@theleaders + }% + {% + \def\@therule{\hrule}\def\@thick{width}\def\@length{height}% + \def\@box{\vbox}\def\@unbox{\unvbox}\def\@elt{\ht}% + \def\@skip{\vskip}\def\@ss{\vss}\def\tabu@leads{\tabu@vleads}% + \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}% + \global\let\tabu@thevleaders \tabu@theleaders + }% + \gdef\tabu@leaders@G{{#1}{#2}{#3}{#4}{#5}}% + }% +}% \tabu@LEADERS +\def\tabu@therule #1#2{\@therule \@thick#1\@length\dimexpr#2/2 \@depth\z@} +\def\tabu@l@@d@rs #1#2#3#4#5{%% width, dash, dash color, gap, gap color + \global\setbox \tabu@leads=\@box{% + {#3\tabu@therule{#1}{#2}}% + \ifx\\#5\\\@skip#4\else{#5\tabu@therule{#1}{#4*2}}\fi + {#3\tabu@therule{#1}{#2}}}% + \global\setbox\tabu@leads=\@box to\@elt\tabu@leads{\@ss + {#3\tabu@therule{#1}{#2}}\@unbox\tabu@leads}% + \edef\tabu@theleaders ##1{\def\noexpand\tabu@theleaders {% + {##1\tabu@therule{#1}{#2}}% + \xleaders \copy\tabu@leads \@ss + \tabu@therule{0pt}{-#2}{##1\tabu@therule{#1}{#2}}}% + }\tabu@theleaders{#3}% +}% \tabu@l@@d@rs +%% \tabu \endtabu \tabu* \longtabu \endlongtabu \longtabu* ---------- +\newcommand*\tabu {\tabu@longfalse + \ifmmode \def\tabu@ {\array}\def\endtabu {\endarray}% + \else \def\tabu@ {\tabu@tabular}\def\endtabu {\endtabular}\fi + \expandafter\let\csname tabu*\endcsname \tabu + \expandafter\def\csname endtabu*\endcsname{\endtabu}% + \tabu@spreadfalse \tabu@negcoeffalse \tabu@settarget +}% {tabu} +\let\tabu@tabular \tabular % +\expandafter\def\csname tabu*\endcsname{\tabuscantokenstrue \tabu} +\newcommand*\longtabu {\tabu@longtrue + \ifmmode\PackageError{tabu}{longtabu not allowed in math mode}\fi + \def\tabu@{\longtable}\def\endlongtabu{\endlongtable}% + \LTchunksize=\@M + \expandafter\let\csname tabu*\endcsname \tabu + \expandafter\def\csname endlongtabu*\endcsname{\endlongtabu}% + \let\LT@startpbox \tabu@LT@startpbox % \everypar{ array struts } + \tabu@spreadfalse \tabu@negcoeffalse \tabu@settarget +}% {longtabu} +\expandafter\def\csname longtabu*\endcsname{\tabuscantokenstrue \longtabu} +\def\tabu@nolongtabu{\PackageError{tabu} + {longtabu requires the longtable package}\@ehd} +%% Read the target and then : \tabular or \@array ------------------ +\def\tabu@settarget {\futurelet\@let@token \tabu@sett@rget } +\def\tabu@sett@rget {\tabu@target \z@ + \ifcase \ifx \bgroup\@let@token \z@ \else + \ifx \@sptoken\@let@token \@ne \else + \if t\@let@token \tw@ \else + \if s\@let@token \thr@@\else + \z@\fi\fi\fi\fi + \expandafter\tabu@begin + \or \expandafter\tabu@gobblespace\expandafter\tabu@settarget + \or \expandafter\tabu@to + \or \expandafter\tabu@spread + \fi +}% \tabu@sett@rget +\def\tabu@to to{\def\tabu@halignto{to}\tabu@gettarget} +\def\tabu@spread spread{\tabu@spreadtrue\def\tabu@halignto{spread}\tabu@gettarget} +\def\tabu@gettarget {\afterassignment\tabu@linegoaltarget \tabu@target } +\def\tabu@linegoaltarget {\futurelet\tabu@temp \tabu@linegoalt@rget } +\def\tabu@linegoalt@rget {% + \ifx \tabu@temp\LNGL@setlinegoal + \LNGL@setlinegoal \expandafter \@firstoftwo \fi % @gobbles \LNGL@setlinegoal + \tabu@begin +}% \tabu@linegoalt@rget +\def\tabu@begin #1#{% + \iftabu@measuring \expandafter\tabu@nestedmeasure \fi + \ifdim \tabu@target=\z@ \let\tabu@halignto \@empty + \else \edef\tabu@halignto{\tabu@halignto\the\tabu@target}% + \fi + \@testopt \tabu@tabu@ \tabu@aligndefault #1\@nil +}% \tabu@begin +\long\def\tabu@tabu@ [#1]#2\@nil #3{\tabu@setup + \def\tabu@align {#1}\def\tabu@savedpream{\NC@find #3}% + \tabu@ [\tabu@align ]#2{#3\tabu@rewritefirst }% +}% \tabu@tabu@ +\def\tabu@nestedmeasure {% + \ifodd 1\iftabu@spread \else \ifdim\tabu@target=\z@ \else 0 \fi\fi\relax + \tabu@spreadtrue + \else \begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}% + \expandafter\tabu@collectbody\expandafter\tabu@quickrule + \expandafter\endgroup + \fi +}% \tabu@nestedmeasure +\def\tabu@quickrule {\indent\vrule height\z@ depth\z@ width\tabu@target} +%% \tabu@setup \tabu@init \tabu@indent +\def\tabu@setup{\tabu@alloc@ + \ifcase \tabu@nested + \ifmmode \else \iftabu@spread\else \ifdim\tabu@target=\z@ + \let\tabu@afterendpar \par + \fi\fi\fi + \def\tabu@aligndefault{c}\tabu@init \tabu@indent + \else % + \def\tabu@aligndefault{t}\let\tabudefaulttarget \linewidth + \fi + \let\tabu@thetarget \tabudefaulttarget \let\tabu@restored \@undefined + \edef\tabu@NC@list{\the\NC@list}\NC@list{\NC@do \tabu@rewritefirst}% + \everycr{}\let\@startpbox \tabu@startpbox % for nested tabu inside longtabu... + \let\@endpbox \tabu@endpbox % idem " " " " " " + \let\@tabarray \tabu@tabarray % idem " " " " " " + \tabu@setcleanup \tabu@setreset +}% \tabu@setup +\def\tabu@init{\tabu@starttimer \tabu@measuringfalse + \edef\tabu@hfuzz {\the\dimexpr\hfuzz+1sp}\global\tabu@footnotes{}% + \let\firsthline \tabu@firsthline \let\lasthline \tabu@lasthline + \let\firstline \tabu@firstline \let\lastline \tabu@lastline + \let\hline \tabu@hline \let\@xhline \tabu@xhline + \let\color \tabu@color \let\@arstrutbox \tabu@arstrutbox + \iftabu@colortbl\else\let\LT@@hline \tabu@LT@@hline \fi + \tabu@trivlist % + \let\@footnotetext \tabu@footnotetext \let\@xfootnotetext \tabu@xfootnotetext + \let\@xfootnote \tabu@xfootnote \let\centering \tabu@centering + \let\raggedright \tabu@raggedright \let\raggedleft \tabu@raggedleft + \let\tabudecimal \tabu@tabudecimal \let\Centering \tabu@Centering + \let\RaggedRight \tabu@RaggedRight \let\RaggedLeft \tabu@RaggedLeft + \let\justifying \tabu@justifying \let\rowfont \tabu@rowfont + \let\fbox \tabu@fbox \let\color@b@x \tabu@color@b@x + \let\tabu@@everycr \everycr \let\tabu@@everypar \everypar + \let\tabu@prepnext@tokORI \prepnext@tok\let\prepnext@tok \tabu@prepnext@tok + \let\tabu@multicolumnORI\multicolumn \let\multicolumn \tabu@multicolumn + \let\tabu@startpbox \@startpbox % for nested tabu inside longtabu pfff !!! + \let\tabu@endpbox \@endpbox % idem " " " " " " " + \let\tabu@tabarray \@tabarray % idem " " " " " " " + \tabu@adl@fix \let\endarray \tabu@endarray % colortbl & arydshln (delarray) + \iftabu@colortbl\CT@everycr\expandafter{\expandafter\iftabu@everyrow \the\CT@everycr \fi}\fi +}% \tabu@init +\def\tabu@indent{% correction for indentation + \ifdim \parindent>\z@\ifx \linewidth\tabudefaulttarget + \everypar\expandafter{% + \the\everypar\everypar\expandafter{\the\everypar}% + \setbox\z@=\lastbox + \ifdim\wd\z@>\z@ \edef\tabu@thetarget + {\the\dimexpr -\wd\z@+\tabudefaulttarget}\fi + \box\z@}% + \fi\fi +}% \tabu@indent +\def\tabu@setcleanup {% saves last global assignments + \ifodd 1\ifmmode \else \iftabu@long \else 0\fi\fi\relax + \def\tabu@aftergroupcleanup{% + \def\tabu@aftergroupcleanup{\aftergroup\tabu@cleanup}}% + \else + \def\tabu@aftergroupcleanup{% + \aftergroup\aftergroup\aftergroup\tabu@cleanup + \let\tabu@aftergroupcleanup \relax}% + \fi + \let\tabu@arc@Gsave \tabu@arc@G + \let\tabu@arc@G \tabu@arc@L % + \let\tabu@drsc@Gsave \tabu@drsc@G + \let\tabu@drsc@G \tabu@drsc@L % + \let\tabu@ls@Gsave \tabu@ls@G + \let\tabu@ls@G \tabu@ls@L % + \let\tabu@rc@Gsave \tabu@rc@G + \let\tabu@rc@G \tabu@rc@L % + \let\tabu@evr@Gsave \tabu@evr@G + \let\tabu@evr@G \tabu@evr@L % + \let\tabu@celllalign@save \tabu@celllalign + \let\tabu@cellralign@save \tabu@cellralign + \let\tabu@cellleft@save \tabu@cellleft + \let\tabu@cellright@save \tabu@cellright + \let\tabu@@celllalign@save \tabu@@celllalign + \let\tabu@@cellralign@save \tabu@@cellralign + \let\tabu@@cellleft@save \tabu@@cellleft + \let\tabu@@cellright@save \tabu@@cellright + \let\tabu@rowfontreset@save \tabu@rowfontreset + \let\tabu@@rowfontreset@save\tabu@@rowfontreset + \let\tabu@rowfontreset \@empty + \edef\tabu@alloc@save {\the\tabu@alloc}% restore at \tabu@reset + \edef\c@taburow@save {\the\c@taburow}% + \edef\tabu@naturalX@save {\the\tabu@naturalX}% + \let\tabu@naturalXmin@save \tabu@naturalXmin + \let\tabu@naturalXmax@save \tabu@naturalXmax + \let\tabu@mkarstrut@save \tabu@mkarstrut + \edef\tabu@clarstrut{% + \extrarowheight \the\dimexpr \ht\@arstrutbox-\ht\strutbox \relax + \extrarowdepth \the\dimexpr \dp\@arstrutbox-\dp\strutbox \relax + \let\noexpand\@arraystretch \@ne \noexpand\tabu@rearstrut}% +}% \tabu@setcleanup +\def\tabu@cleanup {\begingroup + \globaldefs\@ne \tabu@everyrowtrue + \let\tabu@arc@G \tabu@arc@Gsave + \let\CT@arc@ \tabu@arc@G + \let\tabu@drsc@G \tabu@drsc@Gsave + \let\CT@drsc@ \tabu@drsc@G + \let\tabu@ls@G \tabu@ls@Gsave + \let\tabu@ls@ \tabu@ls@G + \let\tabu@rc@G \tabu@rc@Gsave + \let\tabu@rc@ \tabu@rc@G + \let\CT@do@color \relax + \let\tabu@evr@G \tabu@evr@Gsave + \let\tabu@celllalign \tabu@celllalign@save + \let\tabu@cellralign \tabu@cellralign@save + \let\tabu@cellleft \tabu@cellleft@save + \let\tabu@cellright \tabu@cellright@save + \let\tabu@@celllalign \tabu@@celllalign@save + \let\tabu@@cellralign \tabu@@cellralign@save + \let\tabu@@cellleft \tabu@@cellleft@save + \let\tabu@@cellright \tabu@@cellright@save + \let\tabu@rowfontreset \tabu@rowfontreset@save + \let\tabu@@rowfontreset \tabu@@rowfontreset@save + \tabu@naturalX =\tabu@naturalX@save + \let\tabu@naturalXmax \tabu@naturalXmax@save + \let\tabu@naturalXmin \tabu@naturalXmin@save + \let\tabu@mkarstrut \tabu@mkarstrut@save + \c@taburow =\c@taburow@save + \ifcase \tabu@nested \tabu@alloc \m@ne\fi + \endgroup % + \ifcase \tabu@nested + \the\tabu@footnotes \global\tabu@footnotes{}% + \tabu@afterendpar \tabu@elapsedtime + \fi + \tabu@clarstrut + \everyrow\expandafter {\tabu@evr@G}% +}% \tabu@cleanup +\let\tabu@afterendpar \relax +\def\tabu@setreset {% + \edef\tabu@savedparams {% \relax for \tabu@message@save + \ifmmode \col@sep \the\arraycolsep + \else \col@sep \the\tabcolsep \fi \relax + \arrayrulewidth \the\arrayrulewidth \relax + \doublerulesep \the\doublerulesep \relax + \extratabsurround \the\extratabsurround \relax + \extrarowheight \the\extrarowheight \relax + \extrarowdepth \the\extrarowdepth \relax + \abovetabulinesep \the\abovetabulinesep \relax + \belowtabulinesep \the\belowtabulinesep \relax + \def\noexpand\arraystretch{\arraystretch}% + \ifdefined\minrowclearance \minrowclearance\the\minrowclearance\relax\fi}% + \begingroup + \@temptokena\expandafter{\tabu@savedparams}% => only for \savetabu / \usetabu + \ifx \tabu@arc@L\relax \else \tabu@setsave \tabu@arc@L \fi + \ifx \tabu@drsc@L\relax \else \tabu@setsave \tabu@drsc@L \fi + \tabu@setsave \tabu@ls@L \tabu@setsave \tabu@evr@L + \expandafter \endgroup \expandafter + \def\expandafter\tabu@saved@ \expandafter{\the\@temptokena + \let\tabu@arc@G \tabu@arc@L + \let\tabu@drsc@G \tabu@drsc@L + \let\tabu@ls@G \tabu@ls@L + \let\tabu@rc@G \tabu@rc@L + \let\tabu@evr@G \tabu@evr@L}% + \def\tabu@reset{\tabu@savedparams + \tabu@everyrowtrue \c@taburow \z@ + \let\CT@arc@ \tabu@arc@L + \let\CT@drsc@ \tabu@drsc@L + \let\tabu@ls@ \tabu@ls@L + \let\tabu@rc@ \tabu@rc@L + \global\tabu@alloc \tabu@alloc@save + \everyrow\expandafter{\tabu@evr@L}}% +}% \tabu@reset +\def\tabu@setsave #1{\expandafter\tabu@sets@ve #1\@nil{#1}} +\long\def\tabu@sets@ve #1\@nil #2{\@temptokena\expandafter{\the\@temptokena \def#2{#1}}} +%% The Rewriting Process ------------------------------------------- +\def\tabu@newcolumntype #1{% + \expandafter\tabu@new@columntype + \csname NC@find@\string#1\expandafter\endcsname + \csname NC@rewrite@\string#1\endcsname + {#1}% +}% \tabu@newcolumntype +\def\tabu@new@columntype #1#2#3{% + \def#1##1#3{\NC@{##1}}% + \let#2\relax \newcommand*#2% +}% \tabu@new@columntype +\def\tabu@privatecolumntype #1{% + \expandafter\tabu@private@columntype + \csname NC@find@\string#1\expandafter\endcsname + \csname NC@rewrite@\string#1\expandafter\endcsname + \csname tabu@NC@find@\string#1\expandafter\endcsname + \csname tabu@NC@rewrite@\string#1\endcsname + {#1}% +}% \tabu@privatecolumntype +\def\tabu@private@columntype#1#2#3#4{% + \g@addto@macro\tabu@privatecolumns{\let#1#3\let#2#4}% + \tabu@new@columntype#3#4% +}% \tabu@private@columntype +\let\tabu@privatecolumns \@empty +\newcommand*\tabucolumn [1]{\expandafter \def \expandafter + \tabu@highprioritycolumns\expandafter{\tabu@highprioritycolumns + \NC@do #1}}% +\let\tabu@highprioritycolumns \@empty +%% The | ``column'' : rewriting process -------------------------- +\tabu@privatecolumntype |{\tabu@rewritevline} +\newcommand*\tabu@rewritevline[1][]{\tabu@vlinearg{#1}% + \expandafter \NC@find \tabu@rewritten} +\def\tabu@lines #1{% + \ifx|#1\else \tabu@privatecolumntype #1{\tabu@rewritevline}\fi + \NC@list\expandafter{\the\NC@list \NC@do #1}% +}% \tabu@lines@ +\def\tabu@vlinearg #1{% + \ifx\\#1\\\def\tabu@thestyle {\tabu@ls@}% + \else\tabu@getline {#1}% + \fi + \def\tabu@rewritten ##1{\def\tabu@rewritten{!{##1\tabu@thevline}}% + }\expandafter\tabu@rewritten\expandafter{\tabu@thestyle}% + \expandafter \tabu@keepls \tabu@thestyle \@nil +}% \tabu@vlinearg +\def\tabu@keepls #1\@nil{% + \ifcat $\@cdr #1\@nil $% + \ifx \relax#1\else + \ifx \tabu@ls@#1\else + \let#1\relax + \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer + \tabu@savels\noexpand#1}\fi\fi\fi +}% \tabu@keepls +\def\tabu@thevline {\begingroup + \ifdefined\tabu@leaders + \setbox\@tempboxa=\vtop to\dimexpr + \ht\@arstrutbox+\dp\@arstrutbox{{\tabu@thevleaders}}% + \ht\@tempboxa=\ht\@arstrutbox \dp\@tempboxa=\dp\@arstrutbox + \box\@tempboxa + \else + \tabu@thevrule + \fi \endgroup +}% \tabu@thevline +\def\tabu@savels #1{% + \expandafter\let\csname\string#1\endcsname #1% + \expandafter\def\expandafter\tabu@reset\expandafter{\tabu@reset + \tabu@resetls#1}}% +\def\tabu@resetls #1{\expandafter\let\expandafter#1\csname\string#1\endcsname}% +%% \multicolumn inside tabu environment ----------------------------- +\tabu@newcolumntype \tabu@rewritemulticolumn{% + \aftergroup \tabu@endrewritemulticolumn % after \@mkpream group + \NC@list{\NC@do *}\tabu@textbar \tabu@lines + \tabu@savedecl + \tabu@privatecolumns + \NC@list\expandafter{\the\expandafter\NC@list \tabu@NC@list}% + \let\tabu@savels \relax + \NC@find +}% \tabu@rewritemulticolumn +\def\tabu@endrewritemulticolumn{\gdef\tabu@mkpreambuffer{}\endgroup} +\def\tabu@multicolumn{\tabu@ifenvir \tabu@multic@lumn \tabu@multicolumnORI} +\long\def\tabu@multic@lumn #1#2#3{\multispan{#1}\begingroup + \tabu@everyrowtrue + \NC@list{\NC@do \tabu@rewritemulticolumn}% + \expandafter\@gobbletwo % gobbles \multispan{#1} + \tabu@multicolumnORI{#1}{\tabu@rewritemulticolumn #2}% + {\iftabuscantokens \tabu@rescan \else \expandafter\@firstofone \fi + {#3}}% +}% \tabu@multic@lumn +%% The X column(s): rewriting process ----------------------------- +\tabu@privatecolumntype X[1][]{\begingroup \tabu@siunitx{\endgroup \tabu@rewriteX {#1}}} +\def\tabu@nosiunitx #1{#1{}{}\expandafter \NC@find \tabu@rewritten } +\def\tabu@siunitx #1{\@ifnextchar \bgroup + {\tabu@rewriteX@Ss{#1}} + {\tabu@nosiunitx{#1}}} +\def\tabu@rewriteX@Ss #1#2{\@temptokena{}% + \@defaultunits \let\tabu@temp =#2\relax\@nnil + \ifodd 1\ifx S\tabu@temp \else \ifx s\tabu@temp \else 0 \fi\fi + \def\NC@find{\def\NC@find >####1####2<####3\relax{#1 {####1}{####3}% + }\expandafter\NC@find \the\@temptokena \relax + }\expandafter\NC@rewrite@S \@gobble #2\relax + \else \tabu@siunitxerror + \fi + \expandafter \NC@find \tabu@rewritten +}% \tabu@rewriteX@Ss +\def\tabu@siunitxerror {\PackageError{tabu}{Not a S nor s column ! + \MessageBreak X column can only embed siunitx S or s columns}\@ehd +}% \tabu@siunitxerror +\def\tabu@rewriteX #1#2#3{\tabu@Xarg {#1}{#2}{#3}% + \iftabu@measuring + \else \tabu@measuringtrue % first X column found in the preamble + \let\@halignto \relax \let\tabu@halignto \relax + \iftabu@spread \tabu@spreadtarget \tabu@target \tabu@target \z@ + \else \tabu@spreadtarget \z@ \fi + \ifdim \tabu@target=\z@ + \setlength\tabu@target \tabu@thetarget + \tabu@message{\tabu@message@defaulttarget}% + \else \tabu@message{\tabu@message@target}\fi + \fi +}% \tabu@rewriteX +\def\tabu@rewriteXrestore #1#2#3{\let\@halignto \relax + \def\tabu@rewritten{l}} +\def\tabu@Xarg #1#2#3{% + \advance\tabu@Xcol \@ne \let\tabu@Xlcr \@empty + \let\tabu@Xdisp \@empty \let\tabu@Xmath \@empty + \ifx\\#1\\% + \def\tabu@rewritten{p}\tabucolX \p@ % + \else + \let\tabu@rewritten \@empty \let\tabu@temp \@empty \tabucolX \z@ + \tabu@Xparse {}#1\relax + \fi + \tabu@Xrewritten{#2}{#3}% +}% \tabu@Xarg +\def\tabu@Xparse #1{\futurelet\@let@token \tabu@Xtest} +\expandafter\def\expandafter\tabu@Xparsespace\space{\tabu@Xparse{}} +\def\tabu@Xtest{% + \ifcase \ifx \relax\@let@token \z@ \else + \if ,\@let@token \m@ne\else + \if p\@let@token 1\else + \if m\@let@token 2\else + \if b\@let@token 3\else + \if l\@let@token 4\else + \if c\@let@token 5\else + \if r\@let@token 6\else + \if j\@let@token 7\else + \if L\@let@token 8\else + \if C\@let@token 9\else + \if R\@let@token 10\else + \if J\@let@token 11\else + \ifx \@sptoken\@let@token 12\else + \if .\@let@token 13\else + \if -\@let@token 13\else + \ifcat $\@let@token 14\else + 15\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax + \or \tabu@Xtype {p}% + \or \tabu@Xtype {m}% + \or \tabu@Xtype {b}% + \or \tabu@Xalign \raggedright\relax + \or \tabu@Xalign \centering\relax + \or \tabu@Xalign \raggedleft\relax + \or \tabu@Xalign \tabu@justify\relax + \or \tabu@Xalign \RaggedRight\raggedright + \or \tabu@Xalign \Centering\centering + \or \tabu@Xalign \RaggedLeft\raggedleft + \or \tabu@Xalign \justifying\tabu@justify + \or \expandafter \tabu@Xparsespace + \or \expandafter \tabu@Xcoef + \or \expandafter \tabu@Xm@th + \or \tabu@Xcoef{}% + \else\expandafter \tabu@Xparse + \fi +}% \tabu@Xtest +\def\tabu@Xalign #1#2{% + \ifx \tabu@Xlcr\@empty \else \PackageWarning{tabu} + {Duplicate horizontal alignment specification}\fi + \ifdefined#1\def\tabu@Xlcr{#1}\let#1\relax + \else \def\tabu@Xlcr{#2}\let#2\relax\fi + \expandafter\tabu@Xparse +}% \tabu@Xalign +\def\tabu@Xtype #1{% + \ifx \tabu@rewritten\@empty \else \PackageWarning{tabu} + {Duplicate vertical alignment specification}\fi + \def\tabu@rewritten{#1}\expandafter\tabu@Xparse +}% \tabu@Xtype +\def\tabu@Xcoef#1{\edef\tabu@temp{\tabu@temp#1}% + \afterassignment\tabu@Xc@ef \tabu@cnt\number\if-#10\fi +}% \tabu@Xcoef +\def\tabu@Xc@ef{\advance\tabucolX \tabu@temp\the\tabu@cnt\p@ + \tabu@Xparse{}% +}% \tabu@Xc@ef +\def\tabu@Xm@th #1{\futurelet \@let@token \tabu@Xd@sp} +\def\tabu@Xd@sp{\let\tabu@Xmath=$% + \ifx $\@let@token \def\tabu@Xdisp{\displaystyle}% + \expandafter\tabu@Xparse + \else \expandafter\tabu@Xparse\expandafter{\expandafter}% + \fi +}% \tabu@Xd@sp +\def\tabu@Xrewritten {% + \ifx \tabu@rewritten\@empty \def\tabu@rewritten{p}\fi + \ifdim \tabucolX<\z@ \tabu@negcoeftrue + \else\ifdim \tabucolX=\z@ \tabucolX \p@ + \fi\fi + \edef\tabu@temp{{\the\tabu@Xcol}{\tabu@strippt\tabucolX}}% + \edef\tabu@Xcoefs{\tabu@Xcoefs \tabu@ \tabu@temp}% + \edef\tabu@rewritten ##1##2{\def\noexpand\tabu@rewritten{% + >{\tabu@Xlcr \ifx$\tabu@Xmath$\tabu@Xdisp\fi ##1}% + \tabu@rewritten {\tabu@hsize \tabu@temp}% + <{##2\ifx$\tabu@Xmath$\fi}}% + }\tabu@rewritten +}% \tabu@Xrewritten +\def\tabu@hsize #1#2{% + \ifdim #2\p@<\z@ + \ifdim \tabucolX=\maxdimen \tabu@wd{#1}\else + \ifdim \tabu@wd{#1}<-#2\tabucolX \tabu@wd{#1}\else -#2\tabucolX\fi + \fi + \else #2\tabucolX + \fi +}% \tabu@hsize +%% \usetabu and \preamble: rewriting process --------------------- +\tabu@privatecolumntype \usetabu [1]{% + \ifx\\#1\\\tabu@saveerr{}\else + \@ifundefined{tabu@saved@\string#1} + {\tabu@saveerr{#1}} + {\let\tabu@rewriteX \tabu@rewriteXrestore + \csname tabu@saved@\string#1\expandafter\endcsname\expandafter\@ne}% + \fi +}% \NC@rewrite@\usetabu +\tabu@privatecolumntype \preamble [1]{% + \ifx\\#1\\\tabu@saveerr{}\else + \@ifundefined{tabu@saved@\string#1} + {\tabu@saveerr{#1}} + {\csname tabu@saved@\string#1\expandafter\endcsname\expandafter\z@}% + \fi +}% \NC@rewrite@\preamble +%% Controlling the rewriting process ------------------------------- +\tabu@newcolumntype \tabu@rewritefirst{% + \iftabu@long \aftergroup \tabu@longpream % + \else \aftergroup \tabu@pream + \fi + \let\tabu@ \relax \let\tabu@hsize \relax + \let\tabu@Xcoefs \@empty \let\tabu@savels \relax + \tabu@Xcol \z@ \tabu@cnt \tw@ + \gdef\tabu@mkpreambuffer{\tabu@{}}\tabu@measuringfalse + \global\setbox\@arstrutbox \box\@arstrutbox + \NC@list{\NC@do *}\tabu@textbar \tabu@lines + \NC@list\expandafter{\the\NC@list \NC@do X}% + \iftabu@siunitx % + \NC@list\expandafter{\the\NC@list \NC@do S\NC@do s}\fi + \NC@list\expandafter{\the\expandafter\NC@list \tabu@highprioritycolumns}% + \expandafter\def\expandafter\tabu@NC@list\expandafter{% + \the\expandafter\NC@list \tabu@NC@list}% % * | X S + \NC@list\expandafter{\expandafter \NC@do \expandafter\usetabu + \expandafter \NC@do \expandafter\preamble + \the\NC@list \NC@do \tabu@rewritemiddle + \NC@do \tabu@rewritelast}% + \tabu@savedecl + \tabu@privatecolumns + \edef\tabu@prev{\the\@temptokena}\NC@find \tabu@rewritemiddle +}% NC@rewrite@\tabu@rewritefirst +\tabu@newcolumntype \tabu@rewritemiddle{% + \edef\tabu@temp{\the\@temptokena}\NC@find \tabu@rewritelast +}% \NC@rewrite@\tabu@rewritemiddle +\tabu@newcolumntype \tabu@rewritelast{% + \ifx \tabu@temp\tabu@prev \advance\tabu@cnt \m@ne + \NC@list\expandafter{\tabu@NC@list \NC@do \tabu@rewritemiddle + \NC@do \tabu@rewritelast}% + \else \let\tabu@prev\tabu@temp + \fi + \ifcase \tabu@cnt \expandafter\tabu@endrewrite + \else \expandafter\NC@find \expandafter\tabu@rewritemiddle + \fi +}% \NC@rewrite@\tabu@rewritelast +%% Choosing the strategy -------------------------------------------- +\def\tabu@endrewrite {% + \let\tabu@temp \NC@find + \ifx \@arrayright\relax \let\@arrayright \@empty \fi + \count@=% + \ifx \@finalstrut\tabu@finalstrut \z@ % outer in mode 0 print + \iftabu@measuring + \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer + \tabu@target \csname tabu@\the\tabu@nested.T\endcsname + \tabucolX \csname tabu@\the\tabu@nested.X\endcsname + \edef\@halignto {\ifx\@arrayright\@empty to\tabu@target\fi}}% + \fi + \else\iftabu@measuring 4 % X columns + \xdef\tabu@mkpreambuffer{\tabu@{\tabu@mkpreambuffer + \tabu@target \the\tabu@target + \tabu@spreadtarget \the\tabu@spreadtarget}% + \def\noexpand\tabu@Xcoefs{\tabu@Xcoefs}% + \edef\tabu@halignto{\ifx \@arrayright\@empty to\tabu@target\fi}}% + \let\tabu@Xcoefs \relax + \else\ifcase\tabu@nested \thr@@ % outer, no X + \global\let\tabu@afterendpar \relax + \else \@ne % inner, no X, outer in mode 1 or 2 + \fi + \ifdefined\tabu@usetabu + \else \ifdim\tabu@target=\z@ + \else \let\tabu@temp \tabu@extracolsep + \fi\fi + \fi + \fi + \xdef\tabu@mkpreambuffer{\count@ \the\count@ \tabu@mkpreambuffer}% + \tabu@temp +}% \tabu@endrewrite +\def\tabu@extracolsep{\@defaultunits \expandafter\let + \expandafter\tabu@temp \expandafter=\the\@temptokena \relax\@nnil + \ifx \tabu@temp\@sptoken + \expandafter\tabu@gobblespace \expandafter\tabu@extracolsep + \else + \edef\tabu@temp{\noexpand\NC@find + \if |\noexpand\tabu@temp @% + \else\if !\noexpand\tabu@temp @% + \else !% + \fi\fi + {\noexpand\extracolsep\noexpand\@flushglue}}% + \fi + \tabu@temp +}% \tabu@extrac@lsep +%% Implementing the strategy ---------------------------------------- +\long\def\tabu@pream #1\@preamble {% + \let\tabu@ \tabu@@ \tabu@mkpreambuffer \tabu@aftergroupcleanup + \NC@list\expandafter {\tabu@NC@list}% in case of nesting... + \ifdefined\tabu@usetabu \tabu@usetabu \tabu@target \z@ \fi + \let\tabu@savedpreamble \@preamble + \global\let\tabu@elapsedtime \relax + \tabu@thebody ={#1\tabu@aftergroupcleanup}% + \tabu@thebody =\expandafter{\the\expandafter\tabu@thebody + \@preamble}% + \edef\tabuthepreamble {\the\tabu@thebody}% ( no @ allowed for \scantokens ) + \tabu@select +}% \tabu@pream +\long\def\tabu@longpream #1\LT@bchunk #2\LT@bchunk{% + \let\tabu@ \tabu@@ \tabu@mkpreambuffer \tabu@aftergroupcleanup + \NC@list\expandafter {\tabu@NC@list}% in case of nesting... + \let\tabu@savedpreamble \@preamble + \global\let\tabu@elapsedtime \relax + \tabu@thebody ={#1\LT@bchunk #2\tabu@aftergroupcleanup \LT@bchunk}% + \edef\tabuthepreamble {\the\tabu@thebody}% ( no @ allowed for \scantokens ) + \tabu@select +}% \tabu@longpream +\def\tabu@select {% + \ifnum\tabu@nested>\z@ \tabuscantokensfalse \fi + \ifnum \count@=\@ne \iftabu@measuring \count@=\tw@ \fi\fi + \ifcase \count@ + \global\let\tabu@elapsedtime \relax + \tabu@seteverycr + \expandafter \tabuthepreamble % vertical adjustment (inherited from outer) + \or % exit in vertical measure + struts per cell because no X and outer in mode 3 + \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \tabu@seteverycr + \expandafter \tabuthepreamble + \or % exit without measure because no X and outer in mode 4 + \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty + \tabu@seteverycr + \expandafter \tabuthepreamble + \else % needs trials + \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty + \tabu@savecounters + \expandafter \tabu@setstrategy + \fi +}% \tabu@select +\def\tabu@@ {\gdef\tabu@mkpreambuffer} +%% Protections to set up before trials ------------------------------ +\def\tabu@setstrategy {\begingroup % + \tabu@trialh@@k \tabu@cnt \z@ % number of trials + \hbadness \@M \let\hbadness \@tempcnta + \hfuzz \maxdimen \let\hfuzz \@tempdima + \let\write \tabu@nowrite\let\GenericError \tabu@GenericError + \let\savetabu \@gobble \let\tabudefaulttarget \linewidth + \let\@footnotetext \@gobble \let\@xfootnote \tabu@xfootnote + \let\color \tabu@nocolor\let\rowcolor \tabu@norowcolor + \let\tabu@aftergroupcleanup \relax % only after the last trial + \tabu@mkpreambuffer + \ifnum \count@>\thr@@ \let\@halignto \@empty \tabucolX@init + \def\tabu@lasttry{\m@ne\p@}\fi + \begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}\iftabuscantokens \endlinechar=10 \obeyspaces \fi % + \tabu@collectbody \tabu@strategy % +}% \tabu@setstrategy +\def\tabu@savecounters{% + \def\@elt ##1{\csname c@##1\endcsname\the\csname c@##1\endcsname}% + \edef\tabu@clckpt {\begingroup \globaldefs=\@ne \cl@@ckpt \endgroup}\let\@elt \relax +}% \tabu@savecounters +\def\tabucolX@init {% \tabucolX <= \tabu@target / (sum coefs > 0) + \dimen@ \z@ \tabu@Xsum \z@ \tabucolX \z@ \let\tabu@ \tabu@Xinit \tabu@Xcoefs + \ifdim \dimen@>\z@ + \@tempdima \dimexpr \tabu@target *\p@/\dimen@ + \tabu@hfuzz\relax + \ifdim \tabucolX<\@tempdima \tabucolX \@tempdima \fi + \fi +}% \tabucolX@init +\def\tabu@Xinit #1#2{\tabu@Xcol #1 \advance \tabu@Xsum + \ifdim #2\p@>\z@ #2\p@ \advance\dimen@ #2\p@ + \else -#2\p@ \tabu@negcoeftrue + \@tempdima \dimexpr \tabu@target*\p@/\dimexpr-#2\p@\relax \relax + \ifdim \tabucolX<\@tempdima \tabucolX \@tempdima \fi + \tabu@wddef{#1}{0pt}% + \fi +}% \tabu@Xinit +%% Collecting the environment body ---------------------------------- +\long\def\tabu@collectbody #1#2\end #3{% + \edef\tabu@stack{\tabu@pushbegins #2\begin\end\expandafter\@gobble\tabu@stack}% + \ifx \tabu@stack\@empty + \toks@\expandafter{\expandafter\tabu@thebody\expandafter{\the\toks@ #2}% + \def\tabu@end@envir{\end{#3}}% + \iftabuscantokens + \iftabu@long \def\tabu@endenvir {\end{#3}\tabu@gobbleX}% + \else \def\tabu@endenvir {\let\endarray \@empty + \end{#3}\tabu@gobbleX}% + \fi + \else \def\tabu@endenvir {\end{#3}}\fi}% + \let\tabu@collectbody \tabu@endofcollect + \else\def\tabu@temp{#3}% + \ifx \tabu@temp\@empty \toks@\expandafter{\the\toks@ #2\end }% + \else \ifx\tabu@temp\tabu@@spxiii \toks@\expandafter{\the\toks@ #2\end #3}% + \else \ifx\tabu@temp\tabu@X \toks@\expandafter{\the\toks@ #2\end #3}% + \else \toks@\expandafter{\the\toks@ #2\end{#3}}% + \fi\fi\fi + \fi + \tabu@collectbody{#1}% +}% \tabu@collectbody +\long\def\tabu@pushbegins#1\begin#2{\ifx\end#2\else b\expandafter\tabu@pushbegins\fi}% +\def\tabu@endofcollect #1{\ifnum0=`{}\fi + \expandafter\endgroup \the\toks@ #1% +}% \tabu@endofcollect +%% The trials: switching between strategies ------------------------- +\def\tabu@strategy {\relax % stops \count@ assignment ! + \ifcase\count@ % case 0 = print with vertical adjustment (outer is finished) + \expandafter \tabu@endoftrials + \or % case 1 = exit in vertical measure (outer in mode 3) + \expandafter\xdef\csname tabu@\the\tabu@nested.T\endcsname{\the\tabu@target}% + \expandafter\xdef\csname tabu@\the\tabu@nested.X\endcsname{\the\tabucolX}% + \expandafter \tabu@endoftrials + \or % case 2 = exit with a rule replacing the table (outer in mode 4) + \expandafter \tabu@quickend + \or % case 3 = outer is in mode 3 because of no X + \begingroup + \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \expandafter \tabu@measuring + \else % case 4 = horizontal measure + \begingroup + \global\let\tabu@elapsedtime \tabu@message@etime + \long\def\multicolumn##1##2##3{\multispan{##1}}% + \let\tabu@startpboxORI \@startpbox + \iftabu@spread + \def\tabu@naturalXmax {\z@}% + \let\tabu@naturalXmin \tabu@naturalXmax + \tabu@evr{\global\tabu@naturalX \z@}% + \let\@startpbox \tabu@startpboxmeasure + \else\iftabu@negcoef + \let\@startpbox \tabu@startpboxmeasure + \else \let\@startpbox \tabu@startpboxquick + \fi\fi + \expandafter \tabu@measuring + \fi +}% \tabu@strategy +\def\tabu@measuring{\expandafter \tabu@trial \expandafter + \count@ \the\count@ \tabu@endtrial +}% \tabu@measuring +\def\tabu@trial{\iftabu@long \tabu@longtrial \else \tabu@shorttrial \fi} +\def\tabu@shorttrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr + \ifx \tabu@savecounters\relax \else + \let\tabu@savecounters \relax \tabu@clckpt \fi + $\iftabuscantokens \tabu@rescan \else \expandafter\@secondoftwo \fi + \expandafter{\expandafter \tabuthepreamble + \the\tabu@thebody + \csname tabu@adl@endtrial\endcsname + \endarray}$\egroup % got \tabu@box +}% \tabu@shorttrial +\def\tabu@longtrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr + \ifx \tabu@savecounters\relax \else + \let\tabu@savecounters \relax \tabu@clckpt \fi + \iftabuscantokens \tabu@rescan \else \expandafter\@secondoftwo \fi + \expandafter{\expandafter \tabuthepreamble + \the\tabu@thebody + \tabuendlongtrial}\egroup % got \tabu@box +}% \tabu@longtrial +\def\tabuendlongtrial{% no @ allowed for \scantokens + \LT@echunk \global\setbox\@ne \hbox{\unhbox\@ne}\kern\wd\@ne + \LT@get@widths +}% \tabuendlongtrial +\def\tabu@adl@endtrial{% + \crcr \noalign{\global\adl@ncol \tabu@nbcols}}% anything global is crap, junky and fails ! +\def\tabu@seteverycr {\tabu@reset + \everycr \expandafter{\the\everycr \tabu@everycr}% + \let\everycr \tabu@noeverycr % +}% \tabu@seteverycr +\def\tabu@noeverycr{{\aftergroup\tabu@restoreeverycr \afterassignment}\toks@} +\def\tabu@restoreeverycr {\let\everycr \tabu@@everycr} +\def\tabu@everycr {\iftabu@everyrow \noalign{\tabu@everyrow}\fi} +\def\tabu@endoftrials {% + \iftabuscantokens \expandafter\@firstoftwo + \else \expandafter\@secondoftwo + \fi + {\expandafter \tabu@closetrialsgroup \expandafter + \tabu@rescan \expandafter{% + \expandafter\tabuthepreamble + \the\expandafter\tabu@thebody + \iftabu@long \else \endarray \fi}} + {\expandafter\tabu@closetrialsgroup \expandafter + \tabuthepreamble + \the\tabu@thebody}% + \tabu@endenvir % Finish ! +}% \tabu@endoftrials +\def\tabu@closetrialsgroup {% + \toks@\expandafter{\tabu@endenvir}% + \edef\tabu@bufferX{\endgroup + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target + \tabu@cnt \the\tabu@cnt + \def\noexpand\tabu@endenvir{\the\toks@}% + %Quid de \@halignto = \tabu@halignto ?? + }% \tabu@bufferX + \tabu@bufferX + \ifcase\tabu@nested % print out (outer in mode 0) + \global\tabu@cnt \tabu@cnt + \tabu@evr{\tabu@verticaldynamicadjustment}% + \tabu@celllalign@def{\everypar{}}\let\tabu@cellralign \@empty + \let\@finalstrut \tabu@finalstrut + \else % vertical measure of nested tabu + \tabu@evr{\tabu@verticalinit}% + \tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \fi + \tabu@clckpt \let\@halignto \tabu@halignto + \let\@halignto \@empty + \tabu@seteverycr + \ifdim \tabustrutrule>\z@ \ifnum\tabu@nested=\z@ + \setbox\@arstrutbox \box\voidb@x % force \@arstrutbox to be rebuilt (visible struts) + \fi\fi +}% \tabu@closetrialsgroup +\def\tabu@quickend {\expandafter \endgroup \expandafter + \tabu@target \the\tabu@target \tabu@quickrule + \let\endarray \relax \tabu@endenvir +}% \tabu@quickend +\def\tabu@endtrial {\relax % stops \count@ assignment ! + \ifcase \count@ \tabu@err % case 0 = impossible here + \or \tabu@err % case 1 = impossible here + \or \tabu@err % case 2 = impossible here + \or % case 3 = outer goes into mode 0 + \def\tabu@bufferX{\endgroup}\count@ \z@ + \else % case 4 = outer goes into mode 3 + \iftabu@spread \tabu@spreadarith % inner into mode 1 (outer in mode 3) + \else \tabu@arith % or 2 (outer in mode 4) + \fi + \count@=% + \ifcase\tabu@nested \thr@@ % outer goes into mode 3 + \else\iftabu@measuring \tw@ % outer is in mode 4 + \else \@ne % outer is in mode 3 + \fi\fi + \edef\tabu@bufferX{\endgroup + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target}% + \fi + \expandafter \tabu@bufferX \expandafter + \count@ \the\count@ \tabu@strategy +}% \tabu@endtrial +\def\tabu@err{\errmessage{(tabu) Internal impossible error! (\count@=\the\count@)}} +%% The algorithms: compute the widths / stop or go on --------------- +\def\tabu@arithnegcoef {% + \@tempdima \z@ \dimen@ \z@ \let\tabu@ \tabu@arith@negcoef \tabu@Xcoefs +}% \tabu@arithnegcoef +\def\tabu@arith@negcoef #1#2{% + \ifdim #2\p@>\z@ \advance\dimen@ #2\p@ % saturated by definition + \advance\@tempdima #2\tabucolX + \else + \ifdim -#2\tabucolX <\tabu@wd{#1}% c_i X < natural width <= \tabu@target-> saturated + \advance\dimen@ -#2\p@ + \advance\@tempdima -#2\tabucolX + \else + \advance\@tempdima \tabu@wd{#1}% natural width <= c_i X => neutralised + \ifdim \tabu@wd{#1}<\tabu@target \else % neutralised + \advance\dimen@ -#2\p@ % saturated (natural width = tabu@target) + \fi + \fi + \fi +}% \tabu@arith@negcoef +\def\tabu@givespace #1#2{% here \tabu@DELTA < \z@ + \ifdim \@tempdima=\z@ + \tabu@wddef{#1}{\the\dimexpr -\tabu@DELTA*\p@/\tabu@Xsum}% + \else + \tabu@wddef{#1}{\the\dimexpr \tabu@hsize{#1}{#2} + *(\p@ -\tabu@DELTA*\p@/\@tempdima)/\p@\relax}% + \fi +}% \tabu@givespace +\def\tabu@arith {\advance\tabu@cnt \@ne + \ifnum \tabu@cnt=\@ne \tabu@message{\tabu@titles}\fi + \tabu@arithnegcoef + \@tempdimb \dimexpr \wd\tabu@box -\@tempdima \relax % + \tabu@DELTA = \dimexpr \wd\tabu@box - \tabu@target \relax + \tabu@message{\tabu@message@arith}% + \ifdim \tabu@DELTA <\tabu@hfuzz + \ifdim \tabu@DELTA<\z@ % wd (tabu)<\tabu@target ? + \let\tabu@ \tabu@givespace \tabu@Xcoefs + \advance\@tempdima \@tempdimb \advance\@tempdima -\tabu@DELTA % for message + \else % already converged: nothing to do but nearly impossible... + \fi + \tabucolX \maxdimen + \tabu@measuringfalse + \else % need for narrower X columns + \tabucolX =\dimexpr (\@tempdima -\tabu@DELTA) *\p@/\tabu@Xsum \relax + \tabu@measuringtrue + \@whilesw \iftabu@measuring\fi {% + \advance\tabu@cnt \@ne + \tabu@arithnegcoef + \tabu@DELTA =\dimexpr \@tempdima+\@tempdimb -\tabu@target \relax % always < 0 here + \tabu@message{\tabu@header + \tabu@msgalign \tabucolX { }{ }{ }{ }{ }\@@ + \tabu@msgalign \@tempdima+\@tempdimb { }{ }{ }{ }{ }\@@ + \tabu@msgalign \tabu@target { }{ }{ }{ }{ }\@@ + \tabu@msgalign@PT \dimen@ { }{}{}{}{}{}{}\@@ + \ifdim -\tabu@DELTA<\tabu@hfuzz \tabu@spaces target ok\else + \tabu@msgalign \dimexpr -\tabu@DELTA *\p@/\dimen@ {}{}{}{}{}\@@ + \fi}% + \ifdim -\tabu@DELTA<\tabu@hfuzz + \advance\@tempdima \@tempdimb % for message + \tabu@measuringfalse + \else + \advance\tabucolX \dimexpr -\tabu@DELTA *\p@/\dimen@ \relax + \fi + }% + \fi + \tabu@message{\tabu@message@reached}% + \edef\tabu@bufferX{\endgroup \tabu@cnt \the\tabu@cnt + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target}% +}% \tabu@arith +\def\tabu@spreadarith {% + \dimen@ \z@ \@tempdima \tabu@naturalXmax \let\tabu@ \tabu@spread@arith \tabu@Xcoefs + \edef\tabu@naturalXmin {\the\dimexpr\tabu@naturalXmin*\dimen@/\p@}% + \@tempdimc =\dimexpr \wd\tabu@box -\tabu@naturalXmax+\tabu@naturalXmin \relax + \iftabu@measuring + \tabu@target =\dimexpr \@tempdimc+\tabu@spreadtarget \relax + \edef\tabu@bufferX{\endgroup \tabucolX \the\tabucolX \tabu@target\the\tabu@target}% + \else + \tabu@message{\tabu@message@spreadarith}% + \ifdim \dimexpr \@tempdimc+\tabu@spreadtarget >\tabu@target + \tabu@message{(tabu) spread + \ifdim \@tempdimc>\tabu@target useless here: default target used% + \else too large: reduced to fit default target\fi.}% + \else + \tabu@target =\dimexpr \@tempdimc+\tabu@spreadtarget \relax + \tabu@message{(tabu) spread: New target set to \the\tabu@target^^J}% + \fi + \begingroup \let\tabu@wddef \@gobbletwo + \@tempdimb \@tempdima + \tabucolX@init + \tabu@arithnegcoef + \wd\tabu@box =\dimexpr \wd\tabu@box +\@tempdima-\@tempdimb \relax + \expandafter\endgroup \expandafter\tabucolX \the\tabucolX + \tabu@arith + \fi +}% \tabu@spreadarith +\def\tabu@spread@arith #1#2{% + \ifdim #2\p@>\z@ \advance\dimen@ #2\p@ + \else \advance\@tempdima \tabu@wd{#1}\relax + \fi +}% \tabu@spread@arith +%% Reporting in the .log file --------------------------------------- +\def\tabu@message@defaulttarget{% + \ifnum\tabu@nested=\z@^^J(tabu) Default target: + \ifx\tabudefaulttarget\linewidth \string\linewidth + \ifdim \tabu@thetarget=\linewidth \else + -\the\dimexpr\linewidth-\tabu@thetarget\fi = + \else\ifx\tabudefaulttarget\linegoal\string\linegoal= + \fi\fi + \else (tabu) Default target (nested): \fi + \the\tabu@target \on@line + \ifnum\tabu@nested=\z@ , page \the\c@page\fi} +\def\tabu@message@target {^^J(tabu) Target specified: + \the\tabu@target \on@line, page \the\c@page} +\def\tabu@message@arith {\tabu@header + \tabu@msgalign \tabucolX { }{ }{ }{ }{ }\@@ + \tabu@msgalign \wd\tabu@box { }{ }{ }{ }{ }\@@ + \tabu@msgalign \tabu@target { }{ }{ }{ }{ }\@@ + \tabu@msgalign@PT \dimen@ { }{}{}{}{}{}{}\@@ + \ifdim \tabu@DELTA<\tabu@hfuzz giving space\else + \tabu@msgalign \dimexpr (\@tempdima-\tabu@DELTA) *\p@/\tabu@Xsum -\tabucolX {}{}{}{}{}\@@ + \fi +}% \tabu@message@arith +\def\tabu@message@spreadarith {\tabu@spreadheader + \tabu@msgalign \tabu@spreadtarget { }{ }{ }{ }{}\@@ + \tabu@msgalign \wd\tabu@box { }{ }{ }{ }{}\@@ + \tabu@msgalign -\tabu@naturalXmax { }{}{}{}{}\@@ + \tabu@msgalign \tabu@naturalXmin { }{ }{ }{ }{}\@@ + \tabu@msgalign \ifdim \dimexpr\@tempdimc>\tabu@target \tabu@target + \else \@tempdimc+\tabu@spreadtarget \fi + {}{}{}{}{}\@@} +\def\tabu@message@negcoef #1#2{ + \tabu@spaces\tabu@spaces\space * #1. X[\rem@pt#2]: + \space width = \tabu@wd {#1} + \expandafter\string\csname tabu@\the\tabu@nested.W\number#1\endcsname + \ifdim -\tabu@pt#2\tabucolX<\tabu@target + < \number-\rem@pt#2 X + = \the\dimexpr -\tabu@pt#2\tabucolX \relax + \else + <= \the\tabu@target\space < \number-\rem@pt#2 X\fi} +\def\tabu@message@reached{\tabu@header + ******* Reached Target: + hfuzz = \tabu@hfuzz\on@line\space *******} +\def\tabu@message@etime{\edef\tabu@stoptime{\the\pdfelapsedtime}% + \tabu@message{(tabu)\tabu@spaces Time elapsed during measure: + \the\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax sec + \the\numexpr\numexpr(\tabu@stoptime-\tabu@starttime) + -\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax*65536\relax + *1000/65536\relax ms \tabu@spaces(\the\tabu@cnt\space + cycle\ifnum\tabu@cnt>\@ne s\fi)^^J^^J}} +\def\tabu@message@verticalsp {% + \ifdim \@tempdima>\tabu@ht + \ifdim \@tempdimb>\tabu@dp + \expandafter\expandafter\expandafter\string\tabu@ht = + \tabu@msgalign \@tempdima { }{ }{ }{ }{ }\@@ + \expandafter\expandafter\expandafter\string\tabu@dp = + \tabu@msgalign \@tempdimb { }{ }{ }{ }{ }\@@^^J% + \else + \expandafter\expandafter\expandafter\string\tabu@ht = + \tabu@msgalign \@tempdima { }{ }{ }{ }{ }\@@^^J% + \fi + \else\ifdim \@tempdimb>\tabu@dp + \tabu@spaces\tabu@spaces\tabu@spaces + \expandafter\expandafter\expandafter\string\tabu@dp = + \tabu@msgalign \@tempdimb { }{ }{ }{ }{ }\@@^^J\fi + \fi +}% \tabu@message@verticalsp +\edef\tabu@spaces{\@spaces} +\def\tabu@strippt{\expandafter\tabu@pt\the} +{\@makeother\P \@makeother\T\lowercase{\gdef\tabu@pt #1PT{#1}}} +\def\tabu@msgalign{\expandafter\tabu@msg@align\the\dimexpr} +\def\tabu@msgalign@PT{\expandafter\tabu@msg@align\romannumeral-`\0\tabu@strippt} +\def\do #1{% + \def\tabu@msg@align##1.##2##3##4##5##6##7##8##9\@@{% + \ifnum##1<10 #1 #1\else + \ifnum##1<100 #1 \else + \ifnum##1<\@m #1\fi\fi\fi + ##1.##2##3##4##5##6##7##8#1}% + \def\tabu@header{(tabu) \ifnum\tabu@cnt<10 #1\fi\the\tabu@cnt) }% + \def\tabu@titles{\ifnum \tabu@nested=\z@ + (tabu) Try#1 #1 tabu X #1 #1 #1tabu Width #1 #1 Target + #1 #1 #1 Coefs #1 #1 #1 Update^^J\fi}% + \def\tabu@spreadheader{% + (tabu) Try#1 #1 Spread #1 #1 tabu Width #1 #1 #1 Nat. X #1 #1 #1 #1Nat. Min. + #1 New Target^^J% + (tabu) sprd} + \def\tabu@message@save {\begingroup + \def\x ####1{\tabu@msg@align ####1{ }{ }{ }{ }{}\@@} + \def\z ####1{\expandafter\x\expandafter{\romannumeral-`\0\tabu@strippt + \dimexpr####1\p@{ }{ }}}% + \let\color \relax \def\tabu@rulesstyle ####1####2{\detokenize{####1}}% + \let\CT@arc@ \relax \let\@preamble \@gobble + \let\tabu@savedpream \@firstofone + \let\tabu@savedparams \@firstofone + \def\tabu@target ####1\relax {(tabu) target #1 #1 #1 #1 #1 = \x{####1}^^J}% + \def\tabucolX ####1\relax {(tabu) X columns width#1 = \x{####1}^^J}% + \def\tabu@nbcols ####1\relax {(tabu) Number of columns: \z{####1}^^J}% + \def\tabu@aligndefault ####1{(tabu) Default alignment: #1 #1 ####1^^J}% + \def\col@sep ####1\relax {(tabu) column sep #1 #1 #1 = \x{####1}^^J}% + \def\arrayrulewidth ####1\relax{(tabu) arrayrulewidth #1 = \x{####1}}% + \def\doublerulesep ####1\relax { doublerulesep = \x{####1}^^J}% + \def\extratabsurround####1\relax{(tabu) extratabsurround = \x{####1}^^J}% + \def\extrarowheight ####1\relax{(tabu) extrarowheight #1 = \x{####1}}% + \def\extrarowdepth ####1\relax {extrarowdepth = \x{####1}^^J}% + \def\abovetabulinesep####1\relax{(tabu) abovetabulinesep=\x{####1} }% + \def\belowtabulinesep####1\relax{ belowtabulinesep=\x{####1}^^J}% + \def\arraystretch ####1{(tabu) arraystretch #1 #1 = \z{####1}^^J}% + \def\minrowclearance####1\relax{(tabu) minrowclearance #1 = \x{####1}^^J}% + \def\tabu@arc@L ####1{(tabu) taburulecolor #1 #1 = ####1^^J}% + \def\tabu@drsc@L ####1{(tabu) tabudoublerulecolor= ####1^^J}% + \def\tabu@evr@L ####1{(tabu) everyrow #1 #1 #1 #1 = \detokenize{####1}^^J}% + \def\tabu@ls@L ####1{(tabu) line style = \detokenize{####1}^^J}% + \def\NC@find ####1\@nil{(tabu) tabu preamble#1 #1 = \detokenize{####1}^^J}% + \def\tabu@wddef####1####2{(tabu) Natural width ####1 = \x{####2}^^J}% + \let\edef \@gobbletwo \let\def \@empty \let\let \@gobbletwo + \tabu@message{% + (tabu) \string\savetabu{\tabu@temp}: \on@line^^J% + \tabu@usetabu \@nil^^J}% + \endgroup} +}\do{ } +%% Measuring the natural width (varwidth) - store the results ------- +\def\tabu@startpboxmeasure #1{\bgroup % entering \vtop + \edef\tabu@temp{\expandafter\@secondoftwo \ifx\tabu@hsize #1\else\relax\fi}% + \ifodd 1\ifx \tabu@temp\@empty 0 \else % starts with \tabu@hsize ? + \iftabu@spread \else % if spread -> measure + \ifdim \tabu@temp\p@>\z@ 0 \fi\fi\fi% if coef>0 -> do not measure + \let\@startpbox \tabu@startpboxORI % restore immediately (nesting) + \tabu@measuringtrue % for the quick option... + \tabu@Xcol =\expandafter\@firstoftwo\ifx\tabu@hsize #1\fi + \ifdim \tabu@temp\p@>\z@ \ifdim \tabu@temp\tabucolX<\tabu@target + \tabu@target=\tabu@temp\tabucolX \fi\fi + \setbox\tabu@box \hbox \bgroup + \begin{varwidth}\tabu@target + \let\FV@ListProcessLine \tabu@FV@ListProcessLine % \hbox to natural width... + \narrowragged \arraybackslash \parfillskip \@flushglue + \ifdefined\pdfadjustspacing \pdfadjustspacing\z@ \fi + \bgroup \aftergroup\tabu@endpboxmeasure + \ifdefined \cellspacetoplimit \tabu@cellspacepatch \fi + \else \expandafter\@gobble + \tabu@startpboxquick{#1}% \@gobble \bgroup + \fi +}% \tabu@startpboxmeasure +\def\tabu@cellspacepatch{\def\bcolumn##1\@nil{}\let\ecolumn\@empty + \bgroup\color@begingroup} +\def\tabu@endpboxmeasure {% + \@finalstrut \@arstrutbox + \end{varwidth}\egroup % + \ifdim \tabu@temp\p@ <\z@ % neg coef + \ifdim \tabu@wd\tabu@Xcol <\wd\tabu@box + \tabu@wddef\tabu@Xcol {\the\wd\tabu@box}% + \tabu@debug{\tabu@message@endpboxmeasure}% + \fi + \else % spread coef>0 + \global\advance \tabu@naturalX \wd\tabu@box + \@tempdima =\dimexpr \wd\tabu@box *\p@/\dimexpr \tabu@temp\p@\relax \relax + \ifdim \tabu@naturalXmax <\tabu@naturalX + \xdef\tabu@naturalXmax {\the\tabu@naturalX}\fi + \ifdim \tabu@naturalXmin <\@tempdima + \xdef\tabu@naturalXmin {\the\@tempdima}\fi + \fi + \box\tabu@box \egroup % end of \vtop (measure) restore \tabu@target +}% \tabu@endpboxmeasure +\def\tabu@wddef #1{\expandafter\xdef + \csname tabu@\the\tabu@nested.W\number#1\endcsname} +\def\tabu@wd #1{\csname tabu@\the\tabu@nested.W\number#1\endcsname} +\def\tabu@message@endpboxmeasure{\tabu@spaces\tabu@spaces<-> % <-> save natural wd + \the\tabu@Xcol. X[\tabu@temp]: + target = \the\tabucolX \space + \expandafter\expandafter\expandafter\string\tabu@wd\tabu@Xcol + =\tabu@wd\tabu@Xcol +}% \tabu@message@endpboxmeasure +\def\tabu@startpboxquick {\bgroup + \let\@startpbox \tabu@startpboxORI % restore immediately + \let\tabu \tabu@quick % \begin is expanded before... + \expandafter\@gobble \@startpbox % gobbles \bgroup +}% \tabu@startpboxquick +\def\tabu@quick {\begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}\tabu@collectbody \tabu@endquick +}% \tabu@quick +\def\tabu@endquick {% + \ifodd 1\ifx\tabu@end@envir\tabu@endtabu \else + \ifx\tabu@end@envir\tabu@endtabus \else 0\fi\fi\relax + \endgroup + \else \let\endtabu \relax + \tabu@end@envir + \fi +}% \tabu@quick +\def\tabu@endtabu {\end{tabu}} +\def\tabu@endtabus {\end{tabu*}} +%% Measuring the heights and depths - store the results ------------- +\def\tabu@verticalmeasure{\everypar{}% + \ifnum \currentgrouptype>12 % 14=semi-simple, 15=math shift group + \setbox\tabu@box =\hbox\bgroup + \let\tabu@verticalspacing \tabu@verticalsp@lcr + \d@llarbegin % after \hbox ... + \else + \edef\tabu@temp{\ifnum\currentgrouptype=5\vtop + \else\ifnum\currentgrouptype=12\vcenter + \else\vbox\fi\fi}% + \setbox\tabu@box \hbox\bgroup$\tabu@temp \bgroup + \let\tabu@verticalspacing \tabu@verticalsp@pmb + \fi +}% \tabu@verticalmeasure +\def\tabu@verticalsp@lcr{% + \d@llarend \egroup % + \@tempdima \dimexpr \ht\tabu@box+\abovetabulinesep + \@tempdimb \dimexpr \dp\tabu@box+\belowtabulinesep \relax + \ifdim\tabustrutrule>\z@ \tabu@debug{\tabu@message@verticalsp}\fi + \ifdim \tabu@ht<\@tempdima \tabu@htdef{\the\@tempdima}\fi + \ifdim \tabu@dp<\@tempdimb \tabu@dpdef{\the\@tempdimb}\fi + \noindent\vrule height\@tempdima depth\@tempdimb +}% \tabu@verticalsp@lcr +\def\tabu@verticalsp@pmb{% inserts struts as needed + \par \expandafter\egroup + \expandafter$\expandafter + \egroup \expandafter + \@tempdimc \the\prevdepth + \@tempdima \dimexpr \ht\tabu@box+\abovetabulinesep + \@tempdimb \dimexpr \dp\tabu@box+\belowtabulinesep \relax + \ifdim\tabustrutrule>\z@ \tabu@debug{\tabu@message@verticalsp}\fi + \ifdim \tabu@ht<\@tempdima \tabu@htdef{\the\@tempdima}\fi + \ifdim \tabu@dp<\@tempdimb \tabu@dpdef{\the\@tempdimb}\fi + \let\@finalstrut \@gobble + \hrule height\@tempdima depth\@tempdimb width\hsize +%% \box\tabu@box +}% \tabu@verticalsp@pmb + +\def\tabu@verticalinit{% + \ifnum \c@taburow=\z@ \tabu@rearstrut \fi % after \tabu@reset ! + \advance\c@taburow \@ne + \tabu@htdef{\the\ht\@arstrutbox}\tabu@dpdef{\the\dp\@arstrutbox}% + \advance\c@taburow \m@ne +}% \tabu@verticalinit +\def\tabu@htdef {\expandafter\xdef \csname tabu@\the\tabu@nested.H\the\c@taburow\endcsname} +\def\tabu@ht {\csname tabu@\the\tabu@nested.H\the\c@taburow\endcsname} +\def\tabu@dpdef {\expandafter\xdef \csname tabu@\the\tabu@nested.D\the\c@taburow\endcsname} +\def\tabu@dp {\csname tabu@\the\tabu@nested.D\the\c@taburow\endcsname} +\def\tabu@verticaldynamicadjustment {% + \advance\c@taburow \@ne + \extrarowheight \dimexpr\tabu@ht - \ht\strutbox + \extrarowdepth \dimexpr\tabu@dp - \dp\strutbox + \let\arraystretch \@empty + \advance\c@taburow \m@ne +}% \tabu@verticaldynamicadjustment +\def\tabuphantomline{\crcr \noalign{% + {\globaldefs \@ne + \setbox\@arstrutbox \box\voidb@x + \let\tabu@@celllalign \tabu@celllalign + \let\tabu@@cellralign \tabu@cellralign + \let\tabu@@cellleft \tabu@cellleft + \let\tabu@@cellright \tabu@cellright + \let\tabu@@thevline \tabu@thevline + \let\tabu@celllalign \@empty + \let\tabu@cellralign \@empty + \let\tabu@cellright \@empty + \let\tabu@cellleft \@empty + \let\tabu@thevline \relax}% + \edef\tabu@temp{\tabu@multispan \tabu@nbcols{\noindent &}}% + \toks@\expandafter{\tabu@temp \noindent\tabu@everyrowfalse \cr + \noalign{\tabu@rearstrut + {\globaldefs\@ne + \let\tabu@celllalign \tabu@@celllalign + \let\tabu@cellralign \tabu@@cellralign + \let\tabu@cellleft \tabu@@cellleft + \let\tabu@cellright \tabu@@cellright + \let\tabu@thevline \tabu@@thevline}}}% + \expandafter}\the\toks@ +}% \tabuphantomline +%% \firsthline and \lasthline corrections --------------------------- +\def\tabu@firstline {\tabu@hlineAZ \tabu@firsthlinecorrection {}} +\def\tabu@firsthline{\tabu@hlineAZ \tabu@firsthlinecorrection \hline} +\def\tabu@lastline {\tabu@hlineAZ \tabu@lasthlinecorrection {}} +\def\tabu@lasthline {\tabu@hlineAZ \tabu@lasthlinecorrection \hline} +\def\tabu@hline {% replaces \hline if no colortbl (see \AtBeginDocument) + \noalign{\ifnum0=`}\fi + {\CT@arc@\hrule height\arrayrulewidth}% + \futurelet \tabu@temp \tabu@xhline +}% \tabu@hline +\def\tabu@xhline{% + \ifx \tabu@temp \hline + {\ifx \CT@drsc@\relax \vskip + \else\ifx \CT@drsc@\@empty \vskip + \else \CT@drsc@\hrule height + \fi\fi + \doublerulesep}% + \fi + \ifnum0=`{\fi}% +}% \tabu@xhline +\def\tabu@hlineAZ #1#2{\noalign{\ifnum0=`}\fi \dimen@ \z@ \count@ \z@ + \toks@{}\def\tabu@hlinecorrection{#1}\def\tabu@temp{#2}% + \tabu@hlineAZsurround +}% \tabu@hlineAZ +\newcommand*\tabu@hlineAZsurround[1][\extratabsurround]{% + \extratabsurround #1\let\tabucline \tabucline@scan + \let\hline \tabu@hlinescan \let\firsthline \hline + \let\cline \tabu@clinescan \let\lasthline \hline + \expandafter \futurelet \expandafter \tabu@temp + \expandafter \tabu@nexthlineAZ \tabu@temp +}% \tabu@hlineAZsurround +\def\tabu@hlinescan {\tabu@thick \arrayrulewidth \tabu@xhlineAZ \hline} +\def\tabu@clinescan #1{\tabu@thick \arrayrulewidth \tabu@xhlineAZ {\cline{#1}}} +\def\tabucline@scan{\@testopt \tabucline@sc@n {}} +\def\tabucline@sc@n #1[#2]{\tabu@xhlineAZ {\tabucline[{#1}]{#2}}} +\def\tabu@nexthlineAZ{% + \ifx \tabu@temp\hline \else + \ifx \tabu@temp\cline \else + \ifx \tabu@temp\tabucline \else + \tabu@hlinecorrection + \fi\fi\fi +}% \tabu@nexthlineAZ +\def\tabu@xhlineAZ #1{% + \toks@\expandafter{\the\toks@ #1}% + \@tempdimc \tabu@thick % The last line width + \ifcase\count@ \@tempdimb \tabu@thick % The first line width + \else \advance\dimen@ \dimexpr \tabu@thick+\doublerulesep \relax + \fi + \advance\count@ \@ne \futurelet \tabu@temp \tabu@nexthlineAZ +}% \tabu@xhlineAZ +\def\tabu@firsthlinecorrection{% \count@ = number of \hline -1 + \@tempdima \dimexpr \ht\@arstrutbox+\dimen@ + \edef\firsthline{% + \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule + height \the\dimexpr\@tempdima+\extratabsurround + depth \dp\@arstrutbox + width \tabustrutrule}\hss}\cr + \noalign{\vskip -\the\dimexpr \@tempdima+\@tempdimb + +\dp\@arstrutbox \relax}% + \the\toks@ + }\ifnum0=`{\fi + \expandafter}\firsthline % we are then ! +}% \tabu@firsthlinecorrection +\def\tabu@lasthlinecorrection{% + \@tempdima \dimexpr \dp\@arstrutbox+\dimen@+\@tempdimb+\@tempdimc + \edef\lasthline{% + \the\toks@ + \noalign{\vskip -\the\dimexpr\dimen@+\@tempdimb+\dp\@arstrutbox}% + \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule + depth \the\dimexpr \dp\@arstrutbox+\@tempdimb+\dimen@ + +\extratabsurround-\@tempdimc + height \z@ + width \tabustrutrule}\hss}\cr + }\ifnum0=`{\fi + \expandafter}\lasthline % we are then ! +}% \tabu@lasthlinecorrection +\def\tabu@LT@@hline{% + \ifx\LT@next\hline + \global\let\LT@next \@gobble + \ifx \CT@drsc@\relax + \gdef\CT@LT@sep{% + \noalign{\penalty-\@medpenalty\vskip\doublerulesep}}% + \else + \gdef\CT@LT@sep{% + \multispan\LT@cols{% + \CT@drsc@\leaders\hrule\@height\doublerulesep\hfill}\cr}% + \fi + \else + \global\let\LT@next\empty + \gdef\CT@LT@sep{% + \noalign{\penalty-\@lowpenalty\vskip-\arrayrulewidth}}% + \fi + \ifnum0=`{\fi}% + \multispan\LT@cols + {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr + \CT@LT@sep + \multispan\LT@cols + {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr + \noalign{\penalty\@M}% + \LT@next +}% \tabu@LT@@hline +%% Horizontal lines : \tabucline ------------------------------------ +\let\tabu@start \@tempcnta +\let\tabu@stop \@tempcntb +\newcommand*\tabucline{\noalign{\ifnum0=`}\fi \tabu@cline} +\newcommand*\tabu@cline[2][]{\tabu@startstop{#2}% + \ifnum \tabu@stop<\z@ \toks@{}% + \else \tabu@clinearg{#1}\tabu@thestyle + \edef\tabucline{\toks@{% + \ifnum \tabu@start>\z@ \omit + \tabu@multispan\tabu@start {\span\omit}&\fi + \omit \tabu@multispan\tabu@stop {\span\omit}% + \tabu@thehline\cr + }}\tabucline + \tabu@tracinglines{(tabu:tabucline) Style: #1^^J\the\toks@^^J^^J}% + \fi + \futurelet \tabu@temp \tabu@xcline +}% \tabu@cline +\def\tabu@clinearg #1{% + \ifx\\#1\\\let\tabu@thestyle \tabu@ls@ + \else \@defaultunits \expandafter\let\expandafter\@tempa + \romannumeral-`\0#1\relax \@nnil + \ifx \hbox\@tempa \tabu@clinebox{#1}% + \else\ifx \box\@tempa \tabu@clinebox{#1}% + \else\ifx \vbox\@tempa \tabu@clinebox{#1}% + \else\ifx \vtop\@tempa \tabu@clinebox{#1}% + \else\ifx \copy\@tempa \tabu@clinebox{#1}% + \else\ifx \leaders\@tempa \tabu@clineleads{#1}% + \else\ifx \cleaders\@tempa \tabu@clineleads{#1}% + \else\ifx \xleaders\@tempa \tabu@clineleads{#1}% + \else\tabu@getline {#1}% + \fi\fi\fi\fi\fi\fi\fi\fi + \fi +}% \tabu@clinearg +\def\tabu@clinebox #1{\tabu@clineleads{\xleaders#1\hss}} +\def\tabu@clineleads #1{% + \let\tabu@thestyle \relax \let\tabu@leaders \@undefined + \gdef\tabu@thehrule{#1}} +\def\tabu@thehline{\begingroup + \ifdefined\tabu@leaders + \noexpand\tabu@thehleaders + \else \noexpand\tabu@thehrule + \fi \endgroup +}% \tabu@thehline +\def\tabu@xcline{% + \ifx \tabu@temp\tabucline + \toks@\expandafter{\the\toks@ \noalign + {\ifx\CT@drsc@\relax \vskip + \else \CT@drsc@\hrule height + \fi + \doublerulesep}}% + \fi + \tabu@docline +}% \tabu@xcline +\def\tabu@docline {\ifnum0=`{\fi \expandafter}\the\toks@} +\def\tabu@docline@evr {\xdef\tabu@doclineafter{\the\toks@}% + \ifnum0=`{\fi}\aftergroup\tabu@doclineafter} +\def\tabu@multispan #1#2{% + \ifnum\numexpr#1>\@ne #2\expandafter\tabu@multispan + \else \expandafter\@gobbletwo + \fi {#1-1}{#2}% +}% \tabu@multispan +\def\tabu@startstop #1{\tabu@start@stop #1\relax 1-\tabu@nbcols \@nnil} +\def\tabu@start@stop #1-#2\@nnil{% + \@defaultunits \tabu@start\number 0#1\relax \@nnil + \@defaultunits \tabu@stop \number 0#2\relax \@nnil + \tabu@stop \ifnum \tabu@start>\tabu@nbcols \m@ne + \else\ifnum \tabu@stop=\z@ \tabu@nbcols + \else\ifnum \tabu@stop>\tabu@nbcols \tabu@nbcols + \else \tabu@stop + \fi\fi\fi + \advance\tabu@start \m@ne + \ifnum \tabu@start>\z@ \advance\tabu@stop -\tabu@start \fi +}% \tabu@start@stop +%% Numbers: siunitx S columns (and \tabudecimal) ------------------- +\def\tabu@tabudecimal #1{% + \def\tabu@decimal{#1}\@temptokena{}% + \let\tabu@getdecimal@ \tabu@getdecimal@ignorespaces + \tabu@scandecimal +}% \tabu@tabudecimal +\def\tabu@scandecimal{\futurelet \tabu@temp \tabu@getdecimal@} +\def\tabu@skipdecimal#1{#1\tabu@scandecimal} +\def\tabu@getdecimal@ignorespaces{% + \ifcase 0\ifx\tabu@temp\ignorespaces\else + \ifx\tabu@temp\@sptoken1\else + 2\fi\fi\relax + \let\tabu@getdecimal@ \tabu@getdecimal + \expandafter\tabu@skipdecimal + \or \expandafter\tabu@gobblespace\expandafter\tabu@scandecimal + \else \expandafter\tabu@skipdecimal + \fi +}% \tabu@getdecimal@ignorespaces +\def\tabu@get@decimal#1{\@temptokena\expandafter{\the\@temptokena #1}% + \tabu@scandecimal} +\def\do#1{% + \def\tabu@get@decimalspace#1{% + \@temptokena\expandafter{\the\@temptokena #1}\tabu@scandecimal}% +}\do{ } +\let\tabu@@tabudecimal \tabu@tabudecimal +\def\tabu@getdecimal{% + \ifcase 0\ifx 0\tabu@temp\else + \ifx 1\tabu@temp\else + \ifx 2\tabu@temp\else + \ifx 3\tabu@temp\else + \ifx 4\tabu@temp\else + \ifx 5\tabu@temp\else + \ifx 6\tabu@temp\else + \ifx 7\tabu@temp\else + \ifx 8\tabu@temp\else + \ifx 9\tabu@temp\else + \ifx .\tabu@temp\else + \ifx ,\tabu@temp\else + \ifx -\tabu@temp\else + \ifx +\tabu@temp\else + \ifx e\tabu@temp\else + \ifx E\tabu@temp\else + \ifx\tabu@cellleft\tabu@temp1\else + \ifx\ignorespaces\tabu@temp1\else + \ifx\@sptoken\tabu@temp2\else + 3\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax + \expandafter\tabu@get@decimal + \or \expandafter\tabu@skipdecimal + \or \expandafter\tabu@get@decimalspace + \else\expandafter\tabu@printdecimal + \fi +}% \tabu@getdecimal +\def\tabu@printdecimal{% + \edef\tabu@temp{\the\@temptokena}% + \ifx\tabu@temp\@empty\else + \ifx\tabu@temp\space\else + \expandafter\tabu@decimal\expandafter{\the\@temptokena}% + \fi\fi +}% \tabu@printdecimal +%% Verbatim inside X columns ---------------------------------------- +\def\tabu@verbatim{% + \let\verb \tabu@verb + \let\FV@DefineCheckEnd \tabu@FV@DefineCheckEnd +}% \tabu@verbatim +\let\tabu@ltx@verb \verb +\def\tabu@verb{\@ifstar {\tabu@ltx@verb*} \tabu@ltx@verb} +\def\tabu@fancyvrb {% + \def\tabu@FV@DefineCheckEnd ##1{% + \def\tabu@FV@DefineCheckEnd{% + ##1% + \let\FV@CheckEnd \tabu@FV@CheckEnd + \let\FV@@CheckEnd \tabu@FV@@CheckEnd + \let\FV@@@CheckEnd \tabu@FV@@@CheckEnd + \edef\FV@EndScanning{% + \def\noexpand\next{\noexpand\end{\FV@EnvironName}}% + \global\let\noexpand\FV@EnvironName\relax + \noexpand\next}% + \xdef\FV@EnvironName{\detokenize\expandafter{\FV@EnvironName}}}% + }\expandafter\tabu@FV@DefineCheckEnd\expandafter{\FV@DefineCheckEnd} +}% \tabu@fancyvrb +\def\tabu@FV@CheckEnd #1{\expandafter\FV@@CheckEnd \detokenize{#1\end{}}\@nil} +\edef\tabu@FV@@@CheckEnd {\detokenize{\end{}}} +\begingroup +\catcode`\[1 \catcode`\]2 +\@makeother\{ \@makeother\} + \edef\x[\endgroup + \def\noexpand\tabu@FV@@CheckEnd ##1\detokenize[\end{]##2\detokenize[}]##3% + ]\x \@nil{\def\@tempa{#2}\def\@tempb{#3}} +\def\tabu@FV@ListProcessLine #1{% + \hbox {%to \hsize{% + \kern\leftmargin + \hbox {%to \linewidth{% + \FV@LeftListNumber + \FV@LeftListFrame + \FancyVerbFormatLine{#1}\hss +%% DG/SR modification begin - Jan. 28, 1998 (for numbers=right add-on) +%% \FV@RightListFrame}% + \FV@RightListFrame + \FV@RightListNumber}% +%% DG/SR modification end + \hss}} +%% \savetabu -------------------------------------------------------- +\newcommand*\savetabu[1]{\noalign{% + \tabu@sanitizearg{#1}\tabu@temp + \ifx \tabu@temp\@empty \tabu@savewarn{}{The tabu will not be saved}\else + \@ifundefined{tabu@saved@\tabu@temp}{}{\tabu@savewarn{#1}{Overwriting}}% + \ifdefined\tabu@restored \expandafter\let + \csname tabu@saved@\tabu@temp \endcsname \tabu@restored + \else {\tabu@save}% + \fi + \fi}% +}% \savetabu +\def\tabu@save {% + \toks0\expandafter{\tabu@saved@}% + \iftabu@negcoef + \let\tabu@wddef \relax \let\tabu@ \tabu@savewd \edef\tabu@savewd{\tabu@Xcoefs}% + \toks0\expandafter{\the\toks\expandafter0\tabu@savewd}\fi + \toks1\expandafter{\tabu@savedpream}% + \toks2\expandafter{\tabu@savedpreamble}% + \let\@preamble \relax + \let\tabu@savedpream \relax \let\tabu@savedparams \relax + \edef\tabu@preamble{% + \def\noexpand\tabu@aligndefault{\tabu@align}% + \def\tabu@savedparams {\noexpand\the\toks0}% + \def\tabu@savedpream {\noexpand\the\toks1}}% + \edef\tabu@usetabu{% + \def\@preamble {\noexpand\the\toks2}% + \tabu@target \the\tabu@target \relax + \tabucolX \the\tabucolX \relax + \tabu@nbcols \the\tabu@nbcols \relax + \def\noexpand\tabu@aligndefault{\tabu@align}% + \def\tabu@savedparams {\noexpand\the\toks0}% + \def\tabu@savedpream {\noexpand\the\toks1}}% + \let\tabu@aligndefault \relax \let\@sharp \relax + \edef\@tempa{\noexpand\tabu@s@ved + {\tabu@usetabu} + {\tabu@preamble} + {\the\toks1}}\@tempa + \tabu@message@save +}% \tabu@save +\long\def\tabu@s@ved #1#2#3{% + \def\tabu@usetabu{#1}% + \expandafter\gdef\csname tabu@saved@\tabu@temp\endcsname ##1{% + \ifodd ##1% \usetabu + \tabu@measuringfalse \tabu@spreadfalse % Just in case... + \gdef\tabu@usetabu {% + \ifdim \tabu@target>\z@ \tabu@warn@usetabu \fi + \global\let\tabu@usetabu \@undefined + \def\@halignto {to\tabu@target}% + #1% + \ifx \tabu@align\tabu@aligndefault@text + \ifnum \tabu@nested=\z@ + \let\tabu@align \tabu@aligndefault \fi\fi}% + \else % \preamble + \gdef\tabu@preamble {% + \global\let\tabu@preamble \@undefined + #2% + \ifx \tabu@align\tabu@aligndefault@text + \ifnum \tabu@nested=\z@ + \let\tabu@align \tabu@aligndefault \fi\fi}% + \fi + #3}% +}% \tabu@s@ved +\def\tabu@aligndefault@text {\tabu@aligndefault}% +\def\tabu@warn@usetabu {\PackageWarning{tabu} + {Specifying a target with \string\usetabu\space is useless + \MessageBreak The target cannot be changed!}} +\def\tabu@savewd #1#2{\ifdim #2\p@<\z@ \tabu@wddef{#1}{\tabu@wd{#1}}\fi} +\def\tabu@savewarn#1#2{\PackageInfo{tabu} + {User-name `#1' already used for \string\savetabu + \MessageBreak #2}}% +\def\tabu@saveerr#1{\PackageError{tabu} + {User-name `#1' is unknown for \string\usetabu + \MessageBreak I cannot restore an unknown preamble!}\@ehd} +%% \rowfont --------------------------------------------------------- +\newskip \tabu@cellskip +\def\tabu@rowfont{\ifdim \baselineskip=\z@\noalign\fi + {\ifnum0=`}\fi \tabu@row@font} +\newcommand*\tabu@row@font[2][]{% + \ifnum7=\currentgrouptype + \global\let\tabu@@cellleft \tabu@cellleft + \global\let\tabu@@cellright \tabu@cellright + \global\let\tabu@@celllalign \tabu@celllalign + \global\let\tabu@@cellralign \tabu@cellralign + \global\let\tabu@@rowfontreset\tabu@rowfontreset + \fi + \global\let\tabu@rowfontreset \tabu@rowfont@reset + \expandafter\gdef\expandafter\tabu@cellleft\expandafter{\tabu@cellleft #2}% + \ifcsname tabu@cell@#1\endcsname % row alignment + \csname tabu@cell@#1\endcsname \fi + \ifnum0=`{\fi}% end of group / noalign group +}% \rowfont +\def\tabu@ifcolorleavevmode #1{\let\color \tabu@leavevmodecolor #1\let\color\tabu@color}% +\def\tabu@rowfont@reset{% + \global\let\tabu@rowfontreset \tabu@@rowfontreset + \global\let\tabu@cellleft \tabu@@cellleft + \global\let\tabu@cellright \tabu@@cellright + \global\let\tabu@cellfont \@empty + \global\let\tabu@celllalign \tabu@@celllalign + \global\let\tabu@cellralign \tabu@@cellralign +}% \tabu@@rowfontreset +\let\tabu@rowfontreset \@empty % overwritten \AtBeginDocument if colortbl +%% \tabu@prepnext@tok ----------------------------------------------- +\newif \iftabu@cellright +\def\tabu@prepnext@tok{% + \ifnum \count@<\z@ % + \@tempcnta \@M % + \tabu@nbcols\z@ + \let\tabu@fornoopORI \@fornoop + \tabu@cellrightfalse + \else + \ifcase \numexpr \count@-\@tempcnta \relax % (case 0): prev. token is left + \advance \tabu@nbcols \@ne + \iftabu@cellright % before-previous token is right and is finished + \tabu@cellrightfalse % + \tabu@righttok + \fi + \tabu@lefttok + \or % (case 1) previous token is right + \tabu@cellrighttrue \let\@fornoop \tabu@lastnoop + \else % special column: do not change the token + \iftabu@cellright % before-previous token is right + \tabu@cellrightfalse + \tabu@righttok + \fi + \fi % \ifcase + \fi + \tabu@prepnext@tokORI +}% \tabu@prepnext@tok +\long\def\tabu@lastnoop#1\@@#2#3{\tabu@lastn@@p #2\@nextchar \in@\in@@} +\def\tabu@lastn@@p #1\@nextchar #2#3\in@@{% + \ifx \in@#2\else + \let\@fornoop \tabu@fornoopORI + \xdef\tabu@mkpreambuffer{\tabu@nbcols\the\tabu@nbcols \tabu@mkpreambuffer}% + \toks0\expandafter{\expandafter\tabu@everyrowtrue \the\toks0}% + \expandafter\prepnext@tok + \fi +}% \tabu@lastnoop +\def\tabu@righttok{% + \advance \count@ \m@ne + \toks\count@\expandafter {\the\toks\count@ \tabu@cellright \tabu@cellralign}% + \advance \count@ \@ne +}% \tabu@righttok +\def\tabu@lefttok{\toks\count@\expandafter{\expandafter\tabu@celllalign + \the\toks\count@ \tabu@cellleft}% after because of $ +}% \tabu@lefttok +%% Neutralisation of glues ------------------------------------------ +\let\tabu@cellleft \@empty +\let\tabu@cellright \@empty +\tabu@celllalign@def{\tabu@cellleft}% +\let\tabu@cellralign \@empty +\def\tabu@cell@align #1#2#3{% + \let\tabu@maybesiunitx \toks@ \tabu@celllalign + \global \expandafter \tabu@celllalign@def \expandafter {\the\toks@ #1}% + \toks@\expandafter{\tabu@cellralign #2}% + \xdef\tabu@cellralign{\the\toks@}% + \toks@\expandafter{\tabu@cellleft #3}% + \xdef\tabu@cellleft{\the\toks@}% +}% \tabu@cell@align +\def\tabu@cell@l{% force alignment to left + \tabu@cell@align + {\tabu@removehfil \raggedright \tabu@cellleft}% left + {\tabu@flush1\tabu@ignorehfil}% right + \raggedright +}% \tabu@cell@l +\def\tabu@cell@c{% force alignment to center + \tabu@cell@align + {\tabu@removehfil \centering \tabu@flush{.5}\tabu@cellleft} + {\tabu@flush{.5}\tabu@ignorehfil} + \centering +}% \tabu@cell@c +\def\tabu@cell@r{% force alignment to right + \tabu@cell@align + {\tabu@removehfil \raggedleft \tabu@flush1\tabu@cellleft} + \tabu@ignorehfil + \raggedleft +}% \tabu@cell@r +\def\tabu@cell@j{% force justification (for p, m, b columns) + \tabu@cell@align + {\tabu@justify\tabu@cellleft} + {} + \tabu@justify +}% \tabu@cell@j +\def\tabu@justify{% + \leftskip\z@skip \@rightskip\leftskip \rightskip\@rightskip + \parfillskip\@flushglue +}% \tabu@justify +%% ragged2e settings +\def\tabu@cell@L{% force alignment to left (ragged2e) + \tabu@cell@align + {\tabu@removehfil \RaggedRight \tabu@cellleft} + {\tabu@flush 1\tabu@ignorehfil} + \RaggedRight +}% \tabu@cell@L +\def\tabu@cell@C{% force alignment to center (ragged2e) + \tabu@cell@align + {\tabu@removehfil \Centering \tabu@flush{.5}\tabu@cellleft} + {\tabu@flush{.5}\tabu@ignorehfil} + \Centering +}% \tabu@cell@C +\def\tabu@cell@R{% force alignment to right (ragged2e) + \tabu@cell@align + {\tabu@removehfil \RaggedLeft \tabu@flush 1\tabu@cellleft} + \tabu@ignorehfil + \RaggedLeft +}% \tabu@cell@R +\def\tabu@cell@J{% force justification (ragged2e) + \tabu@cell@align + {\justifying \tabu@cellleft} + {} + \justifying +}% \tabu@cell@J +\def\tabu@flush#1{% + \iftabu@colortbl % colortbl uses \hfill rather than \hfil + \hskip \ifnum13<\currentgrouptype \stretch{#1}% + \else \ifdim#1pt<\p@ \tabu@cellskip + \else \stretch{#1} + \fi\fi \relax + \else % array.sty + \ifnum 13<\currentgrouptype + \hfil \hskip1sp \relax \fi + \fi +}% \tabu@flush +\let\tabu@hfil \hfil +\let\tabu@hfill \hfill +\let\tabu@hskip \hskip +\def\tabu@removehfil{% + \iftabu@colortbl + \unkern \tabu@cellskip =\lastskip + \ifnum\gluestretchorder\tabu@cellskip =\tw@ \hskip-\tabu@cellskip + \else \tabu@cellskip \z@skip + \fi + \else + \ifdim\lastskip=1sp\unskip\fi + \ifnum\gluestretchorder\lastskip =\@ne + \hfilneg % \hfilneg for array.sty but not for colortbl... + \fi + \fi +}% \tabu@removehfil +\def\tabu@ignorehfil{\aftergroup \tabu@nohfil} +\def\tabu@nohfil{% \hfil -> do nothing + restore original \hfil + \def\hfil{\let\hfil \tabu@hfil}% local to (alignment template) group +}% \tabu@nohfil +\def\tabu@colortblalignments {% if colortbl + \def\tabu@nohfil{% + \def\hfil {\let\hfil \tabu@hfil}% local to (alignment template) group + \def\hfill {\let\hfill \tabu@hfill}% (colortbl uses \hfill) pfff... + \def\hskip ####1\relax{\let\hskip \tabu@hskip}}% local +}% \tabu@colortblalignments +%% Taking care of footnotes and hyperfootnotes ---------------------- +\long\def\tabu@footnotetext #1{% + \edef\@tempa{\the\tabu@footnotes + \noexpand\footnotetext [\the\csname c@\@mpfn\endcsname]}% + \global\tabu@footnotes\expandafter{\@tempa {#1}}}% +\long\def\tabu@xfootnotetext [#1]#2{% + \global\tabu@footnotes\expandafter{\the\tabu@footnotes + \footnotetext [{#1}]{#2}}} +\let\tabu@xfootnote \@xfootnote +\long\def\tabu@Hy@ftntext{\tabu@Hy@ftntxt {\the \c@footnote }} +\long\def\tabu@Hy@xfootnote [#1]{% + \begingroup + \value\@mpfn #1\relax + \protected@xdef \@thefnmark {\thempfn}% + \endgroup + \@footnotemark \tabu@Hy@ftntxt {#1}% +}% \tabu@Hy@xfootnote +\long\def\tabu@Hy@ftntxt #1#2{% + \edef\@tempa{% + \the\tabu@footnotes + \begingroup + \value\@mpfn #1\relax + \noexpand\protected@xdef\noexpand\@thefnmark {\noexpand\thempfn}% + \expandafter \noexpand \expandafter + \tabu@Hy@footnotetext \expandafter{\Hy@footnote@currentHref}% + }% + \global\tabu@footnotes\expandafter{\@tempa {#2}% + \endgroup}% +}% \tabu@Hy@ftntxt +\long\def\tabu@Hy@footnotetext #1#2{% + \H@@footnotetext{% + \ifHy@nesting + \hyper@@anchor {#1}{#2}% + \else + \Hy@raisedlink{% + \hyper@@anchor {#1}{\relax}% + }% + \def\@currentHref {#1}% + \let\@currentlabelname \@empty + #2% + \fi + }% +}% \tabu@Hy@footnotetext +%% No need for \arraybackslash ! ------------------------------------ +\def\tabu@latextwoe {% +\def\tabu@temp##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}} +\tabu@temp \tabu@centering \centering \arraybackslash +\tabu@temp \tabu@raggedleft \raggedleft \arraybackslash +\tabu@temp \tabu@raggedright \raggedright \arraybackslash +}% \tabu@latextwoe +\def\tabu@raggedtwoe {% +\def\tabu@temp ##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}} +\tabu@temp \tabu@Centering \Centering \arraybackslash +\tabu@temp \tabu@RaggedLeft \RaggedLeft \arraybackslash +\tabu@temp \tabu@RaggedRight \RaggedRight \arraybackslash +\tabu@temp \tabu@justifying \justifying \arraybackslash +}% \tabu@raggedtwoe +\def\tabu@normalcrbackslash{\let\\\@normalcr} +\def\tabu@trivlist{\expandafter\def\expandafter\@trivlist\expandafter{% + \expandafter\tabu@normalcrbackslash \@trivlist}} +%% Utilities: \fbox \fcolorbox and \tabudecimal ------------------- +\def\tabu@fbox {\leavevmode\afterassignment\tabu@beginfbox \setbox\@tempboxa\hbox} +\def\tabu@beginfbox {\bgroup \kern\fboxsep + \bgroup\aftergroup\tabu@endfbox} +\def\tabu@endfbox {\kern\fboxsep\egroup\egroup + \@frameb@x\relax} +\def\tabu@color@b@x #1#2{\leavevmode \bgroup + \def\tabu@docolor@b@x{#1{#2\color@block{\wd\z@}{\ht\z@}{\dp\z@}\box\z@}}% + \afterassignment\tabu@begincolor@b@x \setbox\z@ \hbox +}% \tabu@color@b@x +\def\tabu@begincolor@b@x {\kern\fboxsep \bgroup + \aftergroup\tabu@endcolor@b@x \set@color} +\def\tabu@endcolor@b@x {\kern\fboxsep \egroup + \dimen@\ht\z@ \advance\dimen@ \fboxsep \ht\z@ \dimen@ + \dimen@\dp\z@ \advance\dimen@ \fboxsep \dp\z@ \dimen@ + \tabu@docolor@b@x \egroup +}% \tabu@endcolor@b@x +%% Corrections (arydshln, delarray, colortbl) ----------------------- +\def\tabu@fix@arrayright {%% \@arrayright is missing from \endarray + \iftabu@colortbl + \ifdefined\adl@array % + \def\tabu@endarray{% + \adl@endarray \egroup \adl@arrayrestore \CT@end \egroup % + \@arrayright % + \gdef\@preamble{}}% + \else % + \def\tabu@endarray{% + \crcr \egroup \egroup % + \@arrayright % + \gdef\@preamble{}\CT@end}% + \fi + \else + \ifdefined\adl@array % + \def\tabu@endarray{% + \adl@endarray \egroup \adl@arrayrestore \egroup % + \@arrayright % + \gdef\@preamble{}}% + \else % + \PackageWarning{tabu} + {\string\@arrayright\space is missing from the + \MessageBreak definition of \string\endarray. + \MessageBreak Compatibility with delarray.sty is broken.}% + \fi\fi +}% \tabu@fix@arrayright +\def\tabu@adl@xarraydashrule #1#2#3{% + \ifnum\@lastchclass=\adl@class@start\else + \ifnum\@lastchclass=\@ne\else + \ifnum\@lastchclass=5 \else % @-arg (class 5) and !-arg (class 1) + \adl@leftrulefalse \fi\fi % must be treated the same + \fi + \ifadl@zwvrule\else \ifadl@inactive\else + \@addtopreamble{\vrule\@width\arrayrulewidth + \@height\z@ \@depth\z@}\fi \fi + \ifadl@leftrule + \@addtopreamble{\adl@vlineL{\CT@arc@}{\adl@dashgapcolor}% + {\number#1}#3}% + \else \@addtopreamble{\adl@vlineR{\CT@arc@}{\adl@dashgapcolor}% + {\number#2}#3} + \fi +}% \tabu@adl@xarraydashrule +\def\tabu@adl@act@endpbox {% + \unskip \ifhmode \nobreak \fi \@finalstrut \@arstrutbox + \egroup \egroup + \adl@colhtdp \box\adl@box \hfil +}% \tabu@adl@act@endpbox +\def\tabu@adl@fix {% + \let\adl@xarraydashrule \tabu@adl@xarraydashrule % arydshln + \let\adl@act@endpbox \tabu@adl@act@endpbox % arydshln + \let\adl@act@@endpbox \tabu@adl@act@endpbox % arydshln + \let\@preamerror \@preamerr % arydshln +}% \tabu@adl@fix +%% Correction for longtable' \@startbox definition ------------------ +%% => \everypar is ``missing'' : TeX should be in vertical mode +\def\tabu@LT@startpbox #1{% + \bgroup + \let\@footnotetext\LT@p@ftntext + \setlength\hsize{#1}% + \@arrayparboxrestore + \everypar{% + \vrule \@height \ht\@arstrutbox \@width \z@ + \everypar{}}% +}% \tabu@LT@startpbox +%% \tracingtabu and the package options ------------------ +\DeclareOption{delarray}{\AtEndOfPackage{\RequirePackage{delarray}}} +\DeclareOption{linegoal}{% + \AtEndOfPackage{% + \RequirePackage{linegoal}[2010/12/07]% + \let\tabudefaulttarget \linegoal% \linegoal is \linewidth if not pdfTeX +}} +\DeclareOption{scantokens}{\tabuscantokenstrue} +\DeclareOption{debugshow}{\AtEndOfPackage{\tracingtabu=\tw@}} +\def\tracingtabu {\begingroup\@ifnextchar=% + {\afterassignment\tabu@tracing\count@} + {\afterassignment\tabu@tracing\count@1\relax}} +\def\tabu@tracing{\expandafter\endgroup + \expandafter\tabu@tr@cing \the\count@ \relax +}% \tabu@tracing +\def\tabu@tr@cing #1\relax {% + \ifnum#1>\thr@@ \let\tabu@tracinglines\message + \else \let\tabu@tracinglines\@gobble + \fi + \ifnum#1>\tw@ \let\tabu@DBG \tabu@@DBG + \def\tabu@mkarstrut {\tabu@DBG@arstrut}% + \tabustrutrule 1.5\p@ + \else \let\tabu@DBG \@gobble + \def\tabu@mkarstrut {\tabu@arstrut}% + \tabustrutrule \z@ + \fi + \ifnum#1>\@ne \let\tabu@debug \message + \else \let\tabu@debug \@gobble + \fi + \ifnum#1>\z@ + \let\tabu@message \message + \let\tabu@tracing@save \tabu@message@save + \let\tabu@starttimer \tabu@pdftimer + \else + \let\tabu@message \@gobble + \let\tabu@tracing@save \@gobble + \let\tabu@starttimer \relax + \fi +}% \tabu@tr@cing +%% Setup \AtBeginDocument +\AtBeginDocument{\tabu@AtBeginDocument} +\def\tabu@AtBeginDocument{\let\tabu@AtBeginDocument \@undefined + \ifdefined\arrayrulecolor \tabu@colortbltrue % + \tabu@colortblalignments % different glues are used + \else \tabu@colortblfalse \fi + \ifdefined\CT@arc@ \else \let\CT@arc@ \relax \fi + \ifdefined\CT@drsc@\else \let\CT@drsc@ \relax \fi + \let\tabu@arc@L \CT@arc@ \let\tabu@drsc@L \CT@drsc@ + \ifodd 1\ifcsname siunitx_table_collect_begin:Nn\endcsname % + \expandafter\ifx + \csname siunitx_table_collect_begin:Nn\endcsname\relax 0\fi\fi\relax + \tabu@siunitxtrue + \else \let\tabu@maybesiunitx \@firstofone % + \let\tabu@siunitx \tabu@nosiunitx + \tabu@siunitxfalse + \fi + \ifdefined\adl@array % + \else \let\tabu@adl@fix \relax + \let\tabu@adl@endtrial \@empty \fi + \ifdefined\longtable % + \else \let\longtabu \tabu@nolongtabu \fi + \ifdefined\cellspacetoplimit \tabu@warn@cellspace\fi + \csname\ifcsname ifHy@hyperfootnotes\endcsname % + ifHy@hyperfootnotes\else iffalse\fi\endcsname + \let\tabu@footnotetext \tabu@Hy@ftntext + \let\tabu@xfootnote \tabu@Hy@xfootnote \fi + \ifdefined\FV@DefineCheckEnd% + \tabu@fancyvrb \fi + \ifdefined\color % + \let\tabu@color \color + \def\tabu@leavevmodecolor ##1{% + \def\tabu@leavevmodecolor {\leavevmode ##1}% + }\expandafter\tabu@leavevmodecolor\expandafter{\color}% + \else + \let\tabu@color \tabu@nocolor + \let\tabu@leavevmodecolor \@firstofone \fi + \tabu@latextwoe + \ifdefined\@raggedtwoe@everyselectfont % + \tabu@raggedtwoe + \else + \let\tabu@cell@L \tabu@cell@l + \let\tabu@cell@R \tabu@cell@r + \let\tabu@cell@C \tabu@cell@c + \let\tabu@cell@J \tabu@cell@j \fi + \expandafter\in@ \expandafter\@arrayright \expandafter{\endarray}% + \ifin@ \let\tabu@endarray \endarray + \else \tabu@fix@arrayright \fi% + \everyrow{}% +}% \tabu@AtBeginDocument +\def\tabu@warn@cellspace{% + \PackageWarning{tabu}{% + Package cellspace has some limitations + \MessageBreak And redefines some macros of array.sty. + \MessageBreak Please use \string\tabulinesep\space to control + \MessageBreak vertical spacing of lines inside tabu environment}% +}% \tabu@warn@cellspace +%% tabu Package initialisation +\tabuscantokensfalse +\let\tabu@arc@G \relax +\let\tabu@drsc@G \relax +\let\tabu@evr@G \@empty +\let\tabu@rc@G \@empty +\def\tabu@ls@G {\tabu@linestyle@}% +\let\tabu@@rowfontreset \@empty % +\let\tabu@@celllalign \@empty +\let\tabu@@cellralign \@empty +\let\tabu@@cellleft \@empty +\let\tabu@@cellright \@empty +\def\tabu@naturalXmin {\z@} +\def\tabu@naturalXmax {\z@} +\let\tabu@rowfontreset \@empty +\def\tabulineon {4pt}\let\tabulineoff \tabulineon +\tabu@everyrowtrue +\ifdefined\pdfelapsedtime % + \def\tabu@pdftimer {\xdef\tabu@starttime{\the\pdfelapsedtime}}% +\else \let\tabu@pdftimer \relax \let\tabu@message@etime \relax +\fi +\tracingtabu=\z@ +\newtabulinestyle {=\maxdimen}% creates the 'factory' settings \tabu@linestyle@ +\tabulinestyle{} +\taburowcolors{} +\let\tabudefaulttarget \linewidth +\ProcessOptions* % \ProcessOptions* is quicker ! +\endinput +%% +%% End of file `tabu.sty'. diff --git a/docs/latex/xdf_8h.tex b/docs/latex/xdf_8h.tex new file mode 100644 index 0000000..281ea02 --- /dev/null +++ b/docs/latex/xdf_8h.tex @@ -0,0 +1,23 @@ +\hypertarget{xdf_8h}{}\doxysection{xdf.\+h File Reference} +\label{xdf_8h}\index{xdf.h@{xdf.h}} + + +The header file of \mbox{\hyperlink{class_xdf}{Xdf}} class. + + +{\ttfamily \#include $<$string$>$}\newline +{\ttfamily \#include $<$vector$>$}\newline +{\ttfamily \#include $<$map$>$}\newline +{\ttfamily \#include $<$set$>$}\newline +\doxysubsection*{Classes} +\begin{DoxyCompactItemize} +\item +class \mbox{\hyperlink{class_xdf}{Xdf}} +\item +class \mbox{\hyperlink{struct_xdf_1_1_stream}{Xdf\+::\+Stream}} +\end{DoxyCompactItemize} + + +\doxysubsection{Detailed Description} +The header file of \mbox{\hyperlink{class_xdf}{Xdf}} class. + From acd4b1e9bdbf81ef09db8ce0a758e3d3f363f862 Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 15:13:26 -0700 Subject: [PATCH 05/10] Fix curly braces style --- xdf.cpp | 495 ++++++++++++++++++++++---------------------------------- xdf.h | 9 +- 2 files changed, 195 insertions(+), 309 deletions(-) diff --git a/xdf.cpp b/xdf.cpp index 6823841..cc27e18 100644 --- a/xdf.cpp +++ b/xdf.cpp @@ -29,12 +29,11 @@ #include // bind2nd #include -Xdf::Xdf() -{ +Xdf::Xdf() { + } -int Xdf::load_xdf(std::string filename) -{ +int Xdf::load_xdf(std::string filename) { clock_t time; time = clock(); @@ -59,38 +58,32 @@ int Xdf::load_xdf(std::string filename) std::ifstream file(filename, std::ios::in | std::ios::binary); - if (file.is_open()) - { + if (file.is_open()) { //read [MagicCode] std::string magicNumber; - for (char c; file >> c;) - { + for (char c; file >> c;) { magicNumber.push_back(c); if (magicNumber.size() == 4) break; } - if (magicNumber.compare("XDF:")) - { + if (magicNumber.compare("XDF:")) { std::cout << "This is not a valid XDF file.('" << filename << "')\n"; return -1; } //for each chunk - while (1) - { + while (1) { uint64_t ChLen = read_length(file);//chunk length - if (ChLen == 0) - break; + if (ChLen == 0) break; uint16_t tag; //read tag of the chunk, 6 possibilities read_bin(file, &tag); - switch (tag) - { - case 1: //[FileHeader] - { + switch (tag) { + case 1: { + // [FileHeader] char* buffer = new char[ChLen - 2]; file.read(buffer, ChLen - 2); file_header_ = buffer; @@ -106,26 +99,24 @@ int Xdf::load_xdf(std::string filename) delete[] buffer; } break; - case 2: //read [StreamHeader] chunk - { - //read [StreamID] - uint32_t streamID; + case 2: { + // [StreamHeader] chunk + uint32_t streamID; //read [StreamID] int index; Xdf::read_bin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; - if (it == idmap.end()) - { + if (it == idmap.end()) { index = idmap.size(); idmap.emplace_back(streamID); streams_.emplace_back(); } - else + else { index = std::distance(idmap.begin(), it); - + } pugi::xml_document doc; - //read [Content] + // read [Content] char* buffer = new char[ChLen - 6]; file.read(buffer, ChLen - 6); streams_[index].stream_header = buffer; @@ -141,64 +132,60 @@ int Xdf::load_xdf(std::string filename) streams_[index].info.type = info.child("type").text().get(); streams_[index].info.channel_format = info.child("channel_format").text().get(); - for (auto channel = desc.child("channels").child("channel"); channel; channel = channel.next_sibling("channel")) - { + for (auto channel = desc.child("channels").child("channel"); channel; channel = channel.next_sibling("channel")) { streams_[index].info.channels.emplace_back(); for (auto const &entry : channel.children()) streams_[index].info.channels.back().emplace(entry.name(), entry.child_value()); } - if (streams_[index].info.nominal_srate > 0) + if (streams_[index].info.nominal_srate > 0) { streams_[index].sampling_interval = 1 / streams_[index].info.nominal_srate; - else + } + else { streams_[index].sampling_interval = 0; + } delete[] buffer; } break; - case 3: //read [Samples] chunk - { - //read [StreamID] - uint32_t streamID; + case 3: { + // [Samples] chunk + uint32_t streamID; //read [StreamID] int index; Xdf::read_bin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; - if (it == idmap.end()) - { + if (it == idmap.end()) { index = idmap.size(); idmap.emplace_back(streamID); streams_.emplace_back(); } - else + else { index = std::distance(idmap.begin(), it); - + } //read [NumSampleBytes], [NumSamples] uint64_t numSamp = read_length(file); //check the data type - if (streams_[index].info.channel_format.compare("float32") == 0) - { + if (streams_[index].info.channel_format.compare("float32") == 0) { //if the time series is empty - if (streams_[index].time_series.empty()) + if (streams_[index].time_series.empty()) { streams_[index].time_series.resize(streams_[index].info.channel_count); + } //for each sample - for (size_t i = 0; i < numSamp; i++) - { + for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp auto tsBytes = read_bin(file); double ts; //temporary time stamp - if (tsBytes == 8) - { + if (tsBytes == 8) { Xdf::read_bin(file, &ts); streams_[index].timestamps.emplace_back(ts); } - else - { + else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; streams_[index].timestamps.emplace_back(ts); } @@ -206,35 +193,31 @@ int Xdf::load_xdf(std::string filename) streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams_[index].info.channel_count; ++v) - { + for (int v = 0; v < streams_[index].info.channel_count; ++v) { float data; Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } } - else if (streams_[index].info.channel_format.compare("double64") == 0) - { + else if (streams_[index].info.channel_format.compare("double64") == 0) { //if the time series is empty - if (streams_[index].time_series.empty()) + if (streams_[index].time_series.empty()) { streams_[index].time_series.resize(streams_[index].info.channel_count); + } //for each sample - for (size_t i = 0; i < numSamp; i++) - { + for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp auto tsBytes = read_bin(file); double ts; //temporary time stamp - if (tsBytes == 8) - { + if (tsBytes == 8) { Xdf::read_bin(file, &ts); streams_[index].timestamps.emplace_back(ts); } - else - { + else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; streams_[index].timestamps.emplace_back(ts); } @@ -242,35 +225,31 @@ int Xdf::load_xdf(std::string filename) streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams_[index].info.channel_count; ++v) - { + for (int v = 0; v < streams_[index].info.channel_count; ++v) { double data; Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } } - else if (streams_[index].info.channel_format.compare("int8") == 0) - { + else if (streams_[index].info.channel_format.compare("int8") == 0) { //if the time series is empty - if (streams_[index].time_series.empty()) + if (streams_[index].time_series.empty()) { streams_[index].time_series.resize(streams_[index].info.channel_count); + } //for each sample - for (size_t i = 0; i < numSamp; i++) - { + for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp auto tsBytes = read_bin(file); double ts; //temporary time stamp - if (tsBytes == 8) - { + if (tsBytes == 8) { Xdf::read_bin(file, &ts); streams_[index].timestamps.emplace_back(ts); } - else - { + else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; streams_[index].timestamps.emplace_back(ts); } @@ -278,35 +257,31 @@ int Xdf::load_xdf(std::string filename) streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams_[index].info.channel_count; ++v) - { + for (int v = 0; v < streams_[index].info.channel_count; ++v) { int8_t data; Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } } - else if (streams_[index].info.channel_format.compare("int16") == 0) - { + else if (streams_[index].info.channel_format.compare("int16") == 0) { //if the time series is empty - if (streams_[index].time_series.empty()) + if (streams_[index].time_series.empty()) { streams_[index].time_series.resize(streams_[index].info.channel_count); + } //for each sample - for (size_t i = 0; i < numSamp; i++) - { + for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp auto tsBytes = read_bin(file); double ts; //temporary time stamp - if (tsBytes == 8) - { + if (tsBytes == 8) { Xdf::read_bin(file, &ts); streams_[index].timestamps.emplace_back(ts); } - else - { + else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; streams_[index].timestamps.emplace_back(ts); } @@ -314,35 +289,31 @@ int Xdf::load_xdf(std::string filename) streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams_[index].info.channel_count; ++v) - { + for (int v = 0; v < streams_[index].info.channel_count; ++v) { int16_t data; Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } } - else if (streams_[index].info.channel_format.compare("int32") == 0) - { + else if (streams_[index].info.channel_format.compare("int32") == 0) { //if the time series is empty - if (streams_[index].time_series.empty()) + if (streams_[index].time_series.empty()) { streams_[index].time_series.resize(streams_[index].info.channel_count); + } //for each sample - for (size_t i = 0; i < numSamp; i++) - { + for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp auto tsBytes = read_bin(file); double ts; //temporary time stamp - if (tsBytes == 8) - { + if (tsBytes == 8) { Xdf::read_bin(file, &ts); streams_[index].timestamps.emplace_back(ts); } - else - { + else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; streams_[index].timestamps.emplace_back(ts); } @@ -350,35 +321,31 @@ int Xdf::load_xdf(std::string filename) streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams_[index].info.channel_count; ++v) - { + for (int v = 0; v < streams_[index].info.channel_count; ++v) { int32_t data; Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } } - else if (streams_[index].info.channel_format.compare("int64") == 0) - { + else if (streams_[index].info.channel_format.compare("int64") == 0) { //if the time series is empty - if (streams_[index].time_series.empty()) + if (streams_[index].time_series.empty()) { streams_[index].time_series.resize(streams_[index].info.channel_count); + } //for each sample - for (size_t i = 0; i < numSamp; i++) - { + for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp auto tsBytes = read_bin(file); double ts; //temporary time stamp - if (tsBytes == 8) - { + if (tsBytes == 8) { Xdf::read_bin(file, &ts); streams_[index].timestamps.emplace_back(ts); } - else - { + else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; streams_[index].timestamps.emplace_back(ts); } @@ -386,28 +353,27 @@ int Xdf::load_xdf(std::string filename) streams_[index].last_timestamp = ts; //read the data - for (int v = 0; v < streams_[index].info.channel_count; ++v) - { + for (int v = 0; v < streams_[index].info.channel_count; ++v) { int64_t data; Xdf::read_bin(file, &data); streams_[index].time_series[v].emplace_back(data); } } } - else if (streams_[index].info.channel_format.compare("string") == 0) - { + else if (streams_[index].info.channel_format.compare("string") == 0) { //for each event - for (size_t i = 0; i < numSamp; i++) - { + for (size_t i = 0; i < numSamp; i++) { //read or deduce time stamp auto tsBytes = read_bin(file); double ts; //temporary time stamp - if (tsBytes == 8) + if (tsBytes == 8) { Xdf::read_bin(file, &ts); - else + } + else { ts = streams_[index].last_timestamp + streams_[index].sampling_interval; + } //read the event auto length = Xdf::read_length(file); @@ -422,21 +388,20 @@ int Xdf::load_xdf(std::string filename) } } break; - case 4: //read [ClockOffset] chunk - { + case 4: { + // [ClockOffset] chunk uint32_t streamID; int index; Xdf::read_bin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; - if (it == idmap.end()) - { + if (it == idmap.end()) { index = idmap.size(); idmap.emplace_back(streamID); streams_.emplace_back(); } - else + else { index = std::distance(idmap.begin(), it); - + } double collectionTime; double offsetValue; @@ -448,8 +413,8 @@ int Xdf::load_xdf(std::string filename) streams_[index].clock_values.emplace_back(offsetValue); } break; - case 6: //read [StreamFooter] chunk - { + case 6: { + // [StreamFooter] chunk pugi::xml_document doc; //read [StreamID] @@ -457,15 +422,14 @@ int Xdf::load_xdf(std::string filename) int index; Xdf::read_bin(file, &streamID); std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; - if (it == idmap.end()) - { + if (it == idmap.end()) { index = idmap.size(); idmap.emplace_back(streamID); streams_.emplace_back(); } - else + else { index = std::distance(idmap.begin(), it); - + } char* buffer = new char[ChLen - 6]; file.read(buffer, ChLen - 6); @@ -482,7 +446,8 @@ int Xdf::load_xdf(std::string filename) delete[] buffer; } break; - case 5: //skip other chunk types (Boundary, ...) + case 5: + //skip other chunk types (Boundary, ...) file.seekg(ChLen - 2, file.cur); break; default: @@ -491,18 +456,12 @@ int Xdf::load_xdf(std::string filename) } } - //calculate how much time it takes to read the data clock_t halfWay = clock() - time; std::cout << "it took " << halfWay << " clicks (" << ((float)halfWay) / CLOCKS_PER_SEC << " seconds)" << " reading XDF data" << std::endl; - - //========================================================== - //=============find the min and max time stamps============= - //========================================================== - sync_timestamps(); find_min_max_time_stamps(); @@ -522,8 +481,7 @@ int Xdf::load_xdf(std::string filename) //loading finishes, close file file.close(); } - else - { + else { std::cout << "Unable to open file" << std::endl; return 1; } @@ -531,28 +489,21 @@ int Xdf::load_xdf(std::string filename) return 0; } -void Xdf::sync_timestamps() -{ +void Xdf::sync_timestamps() { // Sync time stamps - for (auto &stream : this->streams_) - { - if (!stream.clock_times.empty()) - { + for (auto &stream : this->streams_) { + if (!stream.clock_times.empty()) { size_t m = 0; // index iterating through stream.time_stamps size_t n = 0; // index iterating through stream.clock_times - while (m < stream.timestamps.size()) - { - if (stream.clock_times[n] < stream.timestamps[m]) - { - while (n < stream.clock_times.size() - 1 && stream.clock_times[n+1] < stream.timestamps[m]) - { + while (m < stream.timestamps.size()) { + if (stream.clock_times[n] < stream.timestamps[m]) { + while (n < stream.clock_times.size() - 1 && stream.clock_times[n+1] < stream.timestamps[m]) { n++; } stream.timestamps[m] += stream.clock_values[n]; } - else if (n == 0) - { + else if (n == 0) { stream.timestamps[m] += stream.clock_values[n]; } m++; @@ -561,20 +512,15 @@ void Xdf::sync_timestamps() } // Sync event time stamps - for (auto &elem : this->event_map_) - { - if (!this->streams_[elem.second].clock_times.empty()) - { + for (auto &elem : this->event_map_) { + if (!this->streams_[elem.second].clock_times.empty()) { size_t k = 0; // index iterating through streams[elem.second].clock_times - while (k < this->streams_[elem.second].clock_times.size() - 1) - { - if (this->streams_[elem.second].clock_times[k+1] < elem.first.second) - { + while (k < this->streams_[elem.second].clock_times.size() - 1) { + if (this->streams_[elem.second].clock_times[k+1] < elem.first.second) { k++; } - else - { + else { break; } } @@ -584,24 +530,18 @@ void Xdf::sync_timestamps() } // Update first and last time stamps in stream footer - for (size_t k = 0; k < this->streams_.size(); k++) - { - if (streams_[k].info.channel_format.compare("string") == 0) - { + for (size_t k = 0; k < this->streams_.size(); k++) { + if (streams_[k].info.channel_format.compare("string") == 0) { double min = NAN; double max = NAN; - for (auto const &elem : this->event_map_) - { - if (elem.second == (int)k) - { - if (std::isnan(min) || elem.first.second < min) - { + for (auto const &elem : this->event_map_) { + if (elem.second == (int)k) { + if (std::isnan(min) || elem.first.second < min) { min = elem.first.second; } - if (std::isnan(max) || elem.first.second > max) - { + if (std::isnan(max) || elem.first.second > max) { max = elem.first.second; } } @@ -610,28 +550,23 @@ void Xdf::sync_timestamps() streams_[k].info.first_timestamp = min; streams_[k].info.last_timestamp = max; } - else - { + else { streams_[k].info.first_timestamp = streams_[k].timestamps.front(); streams_[k].info.last_timestamp = streams_[k].timestamps.back(); } } } -void Xdf::resample(int sampling_rate) -{ +void Xdf::resample(int sampling_rate) { //if user entered a preferred sample rate, we resample all the channels to that sample rate //Otherwise, we resample all channels to the sample rate that has the most channels clock_t time = clock(); #define BUF_SIZE 8192 - for (auto &stream : streams_) - { - if (!stream.time_series.empty() && - stream.info.nominal_srate != sampling_rate && - stream.info.nominal_srate != 0) - { + for (auto &stream : streams_) { + if (!stream.time_series.empty() && stream.info.nominal_srate != sampling_rate && + stream.info.nominal_srate != 0) { int fsin = stream.info.nominal_srate; // input samplerate int fsout = sampling_rate; // output samplerate double bandwidth = 0.95; // bandwidth @@ -642,14 +577,12 @@ void Xdf::resample(int sampling_rate) // initialize smarc filter struct PFilter* pfilt = smarc_init_pfilter(fsin, fsout, bandwidth, rp, rs, tol, NULL, 0); - if (pfilt == NULL) - continue; + if (pfilt == NULL) continue; // initialize smarc filter state struct PState* pstate = smarc_init_pstate(pfilt); - for (auto &row : stream.time_series) - { + for (auto &row : stream.time_series) { // initialize buffers int read = 0; int written = 0; @@ -657,7 +590,6 @@ void Xdf::resample(int sampling_rate) double* inbuf = new double[row.size()]; double* outbuf = new double[OUT_BUF_SIZE]; - std::copy(row.begin(), row.end(), inbuf); read = row.size(); @@ -693,12 +625,10 @@ void Xdf::resample(int sampling_rate) } //resampling finishes here - //====================================================================== //===========Calculating total length & total channel count============= //====================================================================== - calculate_total_length(sampling_rate); adjust_total_length(); @@ -710,14 +640,12 @@ void Xdf::resample(int sampling_rate) } //function of reading the length of each chunk -uint64_t Xdf::read_length(std::ifstream &file) -{ +uint64_t Xdf::read_length(std::ifstream &file) { uint8_t bytes; Xdf::read_bin(file, &bytes); uint64_t length = 0; - switch (bytes) - { + switch (bytes) { case 1: length = read_bin(file); break; @@ -736,33 +664,27 @@ uint64_t Xdf::read_length(std::ifstream &file) return length; } -void Xdf::find_min_max_time_stamps() -{ +void Xdf::find_min_max_time_stamps() { //find the smallest timestamp of all streams - for (auto const &stream : streams_) - { - if (!std::isnan(stream.info.first_timestamp)) - { + for (auto const &stream : streams_) { + if (!std::isnan(stream.info.first_timestamp)) { min_timestamp_ = stream.info.first_timestamp; break; } } - for (auto const &stream : streams_) - { + for (auto const &stream : streams_) { if (!std::isnan(stream.info.first_timestamp) && stream.info.first_timestamp < min_timestamp_) min_timestamp_ = stream.info.first_timestamp; } //find the max timestamp of all streams - for (auto const &stream : streams_) - { + for (auto const &stream : streams_) { if (!std::isnan(stream.info.last_timestamp) && stream.info.last_timestamp > max_timestamp_) max_timestamp_ = stream.info.last_timestamp; } } -void Xdf::find_major_sampling_rate() -{ +void Xdf::find_major_sampling_rate() { // find out which sample rate has the most channels typedef int sampRate; typedef int numChannel; @@ -770,32 +692,30 @@ void Xdf::find_major_sampling_rate() std::vector > srateMap; // pairs of all the streams //find out whether a sample rate already exists in srateMap - for (auto const &stream : streams_) - { - if (stream.info.nominal_srate != 0) - { + for (auto const &stream : streams_) { + if (stream.info.nominal_srate != 0) { std::vector >::iterator it {std::find_if(srateMap.begin(), srateMap.end(), - [&](const std::pair &element) - {return element.first == stream.info.nominal_srate; })} ; + [&](const std::pair &element) + {return element.first == stream.info.nominal_srate; })} ; //if it doesn't, add it here - if (it == srateMap.end()) + if (it == srateMap.end()) { srateMap.emplace_back(stream.info.nominal_srate, stream.info.channel_count); //if it already exists, add additional channel numbers to that sample rate - else - { + } + else { int index (std::distance(srateMap.begin(),it)) ; srateMap[index].second += stream.info.channel_count; } } } - if(srateMap.size() > 0){ + if (srateMap.size() > 0) { //search the srateMap to see which sample rate has the most channels int index (std::distance(srateMap.begin(), std::max_element(srateMap.begin(),srateMap.end(), - [] (const std::pair &largest, - const std::pair &first) - { return largest.second < first.second; }))); + [] (const std::pair &largest, + const std::pair &first) + { return largest.second < first.second; }))); major_sampling_rate_ = srateMap[index].first; //the sample rate that has the most channels } else { @@ -803,13 +723,10 @@ void Xdf::find_major_sampling_rate() } } -void Xdf::calculate_channel_count() -{ +void Xdf::calculate_channel_count() { //calculating total channel count, and indexing them onto streamMap - for (size_t c = 0; c < streams_.size(); c++) - { - if(!streams_[c].time_series.empty()) - { + for (size_t c = 0; c < streams_.size(); c++) { + if(!streams_[c].time_series.empty()) { channel_count_ += streams_[c].info.channel_count; for (int i = 0; i < streams_[c].info.channel_count; i++) @@ -818,20 +735,16 @@ void Xdf::calculate_channel_count() } } -void Xdf::calculate_total_length(int sampling_rate) -{ +void Xdf::calculate_total_length(int sampling_rate) { total_len_ = (max_timestamp_ - min_timestamp_) * sampling_rate; } -void Xdf::free_up_timestamps() -{ +void Xdf::free_up_timestamps() { //free up as much memory as possible - for (auto &stream : streams_) - { + for (auto &stream : streams_) { //we don't need to keep all the time stamps unless it's a stream with irregular samples //filter irregular streams and string streams - if (stream.info.nominal_srate != 0 && !stream.timestamps.empty() && stream.info.channel_format.compare("string")) - { + if (stream.info.nominal_srate != 0 && !stream.timestamps.empty() && stream.info.channel_format.compare("string")) { std::vector nothing; //however we still need to keep the first time stamp of each stream to decide at which position the signal should start nothing.emplace_back(stream.timestamps.front()); @@ -840,61 +753,52 @@ void Xdf::free_up_timestamps() } } -void Xdf::adjust_total_length() -{ - for (auto const &stream : streams_) - { - if(!stream.time_series.empty()) - { - if (total_len_ < stream.time_series.front().size()) +void Xdf::adjust_total_length() { + for (auto const &stream : streams_) { + if(!stream.time_series.empty()) { + if (total_len_ < stream.time_series.front().size()) { total_len_ = stream.time_series.front().size(); + } } } } -void Xdf::find_max_sampling_rate() -{ - for (auto const &stream : streams_) - { - if (stream.info.nominal_srate > max_sampling_rate_) +void Xdf::find_max_sampling_rate() { + for (auto const &stream : streams_) { + if (stream.info.nominal_srate > max_sampling_rate_) { max_sampling_rate_ = stream.info.nominal_srate; + } } } -void Xdf::load_sampling_rate_map() -{ - for (auto const &stream : streams_) +void Xdf::load_sampling_rate_map() { + for (auto const &stream : streams_) { sampling_rate_map_.emplace(stream.info.nominal_srate); + } } -void Xdf::detrend() -{ - for (auto &stream : streams_) - { - for (auto &row : stream.time_series) - { +void Xdf::detrend() { + for (auto &stream : streams_) { + for (auto &row : stream.time_series) { long double init = 0.0; long double mean = std::accumulate(row.begin(), row.end(), init) / row.size(); - for(auto &val: row) val -= mean; + for(auto &val: row) val -= mean; offsets_.emplace_back(mean); } } } -void Xdf::calculate_effective_sampling_rate() -{ - for (auto &stream : streams_) - { - if (stream.info.nominal_srate) - { - try - { +void Xdf::calculate_effective_sampling_rate() { + for (auto &stream : streams_) { + if (stream.info.nominal_srate) { + try { stream.info.effective_sampling_rate = stream.info.sample_count / (stream.info.last_timestamp - stream.info.first_timestamp); - if (stream.info.effective_sampling_rate) + if (stream.info.effective_sampling_rate) { effective_sampling_rates_.emplace_back(stream.info.effective_sampling_rate); + } pugi::xml_document doc; doc.load_string(stream.stream_footer.c_str()); @@ -909,8 +813,7 @@ void Xdf::calculate_effective_sampling_rate() stream.stream_footer = buffer.str(); } - catch (std::exception &e) - { + catch (std::exception &e) { std::cerr << "Error calculating effective sample rate. " << e.what() << std::endl; } @@ -918,15 +821,12 @@ void Xdf::calculate_effective_sampling_rate() } } -int Xdf::write_events_to_xdf(std::string file_path) -{ - if (user_added_stream_) - { +int Xdf::write_events_to_xdf(std::string file_path) { + if (user_added_stream_) { std::fstream file; file.open(file_path, std::ios::app | std::ios::binary); - if (file.is_open()) - { + if (file.is_open()) { //start to append to new XDF file //first write a stream header chunk //Num Length Bytes @@ -950,15 +850,15 @@ int Xdf::write_events_to_xdf(std::string file_path) //length //add the bytes of all following actions together int64_t stringTotalLength = 0; - for (auto const &event : user_created_events_) + for (auto const &event : user_created_events_) { stringTotalLength += event.first.size(); + } int64_t sampleChunkLength = 2 + 4 + 1 + 4 + user_created_events_.size() * (1 + 8 + 1 + 4) + stringTotalLength; file.write((char*)&sampleChunkLength, 8); - //tag tag = 3; file.write((char*)&tag, 2); @@ -973,8 +873,7 @@ int Xdf::write_events_to_xdf(std::string file_path) file.write((char*)&numSamples, 4); //samples - for (auto const &event : user_created_events_) - { + for (auto const &event : user_created_events_) { //TimeStampBytes file.put(8); @@ -995,8 +894,7 @@ int Xdf::write_events_to_xdf(std::string file_path) file.close(); } - else - { + else { std::cerr << "Unable to open file." << std::endl; return -1; //Error } @@ -1007,29 +905,23 @@ int Xdf::write_events_to_xdf(std::string file_path) return 0; //Success } -void Xdf::create_labels() -{ +void Xdf::create_labels() { size_t channelCount = 0; - for (size_t st = 0; st < streams_.size(); st++) - { - if (streams_[st].info.channels.size()) - { - for (size_t ch = 0; ch < streams_[st].info.channels.size(); ch++) - { + for (size_t st = 0; st < streams_.size(); st++) { + if (streams_[st].info.channels.size()) { + for (size_t ch = 0; ch < streams_[st].info.channels.size(); ch++) { // +1 for 1 based numbers; for user convenience only. The internal computation is still 0 based std::string label = "Stream " + std::to_string(st + 1) + " - Channel " + std::to_string(ch + 1) + " - " + std::to_string((int)streams_[st].info.nominal_srate) + " Hz\n"; label += streams_[st].info.name + '\n'; - for (auto const &entry : streams_[st].info.channels[ch]) - { + for (auto const &entry : streams_[st].info.channels[ch]) { if (entry.second != "") label += entry.first + " : " + entry.second + '\n'; } - if (offsets_.size()) - { + if (offsets_.size()) { if (offsets_[channelCount] >= 0) label.append("baseline +").append(std::to_string(offsets_[channelCount])); else @@ -1040,10 +932,8 @@ void Xdf::create_labels() channelCount++; } } - else - { - for (size_t ch = 0; ch < streams_[st].time_series.size(); ch++) - { + else { + for (size_t ch = 0; ch < streams_[st].time_series.size(); ch++) { // +1 for 1 based numbers; for user convenience only. The internal computation is still 0 based std::string label = "Stream " + std::to_string(st + 1) + " - Channel " + std::to_string(ch + 1) + " - " + @@ -1052,8 +942,7 @@ void Xdf::create_labels() label += streams_[st].info.name + '\n'; - if (offsets_.size()) - { + if (offsets_.size()) { if (offsets_[channelCount] >= 0) label.append("baseline +").append(std::to_string(offsets_[channelCount])); else @@ -1068,28 +957,28 @@ void Xdf::create_labels() } } -void Xdf::load_dictionary() -{ - //loop through the eventMap - for (auto const &entry : event_map_) - { +void Xdf::load_dictionary() { + //loop through `event_map_` + for (auto const &entry : event_map_) { //search the dictionary to see whether an event is already in it auto it = std::find(dictionary_.begin(),dictionary_.end(),entry.first.first); //if it isn't yet - if (it == dictionary_.end()) - { //add it to the dictionary, also store its index into eventType vector for future use + if (it == dictionary_.end()) { + //add it to the dictionary, also store its index into eventType vector for future use event_type_.emplace_back(dictionary_.size()); dictionary_.emplace_back(entry.first.first); } //if it's already in there - else //store its index into eventType vector + else { + //store its index into eventType vector event_type_.emplace_back(std::distance(dictionary_.begin(), it)); + } } } template T Xdf::read_bin(std::istream& is, T* obj) { - T dummy; - if(!obj) obj = &dummy; - is.read(reinterpret_cast(obj), sizeof(T)); - return *obj; + T dummy; + if(!obj) obj = &dummy; + is.read(reinterpret_cast(obj), sizeof(T)); + return *obj; } diff --git a/xdf.h b/xdf.h index 700b529..d94bd27 100644 --- a/xdf.h +++ b/xdf.h @@ -34,8 +34,7 @@ * resampling etc. */ -class Xdf -{ +class Xdf { public: //! Default constructor with no parameter. Xdf(); @@ -47,15 +46,13 @@ class Xdf * channels. The Stream struct stores meta-data, time series, timetamps * and other information of a stream. */ - struct Stream - { + struct Stream { std::vector> time_series; /*!< Stores the time series of a stream. Each row represents a channel.*/ std::vector timestamps; /*!< Stores the timestamps. */ std::string stream_header; /*!< Raw XML of stream header chunk. */ std::string stream_footer; /*!< Raw XML of stream footer chunk. */ - struct - { + struct { int channel_count; /*!< Number of channels in the current stream */ double nominal_srate; /*!< The nominal sampling rate of the current stream. */ std::string name; /*!< The name of the current stream. */ From 3dbbf791b1177fee0876cfd84832d0180d80b8f0 Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 15:26:37 -0700 Subject: [PATCH 06/10] Cleaned up local variables --- xdf.cpp | 279 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 142 insertions(+), 137 deletions(-) diff --git a/xdf.cpp b/xdf.cpp index cc27e18..9df24ac 100644 --- a/xdf.cpp +++ b/xdf.cpp @@ -60,23 +60,23 @@ int Xdf::load_xdf(std::string filename) { if (file.is_open()) { //read [MagicCode] - std::string magicNumber; + std::string magic_number; for (char c; file >> c;) { - magicNumber.push_back(c); - if (magicNumber.size() == 4) + magic_number.push_back(c); + if (magic_number.size() == 4) break; } - if (magicNumber.compare("XDF:")) { + if (magic_number.compare("XDF:")) { std::cout << "This is not a valid XDF file.('" << filename << "')\n"; return -1; } //for each chunk while (1) { - uint64_t ChLen = read_length(file);//chunk length + uint64_t channel_length = read_length(file);//chunk length - if (ChLen == 0) break; + if (channel_length == 0) break; uint16_t tag; //read tag of the chunk, 6 possibilities read_bin(file, &tag); @@ -84,13 +84,13 @@ int Xdf::load_xdf(std::string filename) { switch (tag) { case 1: { // [FileHeader] - char* buffer = new char[ChLen - 2]; - file.read(buffer, ChLen - 2); + char* buffer = new char[channel_length - 2]; + file.read(buffer, channel_length - 2); file_header_ = buffer; pugi::xml_document doc; - doc.load_buffer_inplace(buffer, ChLen - 2); + doc.load_buffer_inplace(buffer, channel_length - 2); pugi::xml_node info = doc.child("info"); @@ -101,13 +101,13 @@ int Xdf::load_xdf(std::string filename) { break; case 2: { // [StreamHeader] chunk - uint32_t streamID; //read [StreamID] + uint32_t stream_id; int index; - Xdf::read_bin(file, &streamID); - std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; + Xdf::read_bin(file, &stream_id); + std::vector::iterator it{std::find(idmap.begin(),idmap.end(),stream_id)}; if (it == idmap.end()) { index = idmap.size(); - idmap.emplace_back(streamID); + idmap.emplace_back(stream_id); streams_.emplace_back(); } else { @@ -117,11 +117,11 @@ int Xdf::load_xdf(std::string filename) { pugi::xml_document doc; // read [Content] - char* buffer = new char[ChLen - 6]; - file.read(buffer, ChLen - 6); + char* buffer = new char[channel_length - 6]; + file.read(buffer, channel_length - 6); streams_[index].stream_header = buffer; - doc.load_buffer_inplace(buffer, ChLen - 6); + doc.load_buffer_inplace(buffer, channel_length - 6); pugi::xml_node info = doc.child("info"); pugi::xml_node desc = info.child("desc"); @@ -135,8 +135,9 @@ int Xdf::load_xdf(std::string filename) { for (auto channel = desc.child("channels").child("channel"); channel; channel = channel.next_sibling("channel")) { streams_[index].info.channels.emplace_back(); - for (auto const &entry : channel.children()) + for (auto const &entry : channel.children()) { streams_[index].info.channels.back().emplace(entry.name(), entry.child_value()); + } } if (streams_[index].info.nominal_srate > 0) { @@ -151,13 +152,13 @@ int Xdf::load_xdf(std::string filename) { break; case 3: { // [Samples] chunk - uint32_t streamID; //read [StreamID] + uint32_t stream_id; int index; - Xdf::read_bin(file, &streamID); - std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; + Xdf::read_bin(file, &stream_id); + std::vector::iterator it {std::find(idmap.begin(),idmap.end(),stream_id)}; if (it == idmap.end()) { index = idmap.size(); - idmap.emplace_back(streamID); + idmap.emplace_back(stream_id); streams_.emplace_back(); } else { @@ -165,7 +166,7 @@ int Xdf::load_xdf(std::string filename) { } //read [NumSampleBytes], [NumSamples] - uint64_t numSamp = read_length(file); + uint64_t num_samples = read_length(file); //check the data type if (streams_[index].info.channel_format.compare("float32") == 0) { @@ -175,22 +176,22 @@ int Xdf::load_xdf(std::string filename) { } //for each sample - for (size_t i = 0; i < numSamp; i++) { + for (size_t i = 0; i < num_samples; i++) { //read or deduce time stamp - auto tsBytes = read_bin(file); + auto timestamp_bytes = read_bin(file); - double ts; //temporary time stamp + double timestamp; //temporary time stamp - if (tsBytes == 8) { - Xdf::read_bin(file, &ts); - streams_[index].timestamps.emplace_back(ts); + if (timestamp_bytes == 8) { + Xdf::read_bin(file, ×tamp); + streams_[index].timestamps.emplace_back(timestamp); } else { - ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].timestamps.emplace_back(ts); + timestamp = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].timestamps.emplace_back(timestamp); } - streams_[index].last_timestamp = ts; + streams_[index].last_timestamp = timestamp; //read the data for (int v = 0; v < streams_[index].info.channel_count; ++v) { @@ -207,22 +208,22 @@ int Xdf::load_xdf(std::string filename) { } //for each sample - for (size_t i = 0; i < numSamp; i++) { + for (size_t i = 0; i < num_samples; i++) { //read or deduce time stamp - auto tsBytes = read_bin(file); + auto timestamp_bytes = read_bin(file); - double ts; //temporary time stamp + double timestamp; //temporary time stamp - if (tsBytes == 8) { - Xdf::read_bin(file, &ts); - streams_[index].timestamps.emplace_back(ts); + if (timestamp_bytes == 8) { + Xdf::read_bin(file, ×tamp); + streams_[index].timestamps.emplace_back(timestamp); } else { - ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].timestamps.emplace_back(ts); + timestamp = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].timestamps.emplace_back(timestamp); } - streams_[index].last_timestamp = ts; + streams_[index].last_timestamp = timestamp; //read the data for (int v = 0; v < streams_[index].info.channel_count; ++v) { @@ -239,22 +240,22 @@ int Xdf::load_xdf(std::string filename) { } //for each sample - for (size_t i = 0; i < numSamp; i++) { + for (size_t i = 0; i < num_samples; i++) { //read or deduce time stamp - auto tsBytes = read_bin(file); + auto timestamp_bytes = read_bin(file); - double ts; //temporary time stamp + double timestamp; //temporary time stamp - if (tsBytes == 8) { - Xdf::read_bin(file, &ts); - streams_[index].timestamps.emplace_back(ts); + if (timestamp_bytes == 8) { + Xdf::read_bin(file, ×tamp); + streams_[index].timestamps.emplace_back(timestamp); } else { - ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].timestamps.emplace_back(ts); + timestamp = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].timestamps.emplace_back(timestamp); } - streams_[index].last_timestamp = ts; + streams_[index].last_timestamp = timestamp; //read the data for (int v = 0; v < streams_[index].info.channel_count; ++v) { @@ -271,22 +272,22 @@ int Xdf::load_xdf(std::string filename) { } //for each sample - for (size_t i = 0; i < numSamp; i++) { + for (size_t i = 0; i < num_samples; i++) { //read or deduce time stamp - auto tsBytes = read_bin(file); + auto timestamp_bytes = read_bin(file); - double ts; //temporary time stamp + double timestamp; //temporary time stamp - if (tsBytes == 8) { - Xdf::read_bin(file, &ts); - streams_[index].timestamps.emplace_back(ts); + if (timestamp_bytes == 8) { + Xdf::read_bin(file, ×tamp); + streams_[index].timestamps.emplace_back(timestamp); } else { - ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].timestamps.emplace_back(ts); + timestamp = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].timestamps.emplace_back(timestamp); } - streams_[index].last_timestamp = ts; + streams_[index].last_timestamp = timestamp; //read the data for (int v = 0; v < streams_[index].info.channel_count; ++v) { @@ -303,22 +304,22 @@ int Xdf::load_xdf(std::string filename) { } //for each sample - for (size_t i = 0; i < numSamp; i++) { + for (size_t i = 0; i < num_samples; i++) { //read or deduce time stamp - auto tsBytes = read_bin(file); + auto timestamp_bytes = read_bin(file); - double ts; //temporary time stamp + double timestamp; //temporary time stamp - if (tsBytes == 8) { - Xdf::read_bin(file, &ts); - streams_[index].timestamps.emplace_back(ts); + if (timestamp_bytes == 8) { + Xdf::read_bin(file, ×tamp); + streams_[index].timestamps.emplace_back(timestamp); } else { - ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].timestamps.emplace_back(ts); + timestamp = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].timestamps.emplace_back(timestamp); } - streams_[index].last_timestamp = ts; + streams_[index].last_timestamp = timestamp; //read the data for (int v = 0; v < streams_[index].info.channel_count; ++v) { @@ -335,22 +336,22 @@ int Xdf::load_xdf(std::string filename) { } //for each sample - for (size_t i = 0; i < numSamp; i++) { + for (size_t i = 0; i < num_samples; i++) { //read or deduce time stamp - auto tsBytes = read_bin(file); + auto timestamp_bytes = read_bin(file); - double ts; //temporary time stamp + double timestamp; //temporary time stamp - if (tsBytes == 8) { - Xdf::read_bin(file, &ts); - streams_[index].timestamps.emplace_back(ts); + if (timestamp_bytes == 8) { + Xdf::read_bin(file, ×tamp); + streams_[index].timestamps.emplace_back(timestamp); } else { - ts = streams_[index].last_timestamp + streams_[index].sampling_interval; - streams_[index].timestamps.emplace_back(ts); + timestamp = streams_[index].last_timestamp + streams_[index].sampling_interval; + streams_[index].timestamps.emplace_back(timestamp); } - streams_[index].last_timestamp = ts; + streams_[index].last_timestamp = timestamp; //read the data for (int v = 0; v < streams_[index].info.channel_count; ++v) { @@ -362,17 +363,17 @@ int Xdf::load_xdf(std::string filename) { } else if (streams_[index].info.channel_format.compare("string") == 0) { //for each event - for (size_t i = 0; i < numSamp; i++) { + for (size_t i = 0; i < num_samples; i++) { //read or deduce time stamp - auto tsBytes = read_bin(file); + auto timestamp_bytes = read_bin(file); - double ts; //temporary time stamp + double timestamp; //temporary time stamp - if (tsBytes == 8) { - Xdf::read_bin(file, &ts); + if (timestamp_bytes == 8) { + Xdf::read_bin(file, ×tamp); } else { - ts = streams_[index].last_timestamp + streams_[index].sampling_interval; + timestamp = streams_[index].last_timestamp + streams_[index].sampling_interval; } //read the event @@ -381,9 +382,9 @@ int Xdf::load_xdf(std::string filename) { char* buffer = new char[length + 1]; file.read(buffer, length); buffer[length] = '\0'; - event_map_.emplace_back(std::make_pair(buffer, ts), index); + event_map_.emplace_back(std::make_pair(buffer, timestamp), index); delete[] buffer; - streams_[index].last_timestamp = ts; + streams_[index].last_timestamp = timestamp; } } } @@ -403,39 +404,38 @@ int Xdf::load_xdf(std::string filename) { index = std::distance(idmap.begin(), it); } - double collectionTime; - double offsetValue; + double collection_time; + double offset_value; - Xdf::read_bin(file, &collectionTime); - Xdf::read_bin(file, &offsetValue); + Xdf::read_bin(file, &collection_time); + Xdf::read_bin(file, &offset_value); - streams_[index].clock_times.emplace_back(collectionTime); - streams_[index].clock_values.emplace_back(offsetValue); + streams_[index].clock_times.emplace_back(collection_time); + streams_[index].clock_values.emplace_back(offset_value); } break; case 6: { // [StreamFooter] chunk pugi::xml_document doc; - //read [StreamID] - uint32_t streamID; + uint32_t stream_id; int index; - Xdf::read_bin(file, &streamID); - std::vector::iterator it {std::find(idmap.begin(),idmap.end(),streamID)}; + Xdf::read_bin(file, &stream_id); + std::vector::iterator it {std::find(idmap.begin(),idmap.end(),stream_id)}; if (it == idmap.end()) { index = idmap.size(); - idmap.emplace_back(streamID); + idmap.emplace_back(stream_id); streams_.emplace_back(); } else { index = std::distance(idmap.begin(), it); } - char* buffer = new char[ChLen - 6]; - file.read(buffer, ChLen - 6); + char* buffer = new char[channel_length - 6]; + file.read(buffer, channel_length - 6); streams_[index].stream_footer = buffer; - doc.load_buffer_inplace(buffer, ChLen - 6); + doc.load_buffer_inplace(buffer, channel_length - 6); pugi::xml_node info = doc.child("info"); @@ -448,7 +448,7 @@ int Xdf::load_xdf(std::string filename) { break; case 5: //skip other chunk types (Boundary, ...) - file.seekg(ChLen - 2, file.cur); + file.seekg(channel_length - 2, file.cur); break; default: std::cout << "Unknown chunk encountered.\n"; @@ -686,38 +686,38 @@ void Xdf::find_min_max_time_stamps() { void Xdf::find_major_sampling_rate() { // find out which sample rate has the most channels - typedef int sampRate; - typedef int numChannel; + typedef int SamplingRate; + typedef int ChannelCount; - std::vector > srateMap; // pairs of all the streams + std::vector > sampling_rate_map; //find out whether a sample rate already exists in srateMap for (auto const &stream : streams_) { if (stream.info.nominal_srate != 0) { - std::vector >::iterator it {std::find_if(srateMap.begin(), srateMap.end(), - [&](const std::pair &element) + std::vector >::iterator it {std::find_if(sampling_rate_map.begin(), sampling_rate_map.end(), + [&](const std::pair &element) {return element.first == stream.info.nominal_srate; })} ; //if it doesn't, add it here - if (it == srateMap.end()) { - srateMap.emplace_back(stream.info.nominal_srate, stream.info.channel_count); + if (it == sampling_rate_map.end()) { + sampling_rate_map.emplace_back(stream.info.nominal_srate, stream.info.channel_count); //if it already exists, add additional channel numbers to that sample rate } else { - int index (std::distance(srateMap.begin(),it)) ; - srateMap[index].second += stream.info.channel_count; + int index (std::distance(sampling_rate_map.begin(),it)) ; + sampling_rate_map[index].second += stream.info.channel_count; } } } - if (srateMap.size() > 0) { + if (sampling_rate_map.size() > 0) { //search the srateMap to see which sample rate has the most channels - int index (std::distance(srateMap.begin(), - std::max_element(srateMap.begin(),srateMap.end(), - [] (const std::pair &largest, - const std::pair &first) + int index (std::distance(sampling_rate_map.begin(), + std::max_element(sampling_rate_map.begin(),sampling_rate_map.end(), + [] (const std::pair &largest, + const std::pair &first) { return largest.second < first.second; }))); - major_sampling_rate_ = srateMap[index].first; //the sample rate that has the most channels + major_sampling_rate_ = sampling_rate_map[index].first; //the sample rate that has the most channels } else { major_sampling_rate_ = 0; //if there are no streams with a fixed sample reate } @@ -839,8 +839,8 @@ int Xdf::write_events_to_xdf(std::string file_path) { short tag = 2; file.write((char*)&tag, 2); //streamNumber - int streamNumber = user_added_stream_ + 1; //+1 because the stream IDs in XDF are 1 based instead of 0 based - file.write((char*)&streamNumber, 4); + int stream_number = user_added_stream_ + 1; //+1 because the stream IDs in XDF are 1 based instead of 0 based + file.write((char*)&stream_number, 4); //content file.write(streams_[user_added_stream_].stream_header.c_str(), length - 6);//length - 6 is the string length @@ -854,23 +854,23 @@ int Xdf::write_events_to_xdf(std::string file_path) { stringTotalLength += event.first.size(); } - int64_t sampleChunkLength = 2 + 4 + 1 + 4 + + int64_t sample_chunk_length = 2 + 4 + 1 + 4 + user_created_events_.size() * (1 + 8 + 1 + 4) + stringTotalLength; - file.write((char*)&sampleChunkLength, 8); + file.write((char*)&sample_chunk_length, 8); //tag tag = 3; file.write((char*)&tag, 2); //streamNumber - file.write((char*)&streamNumber, 4); + file.write((char*)&stream_number, 4); //content //NumSamplesBytes file.put(4); - //Num Samples - int numSamples = user_created_events_.size(); - file.write((char*)&numSamples, 4); + //Num samples + int sample_count = user_created_events_.size(); + file.write((char*)&sample_count, 4); //samples for (auto const &event : user_created_events_) { @@ -885,11 +885,11 @@ int Xdf::write_events_to_xdf(std::string file_path) { file.put(4); //Length - int stringLength = event.first.length(); - file.write((char*)&stringLength, 4); + int string_length = event.first.length(); + file.write((char*)&string_length, 4); //String Content - file.write(event.first.c_str(), stringLength); + file.write(event.first.c_str(), string_length); } file.close(); @@ -906,7 +906,7 @@ int Xdf::write_events_to_xdf(std::string file_path) { } void Xdf::create_labels() { - size_t channelCount = 0; + size_t channel_count = 0; for (size_t st = 0; st < streams_.size(); st++) { if (streams_[st].info.channels.size()) { @@ -918,18 +918,21 @@ void Xdf::create_labels() { label += streams_[st].info.name + '\n'; for (auto const &entry : streams_[st].info.channels[ch]) { - if (entry.second != "") + if (entry.second != "") { label += entry.first + " : " + entry.second + '\n'; + } } if (offsets_.size()) { - if (offsets_[channelCount] >= 0) - label.append("baseline +").append(std::to_string(offsets_[channelCount])); - else - label.append("baseline ").append(std::to_string(offsets_[channelCount])); + if (offsets_[channel_count] >= 0) { + label.append("baseline +").append(std::to_string(offsets_[channel_count])); + } + else { + label.append("baseline ").append(std::to_string(offsets_[channel_count])); + } } labels_.emplace_back(label); - channelCount++; + channel_count++; } } else { @@ -943,15 +946,17 @@ void Xdf::create_labels() { label += streams_[st].info.name + '\n'; if (offsets_.size()) { - if (offsets_[channelCount] >= 0) - label.append("baseline +").append(std::to_string(offsets_[channelCount])); - else - label.append("baseline ").append(std::to_string(offsets_[channelCount])); + if (offsets_[channel_count] >= 0) { + label.append("baseline +").append(std::to_string(offsets_[channel_count])); + } + else { + label.append("baseline ").append(std::to_string(offsets_[channel_count])); + } } labels_.emplace_back(label); - channelCount++; + channel_count++; } } } From ae2d0a732cbd57e7846529e9e978acb634119483 Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 15:32:15 -0700 Subject: [PATCH 07/10] Final cleanup --- xdf.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/xdf.cpp b/xdf.cpp index 9df24ac..194a22f 100644 --- a/xdf.cpp +++ b/xdf.cpp @@ -63,8 +63,7 @@ int Xdf::load_xdf(std::string filename) { std::string magic_number; for (char c; file >> c;) { magic_number.push_back(c); - if (magic_number.size() == 4) - break; + if (magic_number.size() == 4) break; } if (magic_number.compare("XDF:")) { @@ -673,14 +672,16 @@ void Xdf::find_min_max_time_stamps() { } } for (auto const &stream : streams_) { - if (!std::isnan(stream.info.first_timestamp) && stream.info.first_timestamp < min_timestamp_) + if (!std::isnan(stream.info.first_timestamp) && stream.info.first_timestamp < min_timestamp_) { min_timestamp_ = stream.info.first_timestamp; + } } //find the max timestamp of all streams for (auto const &stream : streams_) { - if (!std::isnan(stream.info.last_timestamp) && stream.info.last_timestamp > max_timestamp_) + if (!std::isnan(stream.info.last_timestamp) && stream.info.last_timestamp > max_timestamp_) { max_timestamp_ = stream.info.last_timestamp; + } } } @@ -695,12 +696,12 @@ void Xdf::find_major_sampling_rate() { for (auto const &stream : streams_) { if (stream.info.nominal_srate != 0) { std::vector >::iterator it {std::find_if(sampling_rate_map.begin(), sampling_rate_map.end(), - [&](const std::pair &element) + [&](const std::pair &element) {return element.first == stream.info.nominal_srate; })} ; //if it doesn't, add it here if (it == sampling_rate_map.end()) { sampling_rate_map.emplace_back(stream.info.nominal_srate, stream.info.channel_count); - //if it already exists, add additional channel numbers to that sample rate + //if it already exists, add additional channel numbers to that sample rate } else { int index (std::distance(sampling_rate_map.begin(),it)) ; @@ -755,7 +756,7 @@ void Xdf::free_up_timestamps() { void Xdf::adjust_total_length() { for (auto const &stream : streams_) { - if(!stream.time_series.empty()) { + if (!stream.time_series.empty()) { if (total_len_ < stream.time_series.front().size()) { total_len_ = stream.time_series.front().size(); } From 8d5ab8467f71c837d22b61832555303a58f04cb7 Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 19:12:06 -0700 Subject: [PATCH 08/10] More cleanup --- xdf.cpp | 2 +- xdf.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xdf.cpp b/xdf.cpp index 194a22f..7440df9 100644 --- a/xdf.cpp +++ b/xdf.cpp @@ -59,7 +59,7 @@ int Xdf::load_xdf(std::string filename) { std::ifstream file(filename, std::ios::in | std::ios::binary); if (file.is_open()) { - //read [MagicCode] + // read [MagicCode] std::string magic_number; for (char c; file >> c;) { magic_number.push_back(c); diff --git a/xdf.h b/xdf.h index d94bd27..d0ddcb9 100644 --- a/xdf.h +++ b/xdf.h @@ -93,14 +93,14 @@ class Xdf { * \brief An alias of std::string type used on event names. * \sa eventMap */ - typedef std::string event_name_; + typedef std::string EventName; /*! * \brief An alias of double type used on event timestamps. * \sa eventMap */ - typedef double event_timestamp_; + typedef double EventTimestamp; - std::vector, int>> event_map_; /*!< Stores all events across all streams. */ + std::vector, int>> event_map_; /*!< Stores all events across all streams. */ std::vector dictionary_; /*!< Stores unique event types with no repetitions. \sa event_map_ */ std::vector event_type_; /*!< Stores events by their indices in the dictionary.\sa dictionary_, event_map_ */ std::vector labels_; /*!< Stores descriptive labels of each channel. */ From 494bcd2cfe5c3d2a62dbf18e1b08d18f427388f6 Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 19:28:12 -0700 Subject: [PATCH 09/10] Re-ordered methods alphabetical order --- xdf.cpp | 557 ++++++++++++++++++++++++++++---------------------------- xdf.h | 27 +-- 2 files changed, 293 insertions(+), 291 deletions(-) diff --git a/xdf.cpp b/xdf.cpp index 7440df9..392eb48 100644 --- a/xdf.cpp +++ b/xdf.cpp @@ -33,6 +33,102 @@ Xdf::Xdf() { } +void Xdf::adjust_total_length() { + for (auto const &stream : streams_) { + if (!stream.time_series.empty()) { + if (total_len_ < stream.time_series.front().size()) { + total_len_ = stream.time_series.front().size(); + } + } + } +} + +void Xdf::calculate_total_length(int sampling_rate) { + total_len_ = (max_timestamp_ - min_timestamp_) * sampling_rate; +} + +void Xdf::create_labels() { + size_t channel_count = 0; + + for (size_t st = 0; st < streams_.size(); st++) { + if (streams_[st].info.channels.size()) { + for (size_t ch = 0; ch < streams_[st].info.channels.size(); ch++) { + // +1 for 1 based numbers; for user convenience only. The internal computation is still 0 based + std::string label = "Stream " + std::to_string(st + 1) + " - Channel " + std::to_string(ch + 1) + + " - " + std::to_string((int)streams_[st].info.nominal_srate) + " Hz\n"; + + label += streams_[st].info.name + '\n'; + + for (auto const &entry : streams_[st].info.channels[ch]) { + if (entry.second != "") { + label += entry.first + " : " + entry.second + '\n'; + } + } + if (offsets_.size()) { + if (offsets_[channel_count] >= 0) { + label.append("baseline +").append(std::to_string(offsets_[channel_count])); + } + else { + label.append("baseline ").append(std::to_string(offsets_[channel_count])); + } + } + labels_.emplace_back(label); + + channel_count++; + } + } + else { + for (size_t ch = 0; ch < streams_[st].time_series.size(); ch++) { + // +1 for 1 based numbers; for user convenience only. The internal computation is still 0 based + std::string label = "Stream " + std::to_string(st + 1) + + " - Channel " + std::to_string(ch + 1) + " - " + + std::to_string((int)streams_[st].info.nominal_srate) + + " Hz\n" + streams_[st].info.name + '\n' + streams_[st].info.type + '\n'; + + label += streams_[st].info.name + '\n'; + + if (offsets_.size()) { + if (offsets_[channel_count] >= 0) { + label.append("baseline +").append(std::to_string(offsets_[channel_count])); + } + else { + label.append("baseline ").append(std::to_string(offsets_[channel_count])); + } + } + + labels_.emplace_back(label); + + channel_count++; + } + } + } +} + +void Xdf::detrend() { + for (auto &stream : streams_) { + for (auto &row : stream.time_series) { + long double init = 0.0; + long double mean = std::accumulate(row.begin(), row.end(), init) / row.size(); + for(auto &val: row) val -= mean; + offsets_.emplace_back(mean); + } + } +} + +void Xdf::free_up_timestamps() { + //free up as much memory as possible + for (auto &stream : streams_) { + //we don't need to keep all the time stamps unless it's a stream with irregular samples + //filter irregular streams and string streams + if (stream.info.nominal_srate != 0 && !stream.timestamps.empty() && stream.info.channel_format.compare("string")) { + std::vector nothing; + //however we still need to keep the first time stamp of each stream to decide at which position the signal should start + nothing.emplace_back(stream.timestamps.front()); + stream.timestamps.swap(nothing); + } + } +} + int Xdf::load_xdf(std::string filename) { clock_t time; time = clock(); @@ -488,74 +584,6 @@ int Xdf::load_xdf(std::string filename) { return 0; } -void Xdf::sync_timestamps() { - // Sync time stamps - for (auto &stream : this->streams_) { - if (!stream.clock_times.empty()) { - size_t m = 0; // index iterating through stream.time_stamps - size_t n = 0; // index iterating through stream.clock_times - - while (m < stream.timestamps.size()) { - if (stream.clock_times[n] < stream.timestamps[m]) { - while (n < stream.clock_times.size() - 1 && stream.clock_times[n+1] < stream.timestamps[m]) { - n++; - } - stream.timestamps[m] += stream.clock_values[n]; - } - else if (n == 0) { - stream.timestamps[m] += stream.clock_values[n]; - } - m++; - } - } - } - - // Sync event time stamps - for (auto &elem : this->event_map_) { - if (!this->streams_[elem.second].clock_times.empty()) { - size_t k = 0; // index iterating through streams[elem.second].clock_times - - while (k < this->streams_[elem.second].clock_times.size() - 1) { - if (this->streams_[elem.second].clock_times[k+1] < elem.first.second) { - k++; - } - else { - break; - } - } - - elem.first.second += this->streams_[elem.second].clock_values[k]; // apply the last offset value to the timestamp; if there hasn't yet been an offset value take the first recorded one - } - } - - // Update first and last time stamps in stream footer - for (size_t k = 0; k < this->streams_.size(); k++) { - if (streams_[k].info.channel_format.compare("string") == 0) { - double min = NAN; - double max = NAN; - - for (auto const &elem : this->event_map_) { - if (elem.second == (int)k) { - if (std::isnan(min) || elem.first.second < min) { - min = elem.first.second; - } - - if (std::isnan(max) || elem.first.second > max) { - max = elem.first.second; - } - } - } - - streams_[k].info.first_timestamp = min; - streams_[k].info.last_timestamp = max; - } - else { - streams_[k].info.first_timestamp = streams_[k].timestamps.front(); - streams_[k].info.last_timestamp = streams_[k].timestamps.back(); - } - } -} - void Xdf::resample(int sampling_rate) { //if user entered a preferred sample rate, we resample all the channels to that sample rate //Otherwise, we resample all channels to the sample rate that has the most channels @@ -638,186 +666,70 @@ void Xdf::resample(int sampling_rate) { << " resampling" << std::endl; } -//function of reading the length of each chunk -uint64_t Xdf::read_length(std::ifstream &file) { - uint8_t bytes; - Xdf::read_bin(file, &bytes); - uint64_t length = 0; +void Xdf::sync_timestamps() { + // Sync time stamps + for (auto &stream : this->streams_) { + if (!stream.clock_times.empty()) { + size_t m = 0; // index iterating through stream.time_stamps + size_t n = 0; // index iterating through stream.clock_times - switch (bytes) { - case 1: - length = read_bin(file); - break; - case 4: - length = read_bin(file); - break; - case 8: - length = read_bin(file); - break; - default: - std::cout << "Invalid variable-length integer length (" - << static_cast(bytes) << ") encountered.\n"; - return 0; + while (m < stream.timestamps.size()) { + if (stream.clock_times[n] < stream.timestamps[m]) { + while (n < stream.clock_times.size() - 1 && stream.clock_times[n+1] < stream.timestamps[m]) { + n++; + } + stream.timestamps[m] += stream.clock_values[n]; + } + else if (n == 0) { + stream.timestamps[m] += stream.clock_values[n]; + } + m++; + } + } } - return length; -} + // Sync event time stamps + for (auto &elem : this->event_map_) { + if (!this->streams_[elem.second].clock_times.empty()) { + size_t k = 0; // index iterating through streams[elem.second].clock_times -void Xdf::find_min_max_time_stamps() { - //find the smallest timestamp of all streams - for (auto const &stream : streams_) { - if (!std::isnan(stream.info.first_timestamp)) { - min_timestamp_ = stream.info.first_timestamp; - break; - } - } - for (auto const &stream : streams_) { - if (!std::isnan(stream.info.first_timestamp) && stream.info.first_timestamp < min_timestamp_) { - min_timestamp_ = stream.info.first_timestamp; - } - } + while (k < this->streams_[elem.second].clock_times.size() - 1) { + if (this->streams_[elem.second].clock_times[k+1] < elem.first.second) { + k++; + } + else { + break; + } + } - //find the max timestamp of all streams - for (auto const &stream : streams_) { - if (!std::isnan(stream.info.last_timestamp) && stream.info.last_timestamp > max_timestamp_) { - max_timestamp_ = stream.info.last_timestamp; + elem.first.second += this->streams_[elem.second].clock_values[k]; // apply the last offset value to the timestamp; if there hasn't yet been an offset value take the first recorded one } } -} -void Xdf::find_major_sampling_rate() { - // find out which sample rate has the most channels - typedef int SamplingRate; - typedef int ChannelCount; + // Update first and last time stamps in stream footer + for (size_t k = 0; k < this->streams_.size(); k++) { + if (streams_[k].info.channel_format.compare("string") == 0) { + double min = NAN; + double max = NAN; - std::vector > sampling_rate_map; + for (auto const &elem : this->event_map_) { + if (elem.second == (int)k) { + if (std::isnan(min) || elem.first.second < min) { + min = elem.first.second; + } - //find out whether a sample rate already exists in srateMap - for (auto const &stream : streams_) { - if (stream.info.nominal_srate != 0) { - std::vector >::iterator it {std::find_if(sampling_rate_map.begin(), sampling_rate_map.end(), - [&](const std::pair &element) - {return element.first == stream.info.nominal_srate; })} ; - //if it doesn't, add it here - if (it == sampling_rate_map.end()) { - sampling_rate_map.emplace_back(stream.info.nominal_srate, stream.info.channel_count); - //if it already exists, add additional channel numbers to that sample rate - } - else { - int index (std::distance(sampling_rate_map.begin(),it)) ; - sampling_rate_map[index].second += stream.info.channel_count; - } - } - } - - if (sampling_rate_map.size() > 0) { - //search the srateMap to see which sample rate has the most channels - int index (std::distance(sampling_rate_map.begin(), - std::max_element(sampling_rate_map.begin(),sampling_rate_map.end(), - [] (const std::pair &largest, - const std::pair &first) - { return largest.second < first.second; }))); - - major_sampling_rate_ = sampling_rate_map[index].first; //the sample rate that has the most channels - } else { - major_sampling_rate_ = 0; //if there are no streams with a fixed sample reate - } -} - -void Xdf::calculate_channel_count() { - //calculating total channel count, and indexing them onto streamMap - for (size_t c = 0; c < streams_.size(); c++) { - if(!streams_[c].time_series.empty()) { - channel_count_ += streams_[c].info.channel_count; - - for (int i = 0; i < streams_[c].info.channel_count; i++) - stream_map_.emplace_back(c); - } - } -} - -void Xdf::calculate_total_length(int sampling_rate) { - total_len_ = (max_timestamp_ - min_timestamp_) * sampling_rate; -} - -void Xdf::free_up_timestamps() { - //free up as much memory as possible - for (auto &stream : streams_) { - //we don't need to keep all the time stamps unless it's a stream with irregular samples - //filter irregular streams and string streams - if (stream.info.nominal_srate != 0 && !stream.timestamps.empty() && stream.info.channel_format.compare("string")) { - std::vector nothing; - //however we still need to keep the first time stamp of each stream to decide at which position the signal should start - nothing.emplace_back(stream.timestamps.front()); - stream.timestamps.swap(nothing); - } - } -} - -void Xdf::adjust_total_length() { - for (auto const &stream : streams_) { - if (!stream.time_series.empty()) { - if (total_len_ < stream.time_series.front().size()) { - total_len_ = stream.time_series.front().size(); + if (std::isnan(max) || elem.first.second > max) { + max = elem.first.second; + } + } } - } - } -} -void Xdf::find_max_sampling_rate() { - for (auto const &stream : streams_) { - if (stream.info.nominal_srate > max_sampling_rate_) { - max_sampling_rate_ = stream.info.nominal_srate; - } - } -} - -void Xdf::load_sampling_rate_map() { - for (auto const &stream : streams_) { - sampling_rate_map_.emplace(stream.info.nominal_srate); - } -} - -void Xdf::detrend() { - for (auto &stream : streams_) { - for (auto &row : stream.time_series) { - long double init = 0.0; - long double mean = std::accumulate(row.begin(), row.end(), init) / row.size(); - for(auto &val: row) val -= mean; - offsets_.emplace_back(mean); + streams_[k].info.first_timestamp = min; + streams_[k].info.last_timestamp = max; } - } -} - -void Xdf::calculate_effective_sampling_rate() { - for (auto &stream : streams_) { - if (stream.info.nominal_srate) { - try { - stream.info.effective_sampling_rate - = stream.info.sample_count / - (stream.info.last_timestamp - stream.info.first_timestamp); - - if (stream.info.effective_sampling_rate) { - effective_sampling_rates_.emplace_back(stream.info.effective_sampling_rate); - } - - pugi::xml_document doc; - doc.load_string(stream.stream_footer.c_str()); - pugi::xml_node sampleCount = doc.child("info").child("sample_count"); - pugi::xml_node effectiveSampleRate - = doc.child("info").insert_child_after("effective_sample_rate", sampleCount); - effectiveSampleRate.append_child(pugi::node_pcdata) - .set_value(std::to_string(stream.info.effective_sampling_rate).c_str()); - - std::stringstream buffer; - doc.save(buffer); - - stream.stream_footer = buffer.str(); - } - catch (std::exception &e) { - std::cerr << "Error calculating effective sample rate. " - << e.what() << std::endl; - } + else { + streams_[k].info.first_timestamp = streams_[k].timestamps.front(); + streams_[k].info.last_timestamp = streams_[k].timestamps.back(); } } } @@ -906,61 +818,118 @@ int Xdf::write_events_to_xdf(std::string file_path) { return 0; //Success } -void Xdf::create_labels() { - size_t channel_count = 0; +void Xdf::calculate_effective_sampling_rate() { + for (auto &stream : streams_) { + if (stream.info.nominal_srate) { + try { + stream.info.effective_sampling_rate + = stream.info.sample_count / + (stream.info.last_timestamp - stream.info.first_timestamp); - for (size_t st = 0; st < streams_.size(); st++) { - if (streams_[st].info.channels.size()) { - for (size_t ch = 0; ch < streams_[st].info.channels.size(); ch++) { - // +1 for 1 based numbers; for user convenience only. The internal computation is still 0 based - std::string label = "Stream " + std::to_string(st + 1) + " - Channel " + std::to_string(ch + 1) - + " - " + std::to_string((int)streams_[st].info.nominal_srate) + " Hz\n"; + if (stream.info.effective_sampling_rate) { + effective_sampling_rates_.emplace_back(stream.info.effective_sampling_rate); + } - label += streams_[st].info.name + '\n'; + pugi::xml_document doc; + doc.load_string(stream.stream_footer.c_str()); + pugi::xml_node sampleCount = doc.child("info").child("sample_count"); + pugi::xml_node effectiveSampleRate + = doc.child("info").insert_child_after("effective_sample_rate", sampleCount); + effectiveSampleRate.append_child(pugi::node_pcdata) + .set_value(std::to_string(stream.info.effective_sampling_rate).c_str()); - for (auto const &entry : streams_[st].info.channels[ch]) { - if (entry.second != "") { - label += entry.first + " : " + entry.second + '\n'; - } - } - if (offsets_.size()) { - if (offsets_[channel_count] >= 0) { - label.append("baseline +").append(std::to_string(offsets_[channel_count])); - } - else { - label.append("baseline ").append(std::to_string(offsets_[channel_count])); - } - } - labels_.emplace_back(label); + std::stringstream buffer; + doc.save(buffer); - channel_count++; + stream.stream_footer = buffer.str(); + } + catch (std::exception &e) { + std::cerr << "Error calculating effective sample rate. " + << e.what() << std::endl; } } - else { - for (size_t ch = 0; ch < streams_[st].time_series.size(); ch++) { - // +1 for 1 based numbers; for user convenience only. The internal computation is still 0 based - std::string label = "Stream " + std::to_string(st + 1) + - " - Channel " + std::to_string(ch + 1) + " - " + - std::to_string((int)streams_[st].info.nominal_srate) + - " Hz\n" + streams_[st].info.name + '\n' + streams_[st].info.type + '\n'; + } +} - label += streams_[st].info.name + '\n'; +void Xdf::calculate_channel_count() { + //calculating total channel count, and indexing them onto streamMap + for (size_t c = 0; c < streams_.size(); c++) { + if(!streams_[c].time_series.empty()) { + channel_count_ += streams_[c].info.channel_count; - if (offsets_.size()) { - if (offsets_[channel_count] >= 0) { - label.append("baseline +").append(std::to_string(offsets_[channel_count])); - } - else { - label.append("baseline ").append(std::to_string(offsets_[channel_count])); - } - } + for (int i = 0; i < streams_[c].info.channel_count; i++) + stream_map_.emplace_back(c); + } + } +} - labels_.emplace_back(label); +void Xdf::find_major_sampling_rate() { + // find out which sample rate has the most channels + typedef int SamplingRate; + typedef int ChannelCount; - channel_count++; + std::vector > sampling_rate_map; + + //find out whether a sample rate already exists in srateMap + for (auto const &stream : streams_) { + if (stream.info.nominal_srate != 0) { + std::vector >::iterator it {std::find_if(sampling_rate_map.begin(), sampling_rate_map.end(), + [&](const std::pair &element) + {return element.first == stream.info.nominal_srate; })} ; + //if it doesn't, add it here + if (it == sampling_rate_map.end()) { + sampling_rate_map.emplace_back(stream.info.nominal_srate, stream.info.channel_count); + //if it already exists, add additional channel numbers to that sample rate + } + else { + int index (std::distance(sampling_rate_map.begin(),it)) ; + sampling_rate_map[index].second += stream.info.channel_count; } } } + + if (sampling_rate_map.size() > 0) { + //search the srateMap to see which sample rate has the most channels + int index (std::distance(sampling_rate_map.begin(), + std::max_element(sampling_rate_map.begin(),sampling_rate_map.end(), + [] (const std::pair &largest, + const std::pair &first) + { return largest.second < first.second; }))); + + major_sampling_rate_ = sampling_rate_map[index].first; //the sample rate that has the most channels + } else { + major_sampling_rate_ = 0; //if there are no streams with a fixed sample reate + } +} + +void Xdf::find_max_sampling_rate() { + for (auto const &stream : streams_) { + if (stream.info.nominal_srate > max_sampling_rate_) { + max_sampling_rate_ = stream.info.nominal_srate; + } + } +} + +void Xdf::find_min_max_time_stamps() { + //find the smallest timestamp of all streams + for (auto const &stream : streams_) { + if (!std::isnan(stream.info.first_timestamp)) { + min_timestamp_ = stream.info.first_timestamp; + break; + } + } + for (auto const &stream : streams_) { + if (!std::isnan(stream.info.first_timestamp) && stream.info.first_timestamp < min_timestamp_) { + min_timestamp_ = stream.info.first_timestamp; + } + } + + //find the max timestamp of all streams + for (auto const &stream : streams_) { + if (!std::isnan(stream.info.last_timestamp) && stream.info.last_timestamp > max_timestamp_) { + max_timestamp_ = stream.info.last_timestamp; + } + } } void Xdf::load_dictionary() { @@ -982,9 +951,41 @@ void Xdf::load_dictionary() { } } -template T Xdf::read_bin(std::istream& is, T* obj) { +void Xdf::load_sampling_rate_map() { + for (auto const &stream : streams_) { + sampling_rate_map_.emplace(stream.info.nominal_srate); + } +} + +template +T Xdf::read_bin(std::istream& is, T* obj) { T dummy; if(!obj) obj = &dummy; is.read(reinterpret_cast(obj), sizeof(T)); return *obj; } + +//function of reading the length of each chunk +uint64_t Xdf::read_length(std::ifstream &file) { + uint8_t bytes; + Xdf::read_bin(file, &bytes); + uint64_t length = 0; + + switch (bytes) { + case 1: + length = read_bin(file); + break; + case 4: + length = read_bin(file); + break; + case 8: + length = read_bin(file); + break; + default: + std::cout << "Invalid variable-length integer length (" + << static_cast(bytes) << ") encountered.\n"; + return 0; + } + + return length; +} diff --git a/xdf.h b/xdf.h index d0ddcb9..180cec4 100644 --- a/xdf.h +++ b/xdf.h @@ -251,18 +251,6 @@ class Xdf { */ void load_sampling_rate_map(); - /*! - * \brief Gets the length of the upcoming chunk, or the number of samples. - * - * While loading XDF file there are two cases where this method are needed. - * One is to get the length of each chunk, the other is to get the number - * of samples when loading the time series (Chunk tag 3). - * - * \param file The XDF file that is being loaded in the type of `std::ifstream`. - * \return The length of the upcoming chunk (in bytes). - */ - uint64_t read_length(std::ifstream &file); - /*! * \brief Reads a binary scalar variable from an input stream. * @@ -278,7 +266,20 @@ class Xdf { * \param obj Pointer to a variable to load the data into or nullptr. * \return The read data. */ - template T read_bin(std::istream& is, T* obj = nullptr); + template + T read_bin(std::istream& is, T* obj = nullptr); + + /*! + * \brief Gets the length of the upcoming chunk, or the number of samples. + * + * While loading XDF file there are two cases where this method are needed. + * One is to get the length of each chunk, the other is to get the number + * of samples when loading the time series (Chunk tag 3). + * + * \param file The XDF file that is being loaded in the type of `std::ifstream`. + * \return The length of the upcoming chunk (in bytes). + */ + uint64_t read_length(std::ifstream &file); }; #endif // XDF_H From 869443f4330514ac20ea0e06b0f59a48cdfe84b2 Mon Sep 17 00:00:00 2001 From: Yida Lin Date: Sun, 17 May 2020 19:31:09 -0700 Subject: [PATCH 10/10] clean up --- xdf.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/xdf.cpp b/xdf.cpp index 392eb48..1916a24 100644 --- a/xdf.cpp +++ b/xdf.cpp @@ -965,7 +965,6 @@ T Xdf::read_bin(std::istream& is, T* obj) { return *obj; } -//function of reading the length of each chunk uint64_t Xdf::read_length(std::ifstream &file) { uint8_t bytes; Xdf::read_bin(file, &bytes);