diff --git a/Documentation/Getting Started/fonts/slate.eot b/Documentation/Getting Started/fonts/slate.eot new file mode 100644 index 000000000..13c4839a1 Binary files /dev/null and b/Documentation/Getting Started/fonts/slate.eot differ diff --git a/Documentation/Getting Started/fonts/slate.svg b/Documentation/Getting Started/fonts/slate.svg new file mode 100644 index 000000000..5f3498230 --- /dev/null +++ b/Documentation/Getting Started/fonts/slate.svg @@ -0,0 +1,14 @@ + + + +Generated by IcoMoon + + + + + + + + + + diff --git a/Documentation/Getting Started/fonts/slate.ttf b/Documentation/Getting Started/fonts/slate.ttf new file mode 100644 index 000000000..ace9a46a7 Binary files /dev/null and b/Documentation/Getting Started/fonts/slate.ttf differ diff --git a/Documentation/Getting Started/fonts/slate.woff b/Documentation/Getting Started/fonts/slate.woff new file mode 100644 index 000000000..1e72e0ee0 Binary files /dev/null and b/Documentation/Getting Started/fonts/slate.woff differ diff --git a/Documentation/Getting Started/fonts/slate.woff2 b/Documentation/Getting Started/fonts/slate.woff2 new file mode 100644 index 000000000..7c585a727 Binary files /dev/null and b/Documentation/Getting Started/fonts/slate.woff2 differ diff --git a/Documentation/Getting Started/images/logo.png b/Documentation/Getting Started/images/logo.png new file mode 100644 index 000000000..e714fa5b8 Binary files /dev/null and b/Documentation/Getting Started/images/logo.png differ diff --git a/Documentation/Getting Started/images/logo_old.png b/Documentation/Getting Started/images/logo_old.png new file mode 100644 index 000000000..68a478fae Binary files /dev/null and b/Documentation/Getting Started/images/logo_old.png differ diff --git a/Documentation/Getting Started/images/navbar.png b/Documentation/Getting Started/images/navbar.png new file mode 100644 index 000000000..df38e90d8 Binary files /dev/null and b/Documentation/Getting Started/images/navbar.png differ diff --git a/Documentation/Getting Started/index.html b/Documentation/Getting Started/index.html new file mode 100644 index 000000000..6a1d17613 --- /dev/null +++ b/Documentation/Getting Started/index.html @@ -0,0 +1,1108 @@ + + + + + + + MSCL Quick Start Guide + + + + + + + + + + + NAV + Navbar + + +
+ Logo +
+ C++ + C# + Python +
+ + +
+
+ +
+
+
+
+

Introduction

//get the version of MSCL (MSCL_VERSION.majorPart(), .minorPart(), and .patchPart() are also available)
+cout << mscl::MSCL_VERSION.str() << endl;
+
//get the version of MSCL (MSCL_VERSION.majorPart(), .minorPart(), and .patchPart() are also available)
+Console.WriteLine(mscl.MSCL_VERSION.ToString());
+
# get the version of MSCL (MSCL_VERSION.majorPart(), .minorPart(), and .patchPart() are also available)
+print mscl.MSCL_VERSION
+
+

Welcome to the MSCL (MicroStrain Communication Library) Quick Start Guide!

+ +

You can use MSCL to interact with sensors developed by LORD Sensing.

+ +

MSCL has language bindings in C++, .NET (C#, VB, LabView, MATLAB), and Python! You can view code examples in the area to the right, and you can switch the programming language of the examples with the tabs above that.

+ +

This guide will help get you started with using MSCL. It does not encompass everything that MSCL can do. Please see the complete Documentation for a list of all functionality.

+ +

For simplicity, the examples below do not show the necessary error handling that should be performed when using MSCL. Please see the API Documentation for details on Exceptions that each function can throw.

+

Wireless

Creating a BaseStation

#include "mscl/mscl.h"
+
+//create the connection object with port and baud rate
+mscl::Connection connection = mscl::Connection::Serial("COM3", 921600);
+
+//create the BaseStation, passing in the connection
+mscl::BaseStation basestation(connection);
+
//create the connection object with port and baud rate
+mscl.Connection connection = mscl.Connection.Serial("COM3", 921600);
+
+//create the BaseStation, passing in the connection
+mscl.BaseStation basestation = new mscl.BaseStation(connection);
+
import mscl
+
+#create the connection object with port and baud rate
+connection = mscl.Connection.Serial("COM3", 921600)
+
+#create the BaseStation, passing in the connection
+basestation = mscl.BaseStation(connection)
+
+
+

Make sure to replace COM3 and 921600 with your own port settings.

+
+ +

To interface with a wireless device, you will first need to create a BaseStation that represents a physical BaseStation or Gateway.

+ +

A BaseStation takes a Connection as a parameter.

+ +

Serial, TcpIp, and UnixSocket are all available as connection types.

+ + +

Creating a WirelessNode


+//create a WirelessNode with the BaseStation
+mscl::WirelessNode node(31849, baseStation);
+
//create a WirelessNode with the BaseStation we created
+mscl.WirelessNode node = new mscl.WirelessNode(31849, baseStation);
+
# create a WirelessNode with the BaseStation we created
+node = mscl.WirelessNode(31849, baseStation)
+
+
+

Make sure to replace 31849 with the Node Address of your Wireless Node.

+
+ +

To communicate with any Wireless Node, create a WirelessNode instance, providing the Node Address of the physical Node, and the BaseStation that you wish to communicate to the Node with.

+ + +

Communicating with a Node

//ping the Node
+mscl::PingResponse response = node.ping();
+
+//if the ping response was a success
+if(response.success()) 
+{
+    response.baseRssi(); //the BaseStation RSSI
+    response.nodeRssi(); //the Node RSSI
+}
+
//ping the Node
+mscl.PingResponse response = node.ping();
+
+//if the ping response was a success
+if (response.success())
+{
+    response.baseRssi(); //the BaseStation RSSI
+    response.nodeRssi(); //the Node RSSI
+}
+
# ping the Node
+response = node.ping()
+
+# if the ping response was a success
+if response.success():
+    response.baseRssi() # the BaseStation RSSI
+    response.nodeRssi() # the Node RSSI
+
+

A Wireless Node, when powered on, can be in 1 of 3 states:

+ + + + + + + + + + + + + + + + + + + +
Node StateDescription
IdleThe Node is awake and waiting for commands.
SleepThe Node is in a low power sleep state.
SamplingThe Node is actively sampling / sending data.
+ +

If a Node is in an Idle state, it will respond to pings, can be configured, and can be put into the other states (sleep or sampling). To test communicating with a WirelessNode that is in an idle state, use the ping() function.

+
//call the setToIdle function and get the resulting SetToIdleStatus object
+mscl::SetToIdleStatus idleStatus = node.setToIdle();
+
+// checks if the set to idle operation has completed (successfully or with a failure)
+while(!idleStatus.complete())
+{
+    cout << ".";
+
+    if(userCancels)
+        idleStatus.cancel();
+}
+
+//check the result of the Set to Idle operation
+switch(idleStatus.result())
+{
+case mscl::SetToIdleStatus::setToIdleResult_success:
+    cout << "Node is now in idle mode." << endl;
+    break;
+
+case mscl::SetToIdleStatus::setToIdleResult_canceled:
+    cout << "Set to Idle was canceled!" << endl;
+    break;
+
+case mscl::SetToIdleStatus::setToIdleResult_failed:
+    cout << "Set to Idle has failed!" << endl;
+    break;
+}
+
//call the setToIdle function and get the resulting SetToIdleStatus object
+mscl.SetToIdleStatus idleStatus = node.setToIdle();
+
+// checks if the Set to Idle operation has completed (successfully or with a failure)
+while (!idleStatus.complete())
+{
+    Console.Write(".");
+
+    if(userCancels)
+        idleStatus.cancel();
+}
+
+//check the result of the Set to Idle operation
+switch (idleStatus.result())
+{
+    case mscl.SetToIdleStatus.SetToIdleResult.setToIdleResult_success:
+        Console.WriteLine("Node is now in idle mode.");
+        break;
+
+    case mscl.SetToIdleStatus.SetToIdleResult.setToIdleResult_canceled:
+        Console.WriteLine("Set to Idle was canceled!");
+        break;
+
+    case mscl.SetToIdleStatus.SetToIdleResult.setToIdleResult_failed:
+        Console.WriteLine("Set to Idle has failed!");
+        break;
+}
+
# call the setToIdle function and get the resulting SetToIdleStatus object
+idleStatus = node.setToIdle()
+
+# checks if the Set to Idle operation has completed (successfully or with a failure)
+while not idleStatus.complete():
+    print ".",
+
+    if userCancels:
+        idleStatus.cancel()
+
+# check the result of the Set to Idle operation
+result = idleStatus.result()
+if result == mscl.SetToIdleStatus.setToIdleResult_success:
+    print "Node is now in idle mode."
+elif result == mscl.SetToIdleStatus.setToIdleResult_canceled:
+    print "Set to Idle was canceled!"
+else:
+    print "Set to Idle has failed!"
+
+

If a Node is in the Sleep state or Sampling state, it cannot be directly communicated with. In order to communicate with the Node, it must be put back into the Idle state. This can be done by using the setToIdle() function.

+ +

The Set to Idle operation uses all of the BaseStation's bandwidth to attempt to stop/wake the Node. Thus, this can only be performed on a single Node at a time. Once started, the operation will continue until canceled by calling the cancel() function on the SetToIdleStatus object returned from the setToIdle() function.

+

Configuring a Node

Getting Current Config

//get the number of datalogging sessions stored on the node
+node.getNumDatalogSessions();  
+
+//get the user inactivity timeout in seconds
+node.getInactivityTimeout();
+
+//get the ActiveChannels
+node.getActiveChannels();
+
+//get the number of sweeps to sample for
+node.getNumSweeps();
+
+//verify Thermocouple Type is supported by this Node
+if(node.features().supportsThermocoupleType())
+{
+    //get the thermocouple type
+    node.getThermocoupleType();
+}
+
//get the number of datalogging sessions stored on the node
+node.getNumDatalogSessions();  
+
+//get the user inactivity timeout in seconds
+node.getInactivityTimeout();
+
+//get the ActiveChannels
+node.getActiveChannels();
+
+//get the number of sweeps to sample for
+node.getNumSweeps();
+
+//verify Thermocouple Type is supported by this Node
+if(node.features().supportsThermocoupleType())
+{
+    //get the thermocouple type
+    node.getThermocoupleType();
+}
+
# get the number of datalogging sessions stored on the node
+node.getNumDatalogSessions()
+
+# get the user inactivity timeout in seconds
+node.getInactivityTimeout()
+
+# get the ActiveChannels
+node.getActiveChannels()
+
+# get the number of sweeps to sample for
+node.getNumSweeps()
+
+# verify Thermocouple Type is supported by this Node
+if node.features().supportsThermocoupleType():
+    # get the thermocouple type
+    node.getThermocoupleType()
+
+

To get the current configuration settings of a Wireless Node, each setting has an individual function on the WirelessNode object.

+ +

However, not all settings are supported by all Nodes. If a function is called (such as getThermocoupleType()) on a Node that doesn't support that feature (doesn't support thermocouples), it will throw an Error_NotSupported exception.

+ +

Use the NodeFeatures class (node.features()) to check which features are available for the Wireless Node.

+ +





+



+



+

+

Setting the Config

//create a WirelessNodeConfig which is used to set all node configuration options
+mscl::WirelessNodeConfig config;
+
+//set the configuration options that we want to change
+config.bootMode(mscl::WirelessTypes::bootMode_normal);
+config.inactivityTimeout(7200);
+config.samplingMode(mscl::WirelessTypes::samplingMode_sync);
+config.sampleRate(mscl::WirelessTypes::sampleRate_256Hz);
+config.unlimitedDuration(true);
+
+//apply the configuration to the Node
+node.applyConfig(config);
+
//create a WirelessNodeConfig which is used to set all node configuration options
+mscl.WirelessNodeConfig config = new mscl.WirelessNodeConfig();
+
+//set some of the node's configuration options
+config.bootMode(mscl.WirelessTypes.BootMode.bootMode_normal);
+config.inactivityTimeout(7200);
+config.samplingMode(mscl.WirelessTypes.SamplingMode.samplingMode_sync);
+config.sampleRate(mscl.WirelessTypes.WirelessSampleRate.sampleRate_256Hz);
+config.unlimitedDuration(true);
+
+//apply the configuration to the Node
+node.applyConfig(config);
+
# create a WirelessNodeConfig which is used to set all node configuration options
+config = mscl.WirelessNodeConfig()
+
+# set the configuration options that we want to change
+config.bootMode(mscl.WirelessTypes.bootMode_normal)
+config.inactivityTimeout(7200)
+config.samplingMode(mscl.WirelessTypes.samplingMode_sync)
+config.sampleRate(mscl.WirelessTypes.sampleRate_256Hz)
+config.unlimitedDuration(True)
+
+# apply the configuration to the Node
+node.applyConfig(config)
+
+
+

These are just some examples of the Wireless Node config options available. See the complete API Documentation for the full list of available options.

+
+ +

To change configuration settings of a Wireless Nodes, use the WirelessNodeConfig object. This object contains functions for all Wireless Node config options.

+ +

When setting an option in the WirelessNodeConfig, the value is just stored on that object itself. The object must then be given as a parameter in the node.applyConfig() function to write all of the changed options to the physical Node. In this way, you can apply the same WirelessNodeConfig object to multiple Nodes if desired.

+ +

Some of the configuration options may conflict with other options that are being set, or that are currently set on the Wireless Node. For example, only certain Sample Rates are supported in the Burst Sync Sampling mode. If you only update the WirelessNodeConfig object's sample rate, this will be checked against the current sampling mode on the Node when applying and will throw an Error_InvalidNodeConfig exception if it is invalid for that sampling mode. If both the sample rate and sampling mode are set in the WirelessNodeConfig, they will be checked against each other before applying to the Node.

+ +

Not all settings are supported by all Nodes. If the WirelessNodeConfig has an option set (such as thermocoupleType()) and that config is applied to a Node that doesn't support that feature (doesn't support thermocouples), it will throw an Error_InvalidNodeConfig exception.

+ +

Use the NodeFeatures class (node.features()) to check which features are available for the Wireless Node.

+

Starting Sampling

+

There are 2 main sampling modes: Synchronized Sampling and Non-Synchronized Sampling.

+
//create a SyncSamplingNetwork object, giving it the BaseStation that will be the master BaseStation for the network
+mscl::SyncSamplingNetwork network(baseStation);
+
+//add a WirelessNode to the network.
+//Note: The Node must already be configured for Sync Sampling before adding to the network, or else Error_InvalidNodeConfig will be thrown.
+network.addNode(node);
+
+network.ok();               //check if the network status is ok
+network.lossless(true);     //enable Lossless for the network
+network.percentBandwidth(); //get the total percent of bandwidth of the network
+
+//apply the network configuration to every node in the network
+network.applyConfiguration();
+
+//start all the nodes in the network sampling.
+network.startSampling();
+
//create a SyncSamplingNetwork object, giving it the BaseStation that will be the master BaseStation for the network
+mscl.SyncSamplingNetwork network = new mscl.SyncSamplingNetwork(baseStation);
+
+//add a WirelessNode to the network.
+//Note: The Node must already be configured for Sync Sampling before adding to the network, or else Error_InvalidNodeConfig will be thrown.
+network.addNode(node);
+
+network.ok();               //check if the network status is ok
+network.lossless(true);     //enable Lossless for the network
+network.percentBandwidth(); //get the total percent of bandwidth of the network
+
+//apply the network configuration to every node in the network
+network.applyConfiguration();
+
+//start all the nodes in the network sampling.
+network.startSampling();
+
# create a SyncSamplingNetwork object, giving it the BaseStation that will be the master BaseStation for the network
+network = mscl.SyncSamplingNetwork(baseStation)
+
+# add a WirelessNode to the network.
+# Note: The Node must already be configured for Sync Sampling before adding to the network, or else Error_InvalidNodeConfig will be thrown.
+network.addNode(node)
+
+network.ok()                # check if the network status is ok
+network.lossless(true)      # enable Lossless for the network
+network.percentBandwidth()  # get the total percent of bandwidth of the network
+
+# apply the network configuration to every node in the network
+network.applyConfiguration()
+
+# start all the nodes in the network sampling.
+network.startSampling()
+

Synchronized Sampling

+

Synchronized Sampling involves creating a Time Division Multiple Access (TDMA) network with one or more Wireless Nodes tied to a single Base Station. In this mode, all of the Nodes will have a common timestamp that is transmitted with the data, so that data can be accurately aligned. +The BaseStation provides a beacon which keeps the Nodes in the network time-synchronized to +/- 32 microseconds.

+ +

To start a Sync Sampling network, create a SyncSamplingNetwork instance. This takes a BaseStation as a parameter, which will be the master BaseStation that communicates with all of the Nodes, starts them sampling, and provides the beacon.

+ +

After you have configured all of the Nodes, add them to the network using the networks addNode() function.

+ +

Once all of the Nodes have been added to the network, start the network using the network's startSampling() function.

+ + +
//start the Non-Sync Sampling session.
+node.startNonSyncSampling();
+
//start the Non-Sync Sampling session.
+node.startNonSyncSampling();
+
# start the Non-Sync Sampling session.
+node.startNonSyncSampling()
+

Non-Synchronized Sampling

+

Non-Synchronized Sampling requires no beacon, or network. Instead, each Node is set to sample individually. This mode has much lower latency than Synchronized Sampling.

+ +

Since there is no synchronization, there is a high chance of data loss, as Nodes could send their data at the same time as other Nodes, resulting in a loss of packets. This sampling mode also does not transmit timestamps with the data. Instead, timestamps will be assigned to the data when MSCL receives it.

+ +

To start a Non-Sync Sampling network, use the startNonSyncSampling() function on the WirelessNode object.

+

Collecting Data

//create the BaseStation, passing in the connection
+mscl::BaseStation basestation(connection);
+
+while(true)
+{
+    //get all the data sweeps that have been collected, with a timeout of 500 milliseconds
+    mscl::DataSweeps sweeps = basestation.getData(500);
+
+    for(mscl::DataSweep sweep : sweeps)
+    {
+        sweep.nodeAddress();    //the node address the sweep is from
+        sweep.timestamp();      //the TimeStamp of the sweep
+        sweep.tick();           //the tick of the sweep (0 - 65535 counter)
+        sweep.sampleRate();     //the sample rate of the sweep
+        sweep.samplingType();   //the SamplingType of the sweep (sync, nonsync, burst, etc.)
+        sweep.nodeRssi();       //the signal strength at the Node
+        sweep.baseRssi();       //the signal strength at the BaseStation
+        sweep.frequency();      //the radio frequency this was collected on
+
+        //get the vector of data in the sweep
+        mscl::ChannelData data = sweep.data();
+
+        //iterate over each point in the sweep (one point per channel)
+        for(mscl::WirelessDataPoint dataPoint : data)
+        {
+            dataPoint.channelName();    //the name of the channel for this point
+            dataPoint.storedAs();       //the ValueType that the data is stored as
+            dataPoint.as_float();       //get the value as a float
+        }
+    }
+}
+
//create the BaseStation, passing in the connection
+mscl.BaseStation basestation = new mscl.BaseStation(connection);
+
+while(true)
+{
+    //get all the data sweeps that have been collected, with a timeout of 500 milliseconds
+    mscl.DataSweeps sweeps = basestation.getData(500);
+
+    foreach(mscl.DataSweep sweep in sweeps)
+    {
+        sweep.nodeAddress();    //the node address the sweep is from
+        sweep.timestamp();      //the TimeStamp of the sweep
+        sweep.tick();           //the tick of the sweep (0 - 65535 counter)
+        sweep.sampleRate();     //the sample rate of the sweep
+        sweep.samplingType();   //the SamplingType of the sweep (sync, nonsync, burst, etc.)
+        sweep.nodeRssi();       //the signal strength at the Node
+        sweep.baseRssi();       //the signal strength at the BaseStation
+        sweep.frequency();      //the radio frequency this was collected on
+
+        //get the vector of data in the sweep
+        mscl.ChannelData data = sweep.data();
+
+        //iterate over each point in the sweep (one point per channel)
+        foreach(mscl.WirelessDataPoint dataPoint in data)
+        {
+            dataPoint.channelName();    //the name of the channel for this point
+            dataPoint.storedAs();       //the ValueType that the data is stored as
+            dataPoint.as_float();       //get the value as a float
+        }
+    }
+}
+
#create the BaseStation, passing in the connection
+basestation = mscl.BaseStation(connection)
+
+while True:
+
+    # get all the data sweeps that have been collected, with a timeout of 500 milliseconds
+    sweeps = basestation.getData(500)
+
+    for sweep in sweeps:
+        sweep.nodeAddress()    # the node address the sweep is from
+        sweep.timestamp()      # the TimeStamp of the sweep
+        sweep.tick()           # the tick of the sweep (0 - 65535 counter)
+        sweep.sampleRate()     # the sample rate of the sweep
+        sweep.samplingType()   # the SamplingType of the sweep (sync, nonsync, burst, etc.)
+        sweep.nodeRssi()       # the signal strength at the Node
+        sweep.baseRssi()       # the signal strength at the BaseStation
+        sweep.frequency()      # the radio frequency this was collected on
+
+        # get the vector of data in the sweep
+        data = sweep.data()
+
+        # iterate over each point in the sweep (one point per channel)
+        for dataPoint in data:
+            dataPoint.channelName()    # the name of the channel for this point
+            dataPoint.storedAs()       # the ValueType that the data is stored as
+            dataPoint.as_float()       # get the value as a float
+
+
+

as_float() returns the dataPoint value as a 4-byte float. However there are more options, such as as_uint16(), as_double(), as_string(), etc. The ValueType that is returned from the storedAs() function determines how the data is actually stored.

+
+ +

As soon as the BaseStation object is created, all incoming packets will be parsed and stored in an internal circular buffer.

+ +

So if a Wireless Node is already sampling on the same frequency as your BaseStation, you can simply access and consume the data that is being transmitted.

+ +

basestation.getData() will return a vector of DataSweep objects. This will contain all of the sweeps that have been collected after the BaseStation object was created.

+ +

Each DataSweep contains various information describing it. The DataSweep's data() function will return a vector of WirelessDataPoint objects. This will have one point for each active channel that was enabled on the Node.

+ +

Each data point will be stored as a certain type. The datapoint's storedAs() function will return an enum specifying which type the data is stored in (valueType_float, valueType_uint16, etc).

+ +

Using this information, you can call one of the datapoint's as_XXXXX() functions (as_float(), as_uint16(), etc) to get the value in the way it was stored.

+ + +

Inertial

Creating an InertialNode

#include "mscl/mscl.h"
+
+//create the connection object with port and baud rate
+mscl::Connection::Serial connection("COM3", 115200);
+
+//create the InertialNode, passing in the connection
+mscl::InertialNode node(connection);
+
//create the connection object with port and baud rate
+mscl.Connection connection = mscl.Connection.Serial("COM3", 115200);
+
+//create the InertialNode, passing in the connection
+mscl.InertialNode node = new mscl.InertialNode(connection);
+
import mscl
+
+#create the connection object with port and baud rate
+connection = mscl.Connection.Serial("COM3", 115200)
+
+#create the InertialNode, passing in the connection
+node = mscl.InertialNode(connection)
+
+
+

Make sure to replace COM3 and 115200 with your own port settings.

+
+ +

To interace with an Inertial Node, create an InertialNode object.

+ +

An InertialNode takes a Connection as a parameter.

+ +

Serial, TcpIp, and UnixSocket are all available as connection types.

+ + +

Communicating with a Node

//ping the Node
+bool success = node.ping();
+
//ping the Node
+bool success = node.ping();
+
# ping the Node
+success = node.ping()
+
+

To test communicating with an Inertial Node, use the ping() function. +





+
//put the Inertial Node into its idle state
+node.setToIdle();
+
//put the Inertial Node into its idle state
+node.setToIdle();
+
# put the Inertial Node into its idle state
+node.setToIdle()
+
+

Unlike a Wireless Node, an Inertial Node can be directly communicated with even if it is sampling. However, in most cases, it is still useful to set the Node to an idle state between sampling sessions and when changing configurations. To do this, use the setToIdle() function.

+

Configuring a Node

//get all of the active channels for the GPS category on the Node
+mscl::MipChannels activeChs = node.getActiveChannelFields(mscl::MipTypes::CLASS_GNSS);
+
//get all of the active channels for the GPS category on the Node
+mscl.MipChannels activeChs = node.getActiveChannelFields(mscl.MipTypes.DataClass.CLASS_GNSS);
+
# get all of the active channels for the GPS category on the Node
+activeChs = node.getActiveChannelFields(mscl.MipTypes.CLASS_GNSS)
+
+

Each Inertial Node has 1 or more Data Classes on the Node:

+ + + + + + + + + + + + + + + + + + + +
CategoryCode
AHRS/IMUCLASS_AHRS_IMU
GNSSCLASS_GNSS
Estimation FilterCLASS_ESTFILTER
+ +

When getting and setting configuration options, it is sometimes necessary to choose the class to target for the command. This is the case in getting the active channels that are currently enabled on the Node.

+

+mscl::MipChannels ahrsImuChs;
+ahrsImuChs.push_back(mscl::MipChannel(mscl::MipTypes::CH_FIELD_SENSOR_RAW_ACCEL_VEC, mscl::SampleRate::Hertz(500)));
+ahrsImuChs.push_back(mscl::MipChannel(mscl::MipTypes::CH_FIELD_SENSOR_RAW_GYRO_VEC, mscl::SampleRate::Hertz(100)));
+
+mscl::MipChannels gnssChs;
+gnssChs.push_back(mscl::MipChannel(mscl::MipTypes::CH_FIELD_GNSS_LLH_POSITION, mscl::SampleRate::Hertz(1)));
+
+mscl::MipChannels estFilterChs;
+estFilterChs.push_back(mscl::MipChannel(mscl::MipTypes::CH_FIELD_ESTFILTER_ESTIMATED_GYRO_BIAS, mscl::SampleRate::Hertz(100)));
+
+//set the active channels for the different data classes on the Node
+node.setActiveChannelFields(mscl::MipTypes::CLASS_AHRS_IMU, ahrsImuChs);
+node.setActiveChannelFields(mscl::MipTypes::CLASS_GNSS, gnssChs);
+node.setActiveChannelFields(mscl::MipTypes::CLASS_ESTFILTER, estFilterChs);
+
+

+mscl::MipChannels ahrsImuChs = new mscl.MipChannels();
+ahrsImuChs.Add(new mscl.MipChannel(mscl.MipTypes.ChannelField.CH_FIELD_SENSOR_RAW_ACCEL_VEC, mscl.SampleRate.Hertz(500)));
+ahrsImuChs.Add(new mscl.MipChannel(mscl.MipTypes.ChannelField.CH_FIELD_SENSOR_RAW_GYRO_VEC, mscl.SampleRate.Hertz(100)));
+
+mscl::MipChannels gnssChs = new mscl.MipChannels();
+gnssChs.Add(new mscl.MipChannel(mscl.MipTypes.ChannelField.CH_FIELD_GNSS_LLH_POSITION, mscl.SampleRate.Hertz(1)));
+
+mscl::MipChannels estFilterChs = new mscl.MipChannels();
+estFilterChs.Add(new mscl.MipChannel(mscl.MipTypes.ChannelField.CH_FIELD_ESTFILTER_ESTIMATED_GYRO_BIAS, mscl.SampleRate.Hertz(100)));
+
+//set the active channels for the different data classes on the Node
+node.setActiveChannelFields(mscl.MipTypes.DataClass.CLASS_AHRS_IMU, ahrsImuChs);
+node.setActiveChannelFields(mscl.MipTypes.DataClass.CLASS_GNSS, gnssChs);
+node.setActiveChannelFields(mscl.MipTypes.DataClass.CLASS_ESTFILTER, estFilterChs);
+
+

+ahrsImuChs = mscl.MipChannels()
+ahrsImuChs.append(mscl.MipChannel(mscl.MipTypes.CH_FIELD_SENSOR_RAW_ACCEL_VEC, mscl.SampleRate.Hertz(500)))
+ahrsImuChs.append(mscl.MipChannel(mscl.MipTypes.CH_FIELD_SENSOR_RAW_GYRO_VEC, mscl.SampleRate.Hertz(100)))
+
+gnssChs = mscl.MipChannels()
+gnssChs.append(mscl.MipChannel(mscl.MipTypes.CH_FIELD_GNSS_LLH_POSITION, mscl.SampleRate.Hertz(1)))
+
+estFilterChs = mscl.MipChannels()
+estFilterChs.append(mscl.MipChannel(mscl.MipTypes.CH_FIELD_ESTFILTER_ESTIMATED_GYRO_BIAS, mscl.SampleRate.Hertz(100)))
+
+# set the active channels for the AHRS/IMU class on the Node
+node.setActiveChannelFields(mscl.MipTypes.CLASS_AHRS_IMU, ahrsImuChs)
+node.setActiveChannelFields(mscl.MipTypes.CLASS_GNSS, gnssChs)
+node.setActiveChannelFields(mscl.MipTypes.CLASS_ESTFILTER, estFilterChs)
+
+
+

Setting the active channels involves building an MipChannels container, and then passing that to the setActiveChannelFields function for a specific category.

+ +

Not all categories and channel fields are supported by each Inertial Node. Use the node.features() function to get this information on the Node.

+

Starting Sampling

//start sampling the active channels on the AHRS/IMU class of the Node
+node.enableDataStream(mscl::MipTypes::CLASS_AHRS_IMU);
+
+//start sampling the active channels on the GNSS class of the Node
+node.enableDataStream(mscl::MipTypes::CLASS_GNSS);
+
//start sampling on the AHRS/IMU class of the Node
+node.enableDataStream(mscl.MipTypes.DataClass.CLASS_AHRS_IMU);
+
+//start sampling on the GNSS class of the Node
+node.enableDataStream(mscl.MipTypes.DataClass.CLASS_GNSS);
+
# start sampling on the AHRS/IMU class of the Node
+node.enableDataStream(mscl.MipTypes.CLASS_AHRS_IMU)
+
+# start sampling on the GNSS class of the Node
+node.enableDataStream(mscl.MipTypes.CLASS_GNSS)
+
+
+

You can provide an optional 2nd parameter to the enableDataStream function which is a boolean that allows enabling (true, default), or disabling (false) of the data stream.

+
+ +

There are a couple ways to start sampling on an Inertial Node. The first is the enableDataStream command. This allows you to start sampling on individual categories of the Node.

+ +











+
//use the resume command to return to the mode before setToIdle
+node.resume();
+
//use the resume command to return to the mode before setToIdle
+node.resume();
+
# use the resume command to return to the mode before setToIdle
+node.resume()
+
+

Alternatively, you can use the resume() command. This command places the Node back into the mode it was in before issuing the setToIdle() command. So if the Node was previously sampling on all of its categories, then setToIdle() was called, calling resume() will start the Node sampling again.

+

Collecting Data

//create the InertialNode, passing in the connection
+mscl::InertialNode node = mscl.InertialNode(connection);
+
+while(true)
+{
+    //get all the packets that have been collected, with a timeout of 500 milliseconds
+    mscl::MipDataPackets packets = node.getDataPackets(500);
+
+    for(mscl::MipDataPacket packet : packets)
+    {
+        packet.descriptorSet(); //the descriptor set of the packet
+        packet.timestamp();     //the PC time when this packet was received
+
+        //get all of the points in the packet
+        mscl::MipDataPoints points = packet.data();
+
+        for(mscl::MipDataPoint dataPoint : points)
+        {
+            dataPoint.channelName();  //the name of the channel for this point
+            dataPoint.storedAs();     //the ValueType that the data is stored as
+            dataPoint.as_float();     //get the value as a float
+        }
+    }
+}
+
//create the InertialNode, passing in the connection
+mscl.InertialNode node = new mscl.InertialNode(connection);
+
+while(true)
+{
+    //get all the packets that have been collected, with a timeout of 500 milliseconds
+    mscl.MipDataPackets packets = node.getDataPackets(500);
+
+    foreach(mscl.MipDataPacket packet in packets)
+    {
+        packet.descriptorSet();  //the descriptor set of the packet
+        packet.timestamp();      //the PC time when this packet was received
+
+        //get all of the points in the packet
+        mscl.MipDataPoints points = packet.data();
+
+        foreach(mscl.MipDataPoint dataPoint in points)
+        {
+            dataPoint.channelName();  //the name of the channel for this point
+            dataPoint.storedAs();     //the ValueType that the data is stored as
+            dataPoint.as_float();     //get the value as a float
+        }
+    }
+}
+
# create the InertialNode, passing in the connection
+node = mscl.InertialNode(connection)
+
+while True:
+
+    # get all the packets that have been collected, with a timeout of 500 milliseconds
+    packets = node.getDataPackets(500)
+
+    for packet in packets:
+        packet.descriptorSet()  # the descriptor set of the packet
+        packet.timestamp()      # the PC time when this packet was received
+
+        # get all of the points in the packet
+        points = packet.data()
+
+        for dataPoint in points:
+            dataPoint.channelName()   # the name of the channel for this point
+            dataPoint.storedAs()      # the ValueType that the data is stored as
+            dataPoint.as_float()      # get the value as a float
+    }
+
+
+

as_float() returns the dataPoint value as a 4-byte float. However there are more options, such as as_uint16(), as_double(), as_string(), etc. The ValueType that is returned from the storedAs() function determines how the data is actually stored.

+
+ +

As soon as the InertialNode object is created, all data packets will be parsed and stored in an internal circular buffer.

+ +

node.getDataPackets() will return a vector of MipDataPacket objects. This will contain all of the packets that have been collected after the InertialNode object was created.

+ +

Each MipDataPacket contains various information describing it. The MipDataPacket's data() function will return a vector of MipDataPoint objects. These data points represent data from the active channels that were sampling on the Node.

+ +

Each data point will be stored as a certain type. The datapoint's storedAs() function will return an enum specifying which type the data is stored in (valueType_float, valueType_uint16, etc).

+ +

Using this information, you can call one of the data point's as_XXXXX() functions (as_float(), as_uint16(), etc) to get the value in the was it was stored.

+ + +

Displacement

Creating a DisplacementNode

#include "mscl/mscl.h"
+
+//create the connection object with port and baud rate
+mscl::Connection::Serial connection("COM3", 115200);
+
+//create the DisplacementNode, passing in the connection
+mscl::DisplacementNode node(connection);
+
//create the connection object with port and baud rate
+mscl.Connection connection = mscl.Connection.Serial("COM3", 115200);
+
+//create the InertialNode, passing in the connection
+mscl.DisplacementNode node = new mscl.DisplacementNode(connection);
+
import mscl
+
+#create the connection object with port and baud rate
+connection = mscl.Connection.Serial("COM3", 115200)
+
+#create the DisplacementNode, passing in the connection
+node = mscl.DisplacementNode(connection)
+
+
+

Make sure to replace COM3 and 115200 with your own port settings.

+
+ +

To interace with a digital Displacement Node, create a DisplacementNode object.

+ +

A DisplacementNode takes a Connection as a parameter.

+ +

Serial, TcpIp, and UnixSocket are all available as connection types.

+ + +

Communicating with a Node

//ping the Node
+bool success = node.ping();
+
//ping the Node
+bool success = node.ping();
+
# ping the Node
+success = node.ping()
+
+

To test communicating with a Displacement Node, use the ping() function. +





+
//put the Inertial Node into its idle state
+node.setToIdle();
+
//put the Inertial Node into its idle state
+node.setToIdle();
+
# put the Inertial Node into its idle state
+node.setToIdle()
+
+

Unlike a Wireless Node, a Displacement Node can be directly communicated with even if it is sampling. However, in most cases, it is still useful to set the Node to an idle state between sampling sessions and when changing configurations. To do this, use the setToIdle() function.

+

Configuring a Node


+//seed the device time with the current PC time
+//Note: you can pass your own time to this function as a parameter in nanoseconds since unix epoch
+node.setDeviceTime();
+
+

+//seed the device time with the current PC time
+//Note: you can pass your own time to this function as a parameter in nanoseconds since unix epoch
+node.setDeviceTime();
+
+

+#seed the device time with the current PC time
+#Note: you can pass your own time to this function as a parameter in nanoseconds since unix epoch
+node.setDeviceTime()
+
+
+

You can seed the DisplacementNode time before you start sampling so that the time channel that is output has an accurate timestamp.

+

Starting Sampling


+//start sampling
+node.resume();
+
+

+//start sampling
+node.resume();
+
+

+# start sampling
+node.resume()
+
+
+

Use the resume function to start sampling on the Displacement Node.

+ +











+

Collecting Data

//create the DisplacementNode, passing in the connection
+mscl::DisplacementNode node = mscl.DisplacementNode(connection);
+
+while(true)
+{
+    //get all the packets that have been collected, with a timeout of 500 milliseconds
+    mscl::MipDataPackets packets = node.getDataPackets(500);
+
+    for(mscl::MipDataPacket packet : packets)
+    {
+        packet.timestamp();     //the PC time when this packet was received
+
+        //get all of the points in the packet
+        mscl::MipDataPoints points = packet.data();
+
+        for(mscl::MipDataPoint dataPoint : points)
+        {
+            dataPoint.channelName();  //the name of the channel for this point
+            dataPoint.storedAs();     //the ValueType that the data is stored as
+            dataPoint.as_float();     //get the value as a float
+        }
+    }
+}
+
//create the DisplacementNode, passing in the connection
+mscl.DisplacementNode node = new mscl.DisplacementNode(connection);
+
+while(true)
+{
+    //get all the packets that have been collected, with a timeout of 500 milliseconds
+    mscl.MipDataPackets packets = node.getDataPackets(500);
+
+    foreach(mscl.MipDataPacket packet in packets)
+    {
+        packet.timestamp();      //the PC time when this packet was received
+
+        //get all of the points in the packet
+        mscl.MipDataPoints points = packet.data();
+
+        foreach(mscl.MipDataPoint dataPoint in points)
+        {
+            dataPoint.channelName();  //the name of the channel for this point
+            dataPoint.storedAs();     //the ValueType that the data is stored as
+            dataPoint.as_float();     //get the value as a float
+        }
+    }
+}
+
# create the DisplacementNode, passing in the connection
+node = mscl.DisplacementNode(connection)
+
+while True:
+
+    # get all the packets that have been collected, with a timeout of 500 milliseconds
+    packets = node.getDataPackets(500)
+
+    for packet in packets:
+        packet.descriptorSet()  # the descriptor set of the packet
+        packet.timestamp()      # the PC time when this packet was received
+
+        # get all of the points in the packet
+        points = packet.data()
+
+        for dataPoint in points:
+            dataPoint.channelName()   # the name of the channel for this point
+            dataPoint.storedAs()      # the ValueType that the data is stored as
+            dataPoint.as_float()      # get the value as a float
+    }
+
+
+

as_float() returns the dataPoint value as a 4-byte float. However there are more options, such as as_uint16(), as_double(), as_string(), etc. The ValueType that is returned from the storedAs() function determines how the data is actually stored.

+
+ +

As soon as the DisplacementNode object is created, all data packets will be parsed and stored in an internal circular buffer.

+ +

node.getDataPackets() will return a vector of MipDataPacket objects. This will contain all of the packets that have been collected after the DisplacementNode object was created.

+ +

Each MipDataPacket contains various information describing it. The MipDataPacket's data() function will return a vector of MipDataPoint objects. These data points represent data from the active channels that were sampling on the Node.

+ +

Each data point will be stored as a certain type. The datapoint's storedAs() function will return an enum specifying which type the data is stored in (valueType_float, valueType_uint16, etc).

+ +

Using this information, you can call one of the data point's as_XXXXX() functions (as_float(), as_uint16(), etc) to get the value in the was it was stored.

+ + + +

Exceptions

+

MSCL uses the following Exceptions. Check the full documentation for details of which exceptions are thrown by each function.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExceptionDescription
ErrorAn error has occurred.
Error_BadDataTypeA value was accessed as a type that it cannot be converted to.
Error_CommunicationFailed to communicate with a device.
Error_ConnectionAn error has occurred with the connection.
Error_MipCmdFailedThe MIP Command has failed.
Error_InvalidConfigThe configuration is invalid.
Error_InvalidNodeConfigThe configuration for a WirelessNode is invalid.
Error_InvalidSerialPortAn error has occurred with the COM port.
Error_InvalidTcpServerAn error has occured with the TCP/IP port.
Error_InvalidUnixSocketAn error has occurred with the Unix Socket.
Error_NoDataThere is no data available.
Error_NodeCommunicationFailed to communicate with a Wireless Node.
Error_NotSupportedA command or feature was used that is not supported.
Error_UnknownSampleRateThe sample rate is unknown or invalid.
+ +
+
+
+ C++ + C# + Python +
+
+
+ + diff --git a/Documentation/Getting Started/javascripts/all.js b/Documentation/Getting Started/javascripts/all.js new file mode 100644 index 000000000..53b0e1818 --- /dev/null +++ b/Documentation/Getting Started/javascripts/all.js @@ -0,0 +1,168 @@ +!function(){if("ontouchstart"in window){var e,t,n,i,r,o,s={};e=function(e,t){return Math.abs(e[0]-t[0])>5||Math.abs(e[1]-t[1])>5},t=function(e){this.startXY=[e.touches[0].clientX,e.touches[0].clientY],this.threshold=!1},n=function(t){return!this.threshold&&void(this.threshold=e(this.startXY,[t.touches[0].clientX,t.touches[0].clientY]))},i=function(t){if(!this.threshold&&!e(this.startXY,[t.changedTouches[0].clientX,t.changedTouches[0].clientY])){var n=t.changedTouches[0],i=document.createEvent("MouseEvents");i.initMouseEvent("click",!0,!0,window,0,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),i.simulated=!0,t.target.dispatchEvent(i)}},r=function(e){var t=Date.now(),n=t-s.time,i=e.clientX,r=e.clientY,a=[Math.abs(s.x-i),Math.abs(s.y-r)],u=o(e.target,"A")||e.target,l=u.nodeName,c="A"===l,f=window.navigator.standalone&&c&&e.target.getAttribute("href");return s.time=t,s.x=i,s.y=r,!((!e.simulated&&(n<500||n<1500&&a[0]<50&&a[1]<50)||f)&&(e.preventDefault(),e.stopPropagation(),!f))&&(f&&(window.location=u.getAttribute("href")),void(u&&u.classList&&(u.classList.add("energize-focus"),window.setTimeout(function(){u.classList.remove("energize-focus")},150))))},o=function(e,t){for(var n=e;n!==document.body;){if(!n||n.nodeName===t)return n;n=n.parentNode}return null},document.addEventListener("touchstart",t,!1),document.addEventListener("touchmove",n,!1),document.addEventListener("touchend",i,!1),document.addEventListener("click",r,!0)}}(),/*! + * jQuery JavaScript Library v2.2.0 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-01-08T20:02Z + */ +function(e,t){"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(e,t){function n(e){var t=!!e&&"length"in e&&e.length,n=oe.type(e);return"function"!==n&&!oe.isWindow(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function i(e,t,n){if(oe.isFunction(t))return oe.grep(e,function(e,i){return!!t.call(e,i,e)!==n});if(t.nodeType)return oe.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(ge.test(t))return oe.filter(t,e,n);t=oe.filter(t,e)}return oe.grep(e,function(e){return Z.call(t,e)>-1!==n})}function r(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function o(e){var t={};return oe.each(e.match(we)||[],function(e,n){t[n]=!0}),t}function s(){Q.removeEventListener("DOMContentLoaded",s),e.removeEventListener("load",s),oe.ready()}function a(){this.expando=oe.expando+a.uid++}function u(e,t,n){var i;if(void 0===n&&1===e.nodeType)if(i="data-"+t.replace(Ae,"-$&").toLowerCase(),n=e.getAttribute(i),"string"==typeof n){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:Ne.test(n)?oe.parseJSON(n):n)}catch(e){}ke.set(e,t,n)}else n=void 0;return n}function l(e,t,n,i){var r,o=1,s=20,a=i?function(){return i.cur()}:function(){return oe.css(e,t,"")},u=a(),l=n&&n[3]||(oe.cssNumber[t]?"":"px"),c=(oe.cssNumber[t]||"px"!==l&&+u)&&Le.exec(oe.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do o=o||".5",c/=o,oe.style(e,t,c+l);while(o!==(o=a()/u)&&1!==o&&--s)}return n&&(c=+c||+u||0,r=n[1]?c+(n[1]+1)*n[2]:+n[2],i&&(i.unit=l,i.start=c,i.end=r)),r}function c(e,t){var n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[];return void 0===t||t&&oe.nodeName(e,t)?oe.merge([e],n):n}function f(e,t){for(var n=0,i=e.length;n-1)r&&r.push(o);else if(l=oe.contains(o.ownerDocument,o),s=c(h.appendChild(o),"script"),l&&f(s),n)for(d=0;o=s[d++];)He.test(o.type||"")&&n.push(o);return h}function h(){return!0}function p(){return!1}function g(){try{return Q.activeElement}catch(e){}}function v(e,t,n,i,r,o){var s,a;if("object"==typeof t){"string"!=typeof n&&(i=i||n,n=void 0);for(a in t)v(e,a,n,i,t[a],o);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),r===!1)r=p;else if(!r)return this;return 1===o&&(s=r,r=function(e){return oe().off(e),s.apply(this,arguments)},r.guid=s.guid||(s.guid=oe.guid++)),e.each(function(){oe.event.add(this,t,r,i,n)})}function m(e,t){return oe.nodeName(e,"table")&&oe.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e:e}function y(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function x(e){var t=ze.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function b(e,t){var n,i,r,o,s,a,u,l;if(1===t.nodeType){if(Ee.hasData(e)&&(o=Ee.access(e),s=Ee.set(t,o),l=o.events)){delete s.handle,s.events={};for(r in l)for(n=0,i=l[r].length;n1&&"string"==typeof g&&!ie.checkClone&&Be.test(g))return e.each(function(r){var o=e.eq(r);v&&(t[0]=g.call(this,r,o.html())),C(o,t,n,i)});if(h&&(r=d(t,e[0].ownerDocument,!1,e,i),o=r.firstChild,1===r.childNodes.length&&(r=o),o||i)){for(s=oe.map(c(r,"script"),y),a=s.length;f")).appendTo(t.documentElement),t=Xe[0].contentDocument,t.write(),t.close(),n=T(e,t),Xe.detach()),Ue[e]=n),n}function k(e,t,n){var i,r,o,s,a=e.style;return n=n||Je(e),n&&(s=n.getPropertyValue(t)||n[t],""!==s||oe.contains(e.ownerDocument,e)||(s=oe.style(e,t)),!ie.pixelMarginRight()&&Qe.test(s)&&Ye.test(t)&&(i=a.width,r=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=i,a.minWidth=r,a.maxWidth=o)),void 0!==s?s+"":s}function N(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function A(e){if(e in it)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=nt.length;n--;)if(e=nt[n]+t,e in it)return e}function j(e,t,n){var i=Le.exec(t);return i?Math.max(0,i[2]-(n||0))+(i[3]||"px"):t}function L(e,t,n,i,r){for(var o=n===(i?"border":"content")?4:"width"===t?1:0,s=0;o<4;o+=2)"margin"===n&&(s+=oe.css(e,n+Oe[o],!0,r)),i?("content"===n&&(s-=oe.css(e,"padding"+Oe[o],!0,r)),"margin"!==n&&(s-=oe.css(e,"border"+Oe[o]+"Width",!0,r))):(s+=oe.css(e,"padding"+Oe[o],!0,r),"padding"!==n&&(s+=oe.css(e,"border"+Oe[o]+"Width",!0,r)));return s}function O(t,n,i){var r=!0,o="width"===n?t.offsetWidth:t.offsetHeight,s=Je(t),a="border-box"===oe.css(t,"boxSizing",!1,s);if(Q.msFullscreenElement&&e.top!==e&&t.getClientRects().length&&(o=Math.round(100*t.getBoundingClientRect()[n])),o<=0||null==o){if(o=k(t,n,s),(o<0||null==o)&&(o=t.style[n]),Qe.test(o))return o;r=a&&(ie.boxSizingReliable()||o===t.style[n]),o=parseFloat(o)||0}return o+L(t,n,i||(a?"border":"content"),r,s)+"px"}function D(e,t){for(var n,i,r,o=[],s=0,a=e.length;s=0&&n=0},isPlainObject:function(e){return"object"===oe.type(e)&&!e.nodeType&&!oe.isWindow(e)&&!(e.constructor&&!ne.call(e.constructor.prototype,"isPrototypeOf"))},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?ee[te.call(e)]||"object":typeof e},globalEval:function(e){var t,n=eval;e=oe.trim(e),e&&(1===e.indexOf("use strict")?(t=Q.createElement("script"),t.text=e,Q.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(ae,"ms-").replace(ue,le)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var i,r=0;if(n(e))for(i=e.length;rC.cacheLength&&delete e[t.shift()],e[n+" "]=i}var t=[];return e}function i(e){return e[R]=!0,e}function r(e){var t=D.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),i=n.length;i--;)C.attrHandle[n[i]]=t}function s(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||U)-(~e.sourceIndex||U);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function l(e){return i(function(t){return t=+t,i(function(n,i){for(var r,o=e([],n.length,t),s=o.length;s--;)n[r=o[s]]&&(n[r]=!(i[r]=n[r]))})})}function c(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,i="";t1?function(t,n,i){for(var r=e.length;r--;)if(!e[r](t,n,i))return!1;return!0}:e[0]}function g(e,n,i){for(var r=0,o=n.length;r-1&&(i[l]=!(s[l]=f))}}else x=v(x===s?x.splice(p,x.length):x),o?o(null,s,x,u):K.apply(s,x)})}function y(e){for(var t,n,i,r=e.length,o=C.relative[e[0].type],s=o||C.relative[" "],a=o?1:0,u=h(function(e){return e===t},s,!0),l=h(function(e){return ee(t,e)>-1},s,!0),c=[function(e,n,i){var r=!o&&(i||n!==A)||((t=n).nodeType?u(e,n,i):l(e,n,i));return t=null,r}];a1&&p(c),a>1&&d(e.slice(0,a-1).concat({value:" "===e[a-2].type?"*":""})).replace(ae,"$1"),n,a0,o=e.length>0,s=function(i,s,a,u,l){var c,f,d,h=0,p="0",g=i&&[],m=[],y=A,x=i||o&&C.find.TAG("*",l),b=W+=null==y?1:Math.random()||.1,w=x.length;for(l&&(A=s===D||s||l);p!==w&&null!=(c=x[p]);p++){if(o&&c){for(f=0,s||c.ownerDocument===D||(O(c),a=!q);d=e[f++];)if(d(c,s||D,a)){u.push(c);break}l&&(W=b)}r&&((c=!d&&c)&&h--,i&&g.push(c))}if(h+=p,r&&p!==h){for(f=0;d=n[f++];)d(g,m,s,a);if(i){if(h>0)for(;p--;)g[p]||m[p]||(m[p]=J.call(u));m=v(m)}K.apply(u,m),l&&!i&&m.length>0&&h+n.length>1&&t.uniqueSort(u)}return l&&(W=b,A=y),g};return r?i(s):s}var b,w,C,S,T,E,k,N,A,j,L,O,D,_,q,H,P,F,$,R="sizzle"+1*new Date,I=e.document,W=0,M=0,B=n(),z=n(),V=n(),X=function(e,t){return e===t&&(L=!0),0},U=1<<31,Y={}.hasOwnProperty,Q=[],J=Q.pop,G=Q.push,K=Q.push,Z=Q.slice,ee=function(e,t){for(var n=0,i=e.length;n+~]|"+ne+")"+ne+"*"),ce=new RegExp("="+ne+"*([^\\]'\"]*?)"+ne+"*\\]","g"),fe=new RegExp(oe),de=new RegExp("^"+ie+"$"),he={ID:new RegExp("^#("+ie+")"),CLASS:new RegExp("^\\.("+ie+")"),TAG:new RegExp("^("+ie+"|[*])"),ATTR:new RegExp("^"+re),PSEUDO:new RegExp("^"+oe),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ne+"*(even|odd|(([+-]|)(\\d*)n|)"+ne+"*(?:([+-]|)"+ne+"*(\\d+)|))"+ne+"*\\)|)","i"),bool:new RegExp("^(?:"+te+")$","i"),needsContext:new RegExp("^"+ne+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ne+"*((?:-\\d)?\\d*)"+ne+"*\\)|)(?=[^-]|$)","i")},pe=/^(?:input|select|textarea|button)$/i,ge=/^h\d$/i,ve=/^[^{]+\{\s*\[native \w/,me=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ye=/[+~]/,xe=/'|\\/g,be=new RegExp("\\\\([\\da-f]{1,6}"+ne+"?|("+ne+")|.)","ig"),we=function(e,t,n){var i="0x"+t-65536;return i!==i||n?t:i<0?String.fromCharCode(i+65536):String.fromCharCode(i>>10|55296,1023&i|56320)},Ce=function(){O()};try{K.apply(Q=Z.call(I.childNodes),I.childNodes),Q[I.childNodes.length].nodeType}catch(e){K={apply:Q.length?function(e,t){G.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}w=t.support={},T=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},O=t.setDocument=function(e){var t,n,i=e?e.ownerDocument||e:I;return i!==D&&9===i.nodeType&&i.documentElement?(D=i,_=D.documentElement,q=!T(D),(n=D.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",Ce,!1):n.attachEvent&&n.attachEvent("onunload",Ce)),w.attributes=r(function(e){return e.className="i",!e.getAttribute("className")}),w.getElementsByTagName=r(function(e){return e.appendChild(D.createComment("")),!e.getElementsByTagName("*").length}),w.getElementsByClassName=ve.test(D.getElementsByClassName),w.getById=r(function(e){return _.appendChild(e).id=R,!D.getElementsByName||!D.getElementsByName(R).length}),w.getById?(C.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&q){var n=t.getElementById(e);return n?[n]:[]}},C.filter.ID=function(e){var t=e.replace(be,we);return function(e){return e.getAttribute("id")===t}}):(delete C.find.ID,C.filter.ID=function(e){var t=e.replace(be,we);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}}),C.find.TAG=w.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[r++];)1===n.nodeType&&i.push(n);return i}return o},C.find.CLASS=w.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&q)return t.getElementsByClassName(e)},P=[],H=[],(w.qsa=ve.test(D.querySelectorAll))&&(r(function(e){_.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&H.push("[*^$]="+ne+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||H.push("\\["+ne+"*(?:value|"+te+")"),e.querySelectorAll("[id~="+R+"-]").length||H.push("~="),e.querySelectorAll(":checked").length||H.push(":checked"),e.querySelectorAll("a#"+R+"+*").length||H.push(".#.+[+~]")}),r(function(e){var t=D.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&H.push("name"+ne+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||H.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),H.push(",.*:")})),(w.matchesSelector=ve.test(F=_.matches||_.webkitMatchesSelector||_.mozMatchesSelector||_.oMatchesSelector||_.msMatchesSelector))&&r(function(e){w.disconnectedMatch=F.call(e,"div"),F.call(e,"[s!='']:x"),P.push("!=",oe)}),H=H.length&&new RegExp(H.join("|")),P=P.length&&new RegExp(P.join("|")),t=ve.test(_.compareDocumentPosition),$=t||ve.test(_.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},X=t?function(e,t){if(e===t)return L=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===D||e.ownerDocument===I&&$(I,e)?-1:t===D||t.ownerDocument===I&&$(I,t)?1:j?ee(j,e)-ee(j,t):0:4&n?-1:1)}:function(e,t){if(e===t)return L=!0,0;var n,i=0,r=e.parentNode,o=t.parentNode,a=[e],u=[t];if(!r||!o)return e===D?-1:t===D?1:r?-1:o?1:j?ee(j,e)-ee(j,t):0;if(r===o)return s(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;a[i]===u[i];)i++;return i?s(a[i],u[i]):a[i]===I?-1:u[i]===I?1:0},D):D},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==D&&O(e),n=n.replace(ce,"='$1']"),w.matchesSelector&&q&&!V[n+" "]&&(!P||!P.test(n))&&(!H||!H.test(n)))try{var i=F.call(e,n);if(i||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return i}catch(e){}return t(n,D,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==D&&O(e),$(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==D&&O(e);var n=C.attrHandle[t.toLowerCase()],i=n&&Y.call(C.attrHandle,t.toLowerCase())?n(e,t,!q):void 0;return void 0!==i?i:w.attributes||!q?e.getAttribute(t):(i=e.getAttributeNode(t))&&i.specified?i.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],i=0,r=0;if(L=!w.detectDuplicates,j=!w.sortStable&&e.slice(0),e.sort(X),L){for(;t=e[r++];)t===e[r]&&(i=n.push(r));for(;i--;)e.splice(n[i],1)}return j=null,e},S=t.getText=function(e){var t,n="",i=0,r=e.nodeType;if(r){if(1===r||9===r||11===r){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=S(e)}else if(3===r||4===r)return e.nodeValue}else for(;t=e[i++];)n+=S(t);return n},C=t.selectors={cacheLength:50,createPseudo:i,match:he,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,we),e[3]=(e[3]||e[4]||e[5]||"").replace(be,we),"~="===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]||t.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]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&fe.test(n)&&(t=E(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(be,we).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=B[e+" "];return t||(t=new RegExp("(^|"+ne+")"+e+"("+ne+"|$)"))&&B(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,i){return function(r){var o=t.attr(r,e);return null==o?"!="===n:!n||(o+="","="===n?o===i:"!="===n?o!==i:"^="===n?i&&0===o.indexOf(i):"*="===n?i&&o.indexOf(i)>-1:"$="===n?i&&o.slice(-i.length)===i:"~="===n?(" "+o.replace(se," ")+" ").indexOf(i)>-1:"|="===n&&(o===i||o.slice(0,i.length+1)===i+"-"))}},CHILD:function(e,t,n,i,r){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===i&&0===r?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,d,h,p,g=o!==s?"nextSibling":"previousSibling",v=t.parentNode,m=a&&t.nodeName.toLowerCase(),y=!u&&!a,x=!1;if(v){if(o){for(;g;){for(d=t;d=d[g];)if(a?d.nodeName.toLowerCase()===m:1===d.nodeType)return!1;p=g="only"===e&&!p&&"nextSibling"}return!0}if(p=[s?v.firstChild:v.lastChild],s&&y){for(d=v,f=d[R]||(d[R]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],h=l[0]===W&&l[1],x=h&&l[2],d=h&&v.childNodes[h];d=++h&&d&&d[g]||(x=h=0)||p.pop();)if(1===d.nodeType&&++x&&d===t){c[e]=[W,h,x];break}}else if(y&&(d=t,f=d[R]||(d[R]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],h=l[0]===W&&l[1],x=h),x===!1)for(;(d=++h&&d&&d[g]||(x=h=0)||p.pop())&&((a?d.nodeName.toLowerCase()!==m:1!==d.nodeType)||!++x||(y&&(f=d[R]||(d[R]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[W,x]),d!==t)););return x-=r,x===i||x%i===0&&x/i>=0}}},PSEUDO:function(e,n){var r,o=C.pseudos[e]||C.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[R]?o(n):o.length>1?(r=[e,e,"",n],C.setFilters.hasOwnProperty(e.toLowerCase())?i(function(e,t){for(var i,r=o(e,n),s=r.length;s--;)i=ee(e,r[s]),e[i]=!(t[i]=r[s])}):function(e){return o(e,0,r)}):o}},pseudos:{not:i(function(e){var t=[],n=[],r=k(e.replace(ae,"$1"));return r[R]?i(function(e,t,n,i){for(var o,s=r(e,null,i,[]),a=e.length;a--;)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:i(function(e){return function(n){return t(e,n).length>0}}),contains:i(function(e){return e=e.replace(be,we),function(t){return(t.textContent||t.innerText||S(t)).indexOf(e)>-1}}),lang:i(function(e){return de.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(be,we).toLowerCase(),function(t){var n;do if(n=q?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===_},focus:function(e){return e===D.activeElement&&(!D.hasFocus||D.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!C.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return pe.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n=0;)e.push(i);return e}),gt:l(function(e,t,n){for(var i=n<0?n+t:n;++i2&&"ID"===(s=o[0]).type&&w.getById&&9===t.nodeType&&q&&C.relative[o[1].type]){if(t=(C.find.ID(s.matches[0].replace(be,we),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(r=he.needsContext.test(e)?0:o.length;r--&&(s=o[r],!C.relative[a=s.type]);)if((u=C.find[a])&&(i=u(s.matches[0].replace(be,we),ye.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(r,1),e=i.length&&d(o),!e)return K.apply(n,i),n;break}}return(l||k(e,f))(i,t,!q,n,!t||ye.test(e)&&c(t.parentNode)||t),n},w.sortStable=R.split("").sort(X).join("")===R,w.detectDuplicates=!!L,O(),w.sortDetached=r(function(e){return 1&e.compareDocumentPosition(D.createElement("div"))}),r(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),w.attributes&&r(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),r(function(e){return null==e.getAttribute("disabled")})||o(te,function(e,t,n){var i;if(!n)return e[t]===!0?t.toLowerCase():(i=e.getAttributeNode(t))&&i.specified?i.value:null}),t}(e);oe.find=ce,oe.expr=ce.selectors,oe.expr[":"]=oe.expr.pseudos,oe.uniqueSort=oe.unique=ce.uniqueSort,oe.text=ce.getText,oe.isXMLDoc=ce.isXML,oe.contains=ce.contains;var fe=function(e,t,n){for(var i=[],r=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(r&&oe(e).is(n))break;i.push(e)}return i},de=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},he=oe.expr.match.needsContext,pe=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,ge=/^.[^:#\[\.,]*$/;oe.filter=function(e,t,n){var i=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===i.nodeType?oe.find.matchesSelector(i,e)?[i]:[]:oe.find.matches(e,oe.grep(t,function(e){return 1===e.nodeType}))},oe.fn.extend({find:function(e){var t,n=this.length,i=[],r=this;if("string"!=typeof e)return this.pushStack(oe(e).filter(function(){for(t=0;t1?oe.unique(i):i),i.selector=this.selector?this.selector+" "+e:e,i},filter:function(e){return this.pushStack(i(this,e||[],!1))},not:function(e){return this.pushStack(i(this,e||[],!0))},is:function(e){return!!i(this,"string"==typeof e&&he.test(e)?oe(e):e||[],!1).length}});var ve,me=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,ye=oe.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||ve,"string"==typeof e){if(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:me.exec(e),!i||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof oe?t[0]:t,oe.merge(this,oe.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:Q,!0)),pe.test(i[1])&&oe.isPlainObject(t))for(i in t)oe.isFunction(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return r=Q.getElementById(i[2]),r&&r.parentNode&&(this.length=1,this[0]=r),this.context=Q,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):oe.isFunction(e)?void 0!==n.ready?n.ready(e):e(oe):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),oe.makeArray(e,this))};ye.prototype=oe.fn,ve=oe(Q);var xe=/^(?:parents|prev(?:Until|All))/,be={children:!0,contents:!0,next:!0,prev:!0};oe.fn.extend({has:function(e){var t=oe(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&oe.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?oe.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?Z.call(oe(e),this[0]):Z.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(oe.uniqueSort(oe.merge(this.get(),oe(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),oe.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return fe(e,"parentNode")},parentsUntil:function(e,t,n){return fe(e,"parentNode",n)},next:function(e){return r(e,"nextSibling")},prev:function(e){return r(e,"previousSibling")},nextAll:function(e){return fe(e,"nextSibling")},prevAll:function(e){return fe(e,"previousSibling")},nextUntil:function(e,t,n){return fe(e,"nextSibling",n)},prevUntil:function(e,t,n){return fe(e,"previousSibling",n)},siblings:function(e){return de((e.parentNode||{}).firstChild,e)},children:function(e){return de(e.firstChild)},contents:function(e){return e.contentDocument||oe.merge([],e.childNodes)}},function(e,t){oe.fn[e]=function(n,i){var r=oe.map(this,t,n);return"Until"!==e.slice(-5)&&(i=n),i&&"string"==typeof i&&(r=oe.filter(i,r)),this.length>1&&(be[e]||oe.uniqueSort(r),xe.test(e)&&r.reverse()),this.pushStack(r)}});var we=/\S+/g;oe.Callbacks=function(e){e="string"==typeof e?o(e):oe.extend({},e);var t,n,i,r,s=[],a=[],u=-1,l=function(){for(r=e.once,i=t=!0;a.length;u=-1)for(n=a.shift();++u-1;)s.splice(n,1),n<=u&&u--}),this},has:function(e){return e?oe.inArray(e,s)>-1:s.length>0},empty:function(){return s&&(s=[]),this},disable:function(){return r=a=[],s=n="",this},disabled:function(){return!s},lock:function(){return r=a=[],n||(s=n=""),this},locked:function(){return!!r},fireWith:function(e,n){return r||(n=n||[],n=[e,n.slice?n.slice():n],a.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!i}};return c},oe.extend({Deferred:function(e){var t=[["resolve","done",oe.Callbacks("once memory"),"resolved"],["reject","fail",oe.Callbacks("once memory"),"rejected"],["notify","progress",oe.Callbacks("memory")]],n="pending",i={state:function(){return n},always:function(){return r.done(arguments).fail(arguments),this},then:function(){var e=arguments;return oe.Deferred(function(n){oe.each(t,function(t,o){var s=oe.isFunction(e[t])&&e[t];r[o[1]](function(){var e=s&&s.apply(this,arguments);e&&oe.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[o[0]+"With"](this===i?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?oe.extend(e,i):i}},r={};return i.pipe=i.then,oe.each(t,function(e,o){var s=o[2],a=o[3];i[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),r[o[0]]=function(){return r[o[0]+"With"](this===r?i:this,arguments),this},r[o[0]+"With"]=s.fireWith}),i.promise(r),e&&e.call(r,r),r},when:function(e){var t,n,i,r=0,o=J.call(arguments),s=o.length,a=1!==s||e&&oe.isFunction(e.promise)?s:0,u=1===a?e:oe.Deferred(),l=function(e,n,i){return function(r){n[e]=this,i[e]=arguments.length>1?J.call(arguments):r,i===t?u.notifyWith(n,i):--a||u.resolveWith(n,i)}};if(s>1)for(t=new Array(s),n=new Array(s),i=new Array(s);r0||(Ce.resolveWith(Q,[oe]),oe.fn.triggerHandler&&(oe(Q).triggerHandler("ready"),oe(Q).off("ready"))))}}),oe.ready.promise=function(t){return Ce||(Ce=oe.Deferred(),"complete"===Q.readyState||"loading"!==Q.readyState&&!Q.documentElement.doScroll?e.setTimeout(oe.ready):(Q.addEventListener("DOMContentLoaded",s),e.addEventListener("load",s))),Ce.promise(t)},oe.ready.promise();var Se=function(e,t,n,i,r,o,s){var a=0,u=e.length,l=null==n;if("object"===oe.type(n)){r=!0;for(a in n)Se(e,t,a,n[a],!0,o,s)}else if(void 0!==i&&(r=!0,oe.isFunction(i)||(s=!0),l&&(s?(t.call(e,i),t=null):(l=t,t=function(e,t,n){return l.call(oe(e),n)})),t))for(;a-1&&void 0!==n&&ke.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){ke.remove(this,e)})}}),oe.extend({queue:function(e,t,n){var i;if(e)return t=(t||"fx")+"queue",i=Ee.get(e,t),n&&(!i||oe.isArray(n)?i=Ee.access(e,t,oe.makeArray(n)):i.push(n)),i||[]},dequeue:function(e,t){t=t||"fx";var n=oe.queue(e,t),i=n.length,r=n.shift(),o=oe._queueHooks(e,t),s=function(){oe.dequeue(e,t)};"inprogress"===r&&(r=n.shift(),i--),r&&("fx"===t&&n.unshift("inprogress"),delete o.stop,r.call(e,s,o)),!i&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Ee.get(e,n)||Ee.access(e,n,{empty:oe.Callbacks("once memory").add(function(){Ee.remove(e,[t+"queue",n])})})}}),oe.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length",""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};Pe.optgroup=Pe.option,Pe.tbody=Pe.tfoot=Pe.colgroup=Pe.caption=Pe.thead,Pe.th=Pe.td;var Fe=/<|&#?\w+;/;!function(){var e=Q.createDocumentFragment(),t=e.appendChild(Q.createElement("div")),n=Q.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),ie.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",ie.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var $e=/^key/,Re=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ie=/^([^.]*)(?:\.(.+)|)/;oe.event={global:{},add:function(e,t,n,i,r){var o,s,a,u,l,c,f,d,h,p,g,v=Ee.get(e);if(v)for(n.handler&&(o=n,n=o.handler,r=o.selector),n.guid||(n.guid=oe.guid++),(u=v.events)||(u=v.events={}),(s=v.handle)||(s=v.handle=function(t){return"undefined"!=typeof oe&&oe.event.triggered!==t.type?oe.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(we)||[""],l=t.length;l--;)a=Ie.exec(t[l])||[],h=g=a[1],p=(a[2]||"").split(".").sort(),h&&(f=oe.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,f=oe.event.special[h]||{},c=oe.extend({type:h,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&oe.expr.match.needsContext.test(r),namespace:p.join(".")},o),(d=u[h])||(d=u[h]=[],d.delegateCount=0,f.setup&&f.setup.call(e,i,p,s)!==!1||e.addEventListener&&e.addEventListener(h,s)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),r?d.splice(d.delegateCount++,0,c):d.push(c),oe.event.global[h]=!0)},remove:function(e,t,n,i,r){var o,s,a,u,l,c,f,d,h,p,g,v=Ee.hasData(e)&&Ee.get(e);if(v&&(u=v.events)){for(t=(t||"").match(we)||[""],l=t.length;l--;)if(a=Ie.exec(t[l])||[],h=g=a[1],p=(a[2]||"").split(".").sort(),h){for(f=oe.event.special[h]||{},h=(i?f.delegateType:f.bindType)||h,d=u[h]||[],a=a[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=d.length;o--;)c=d[o],!r&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(d.splice(o,1),c.selector&&d.delegateCount--,f.remove&&f.remove.call(e,c));s&&!d.length&&(f.teardown&&f.teardown.call(e,p,v.handle)!==!1||oe.removeEvent(e,h,v.handle),delete u[h])}else for(h in u)oe.event.remove(e,h+t[l],n,i,!0);oe.isEmptyObject(u)&&Ee.remove(e,"handle events")}},dispatch:function(e){e=oe.event.fix(e);var t,n,i,r,o,s=[],a=J.call(arguments),u=(Ee.get(this,"events")||{})[e.type]||[],l=oe.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){for(s=oe.event.handlers.call(this,e,u),t=0;(r=s[t++])&&!e.isPropagationStopped();)for(e.currentTarget=r.elem,n=0;(o=r.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,i=((oe.event.special[o.origType]||{}).handle||o.handler).apply(r.elem,a), +void 0!==i&&(e.result=i)===!1&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,i,r,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&("click"!==e.type||isNaN(e.button)||e.button<1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(i=[],n=0;n-1:oe.find(r,this,null,[u]).length),i[r]&&i.push(o);i.length&&s.push({elem:u,handlers:i})}return a]*)\/>/gi,Me=/\s*$/g;oe.extend({htmlPrefilter:function(e){return e.replace(We,"<$1>")},clone:function(e,t,n){var i,r,o,s,a=e.cloneNode(!0),u=oe.contains(e.ownerDocument,e);if(!(ie.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||oe.isXMLDoc(e)))for(s=c(a),o=c(e),i=0,r=o.length;i0&&f(s,!u&&c(e,"script")),a},cleanData:function(e){for(var t,n,i,r=oe.event.special,o=0;void 0!==(n=e[o]);o++)if(Te(n)){if(t=n[Ee.expando]){if(t.events)for(i in t.events)r[i]?oe.event.remove(n,i):oe.removeEvent(n,i,t.handle);n[Ee.expando]=void 0}n[ke.expando]&&(n[ke.expando]=void 0)}}}),oe.fn.extend({domManip:C,detach:function(e){return S(this,e,!0)},remove:function(e){return S(this,e)},text:function(e){return Se(this,function(e){return void 0===e?oe.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return C(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=m(this,e);t.appendChild(e)}})},prepend:function(){return C(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=m(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return C(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return C(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(oe.cleanData(c(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return oe.clone(this,e,t)})},html:function(e){return Se(this,function(e){var t=this[0]||{},n=0,i=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Me.test(e)&&!Pe[(qe.exec(e)||["",""])[1].toLowerCase()]){e=oe.htmlPrefilter(e);try{for(;n1)},show:function(){return D(this,!0)},hide:function(){return D(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){De(this)?oe(this).show():oe(this).hide()})}}),oe.Tween=_,_.prototype={constructor:_,init:function(e,t,n,i,r,o){this.elem=e,this.prop=n,this.easing=r||oe.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=i,this.unit=o||(oe.cssNumber[n]?"":"px")},cur:function(){var e=_.propHooks[this.prop];return e&&e.get?e.get(this):_.propHooks._default.get(this)},run:function(e){var t,n=_.propHooks[this.prop];return this.options.duration?this.pos=t=oe.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):_.propHooks._default.set(this),this}},_.prototype.init.prototype=_.prototype,_.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=oe.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){oe.fx.step[e.prop]?oe.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[oe.cssProps[e.prop]]&&!oe.cssHooks[e.prop]?e.elem[e.prop]=e.now:oe.style(e.elem,e.prop,e.now+e.unit)}}},_.propHooks.scrollTop=_.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},oe.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},oe.fx=_.prototype.init,oe.fx.step={};var rt,ot,st=/^(?:toggle|show|hide)$/,at=/queueHooks$/;oe.Animation=oe.extend(R,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return l(n.elem,e,Le.exec(t),n),n}]},tweener:function(e,t){oe.isFunction(e)?(t=e,e=["*"]):e=e.match(we);for(var n,i=0,r=e.length;i1)},removeAttr:function(e){return this.each(function(){oe.removeAttr(this,e)})}}),oe.extend({attr:function(e,t,n){var i,r,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?oe.prop(e,t,n):(1===o&&oe.isXMLDoc(e)||(t=t.toLowerCase(),r=oe.attrHooks[t]||(oe.expr.match.bool.test(t)?ut:void 0)),void 0!==n?null===n?void oe.removeAttr(e,t):r&&"set"in r&&void 0!==(i=r.set(e,n,t))?i:(e.setAttribute(t,n+""),n):r&&"get"in r&&null!==(i=r.get(e,t))?i:(i=oe.find.attr(e,t),null==i?void 0:i))},attrHooks:{type:{set:function(e,t){if(!ie.radioValue&&"radio"===t&&oe.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,i,r=0,o=t&&t.match(we);if(o&&1===e.nodeType)for(;n=o[r++];)i=oe.propFix[n]||n,oe.expr.match.bool.test(n)&&(e[i]=!1),e.removeAttribute(n)}}),ut={set:function(e,t,n){return t===!1?oe.removeAttr(e,n):e.setAttribute(n,n),n}},oe.each(oe.expr.match.bool.source.match(/\w+/g),function(e,t){var n=lt[t]||oe.find.attr;lt[t]=function(e,t,i){var r,o;return i||(o=lt[t],lt[t]=r,r=null!=n(e,t,i)?t.toLowerCase():null,lt[t]=o),r}});var ct=/^(?:input|select|textarea|button)$/i,ft=/^(?:a|area)$/i;oe.fn.extend({prop:function(e,t){return Se(this,oe.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[oe.propFix[e]||e]})}}),oe.extend({prop:function(e,t,n){var i,r,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&oe.isXMLDoc(e)||(t=oe.propFix[t]||t,r=oe.propHooks[t]),void 0!==n?r&&"set"in r&&void 0!==(i=r.set(e,n,t))?i:e[t]=n:r&&"get"in r&&null!==(i=r.get(e,t))?i:e[t]},propHooks:{tabIndex:{get:function(e){var t=oe.find.attr(e,"tabindex");return t?parseInt(t,10):ct.test(e.nodeName)||ft.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),ie.optSelected||(oe.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),oe.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){oe.propFix[this.toLowerCase()]=this});var dt=/[\t\r\n\f]/g;oe.fn.extend({addClass:function(e){var t,n,i,r,o,s,a,u=0;if(oe.isFunction(e))return this.each(function(t){oe(this).addClass(e.call(this,t,I(this)))});if("string"==typeof e&&e)for(t=e.match(we)||[];n=this[u++];)if(r=I(n),i=1===n.nodeType&&(" "+r+" ").replace(dt," ")){for(s=0;o=t[s++];)i.indexOf(" "+o+" ")<0&&(i+=o+" ");a=oe.trim(i),r!==a&&n.setAttribute("class",a)}return this},removeClass:function(e){var t,n,i,r,o,s,a,u=0;if(oe.isFunction(e))return this.each(function(t){oe(this).removeClass(e.call(this,t,I(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof e&&e)for(t=e.match(we)||[];n=this[u++];)if(r=I(n),i=1===n.nodeType&&(" "+r+" ").replace(dt," ")){for(s=0;o=t[s++];)for(;i.indexOf(" "+o+" ")>-1;)i=i.replace(" "+o+" "," ");a=oe.trim(i),r!==a&&n.setAttribute("class",a)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):oe.isFunction(e)?this.each(function(n){oe(this).toggleClass(e.call(this,n,I(this),t),t)}):this.each(function(){var t,i,r,o;if("string"===n)for(i=0,r=oe(this),o=e.match(we)||[];t=o[i++];)r.hasClass(t)?r.removeClass(t):r.addClass(t);else void 0!==e&&"boolean"!==n||(t=I(this),t&&Ee.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||e===!1?"":Ee.get(this,"__className__")||""))})},hasClass:function(e){var t,n,i=0;for(t=" "+e+" ";n=this[i++];)if(1===n.nodeType&&(" "+I(n)+" ").replace(dt," ").indexOf(t)>-1)return!0;return!1}});var ht=/\r/g;oe.fn.extend({val:function(e){var t,n,i,r=this[0];{if(arguments.length)return i=oe.isFunction(e),this.each(function(n){var r;1===this.nodeType&&(r=i?e.call(this,n,oe(this).val()):e,null==r?r="":"number"==typeof r?r+="":oe.isArray(r)&&(r=oe.map(r,function(e){return null==e?"":e+""})),t=oe.valHooks[this.type]||oe.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&void 0!==t.set(this,r,"value")||(this.value=r))});if(r)return t=oe.valHooks[r.type]||oe.valHooks[r.nodeName.toLowerCase()],t&&"get"in t&&void 0!==(n=t.get(r,"value"))?n:(n=r.value,"string"==typeof n?n.replace(ht,""):null==n?"":n)}}}),oe.extend({valHooks:{option:{get:function(e){return oe.trim(e.value)}},select:{get:function(e){for(var t,n,i=e.options,r=e.selectedIndex,o="select-one"===e.type||r<0,s=o?null:[],a=o?r+1:i.length,u=r<0?a:o?r:0;u-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),oe.each(["radio","checkbox"],function(){oe.valHooks[this]={set:function(e,t){if(oe.isArray(t))return e.checked=oe.inArray(oe(e).val(),t)>-1}},ie.checkOn||(oe.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var pt=/^(?:focusinfocus|focusoutblur)$/;oe.extend(oe.event,{trigger:function(t,n,i,r){var o,s,a,u,l,c,f,d=[i||Q],h=ne.call(t,"type")?t.type:t,p=ne.call(t,"namespace")?t.namespace.split("."):[];if(s=a=i=i||Q,3!==i.nodeType&&8!==i.nodeType&&!pt.test(h+oe.event.triggered)&&(h.indexOf(".")>-1&&(p=h.split("."),h=p.shift(),p.sort()),l=h.indexOf(":")<0&&"on"+h,t=t[oe.expando]?t:new oe.Event(h,"object"==typeof t&&t),t.isTrigger=r?2:3,t.namespace=p.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:oe.makeArray(n,[t]),f=oe.event.special[h]||{},r||!f.trigger||f.trigger.apply(i,n)!==!1)){if(!r&&!f.noBubble&&!oe.isWindow(i)){for(u=f.delegateType||h,pt.test(u+h)||(s=s.parentNode);s;s=s.parentNode)d.push(s),a=s;a===(i.ownerDocument||Q)&&d.push(a.defaultView||a.parentWindow||e)}for(o=0;(s=d[o++])&&!t.isPropagationStopped();)t.type=o>1?u:f.bindType||h,c=(Ee.get(s,"events")||{})[t.type]&&Ee.get(s,"handle"),c&&c.apply(s,n),c=l&&s[l],c&&c.apply&&Te(s)&&(t.result=c.apply(s,n),t.result===!1&&t.preventDefault());return t.type=h,r||t.isDefaultPrevented()||f._default&&f._default.apply(d.pop(),n)!==!1||!Te(i)||l&&oe.isFunction(i[h])&&!oe.isWindow(i)&&(a=i[l],a&&(i[l]=null),oe.event.triggered=h,i[h](),oe.event.triggered=void 0,a&&(i[l]=a)),t.result}},simulate:function(e,t,n){var i=oe.extend(new oe.Event,n,{type:e,isSimulated:!0});oe.event.trigger(i,null,t),i.isDefaultPrevented()&&n.preventDefault()}}),oe.fn.extend({trigger:function(e,t){return this.each(function(){oe.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return oe.event.trigger(e,t,n,!0)}}),oe.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){oe.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),oe.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),ie.focusin="onfocusin"in e,ie.focusin||oe.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){oe.event.simulate(t,e.target,oe.event.fix(e))};oe.event.special[t]={setup:function(){var i=this.ownerDocument||this,r=Ee.access(i,t);r||i.addEventListener(e,n,!0),Ee.access(i,t,(r||0)+1)},teardown:function(){var i=this.ownerDocument||this,r=Ee.access(i,t)-1;r?Ee.access(i,t,r):(i.removeEventListener(e,n,!0),Ee.remove(i,t))}}});var gt=e.location,vt=oe.now(),mt=/\?/;oe.parseJSON=function(e){return JSON.parse(e+"")},oe.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||oe.error("Invalid XML: "+t),n};var yt=/#.*$/,xt=/([?&])_=[^&]*/,bt=/^(.*?):[ \t]*([^\r\n]*)$/gm,wt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ct=/^(?:GET|HEAD)$/,St=/^\/\//,Tt={},Et={},kt="*/".concat("*"),Nt=Q.createElement("a");Nt.href=gt.href,oe.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:gt.href,type:"GET",isLocal:wt.test(gt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":kt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":oe.parseJSON,"text xml":oe.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?B(B(e,oe.ajaxSettings),t):B(oe.ajaxSettings,e)},ajaxPrefilter:W(Tt),ajaxTransport:W(Et),ajax:function(t,n){function i(t,n,i,a){var l,f,y,x,w,S=n;2!==b&&(b=2,u&&e.clearTimeout(u),r=void 0,s=a||"",C.readyState=t>0?4:0,l=t>=200&&t<300||304===t,i&&(x=z(d,C,i)),x=V(d,x,C,l),l?(d.ifModified&&(w=C.getResponseHeader("Last-Modified"),w&&(oe.lastModified[o]=w),w=C.getResponseHeader("etag"),w&&(oe.etag[o]=w)),204===t||"HEAD"===d.type?S="nocontent":304===t?S="notmodified":(S=x.state,f=x.data,y=x.error,l=!y)):(y=S,!t&&S||(S="error",t<0&&(t=0))),C.status=t,C.statusText=(n||S)+"",l?g.resolveWith(h,[f,S,C]):g.rejectWith(h,[C,S,y]),C.statusCode(m),m=void 0,c&&p.trigger(l?"ajaxSuccess":"ajaxError",[C,d,l?f:y]),v.fireWith(h,[C,S]),c&&(p.trigger("ajaxComplete",[C,d]),--oe.active||oe.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=void 0),n=n||{};var r,o,s,a,u,l,c,f,d=oe.ajaxSetup({},n),h=d.context||d,p=d.context&&(h.nodeType||h.jquery)?oe(h):oe.event,g=oe.Deferred(),v=oe.Callbacks("once memory"),m=d.statusCode||{},y={},x={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!a)for(a={};t=bt.exec(s);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=x[n]=x[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(b<2)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return r&&r.abort(t),i(0,t),this}};if(g.promise(C).complete=v.add,C.success=C.done,C.error=C.fail,d.url=((t||d.url||gt.href)+"").replace(yt,"").replace(St,gt.protocol+"//"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=oe.trim(d.dataType||"*").toLowerCase().match(we)||[""],null==d.crossDomain){l=Q.createElement("a");try{l.href=d.url,l.href=l.href,d.crossDomain=Nt.protocol+"//"+Nt.host!=l.protocol+"//"+l.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&"string"!=typeof d.data&&(d.data=oe.param(d.data,d.traditional)),M(Tt,d,n,C),2===b)return C;c=oe.event&&d.global,c&&0===oe.active++&&oe.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!Ct.test(d.type),o=d.url,d.hasContent||(d.data&&(o=d.url+=(mt.test(o)?"&":"?")+d.data,delete d.data),d.cache===!1&&(d.url=xt.test(o)?o.replace(xt,"$1_="+vt++):o+(mt.test(o)?"&":"?")+"_="+vt++)),d.ifModified&&(oe.lastModified[o]&&C.setRequestHeader("If-Modified-Since",oe.lastModified[o]),oe.etag[o]&&C.setRequestHeader("If-None-Match",oe.etag[o])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",d.contentType),C.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+kt+"; q=0.01":""):d.accepts["*"]);for(f in d.headers)C.setRequestHeader(f,d.headers[f]);if(d.beforeSend&&(d.beforeSend.call(h,C,d)===!1||2===b))return C.abort();w="abort";for(f in{success:1,error:1,complete:1})C[f](d[f]);if(r=M(Et,d,n,C)){if(C.readyState=1,c&&p.trigger("ajaxSend",[C,d]),2===b)return C;d.async&&d.timeout>0&&(u=e.setTimeout(function(){C.abort("timeout")},d.timeout));try{b=1,r.send(y,i)}catch(e){if(!(b<2))throw e;i(-1,e)}}else i(-1,"No Transport");return C},getJSON:function(e,t,n){return oe.get(e,t,n,"json")},getScript:function(e,t){return oe.get(e,void 0,t,"script")}}),oe.each(["get","post"],function(e,t){oe[t]=function(e,n,i,r){return oe.isFunction(n)&&(r=r||i,i=n,n=void 0),oe.ajax(oe.extend({url:e,type:t,dataType:r,data:n,success:i},oe.isPlainObject(e)&&e))}}),oe._evalUrl=function(e){return oe.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},oe.fn.extend({wrapAll:function(e){var t;return oe.isFunction(e)?this.each(function(t){oe(this).wrapAll(e.call(this,t))}):(this[0]&&(t=oe(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return oe.isFunction(e)?this.each(function(t){oe(this).wrapInner(e.call(this,t))}):this.each(function(){var t=oe(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=oe.isFunction(e);return this.each(function(n){oe(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){oe.nodeName(this,"body")||oe(this).replaceWith(this.childNodes)}).end()}}),oe.expr.filters.hidden=function(e){return!oe.expr.filters.visible(e)},oe.expr.filters.visible=function(e){return e.offsetWidth>0||e.offsetHeight>0||e.getClientRects().length>0};var At=/%20/g,jt=/\[\]$/,Lt=/\r?\n/g,Ot=/^(?:submit|button|image|reset|file)$/i,Dt=/^(?:input|select|textarea|keygen)/i;oe.param=function(e,t){var n,i=[],r=function(e,t){t=oe.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=oe.ajaxSettings&&oe.ajaxSettings.traditional),oe.isArray(e)||e.jquery&&!oe.isPlainObject(e))oe.each(e,function(){r(this.name,this.value)});else for(n in e)X(n,e[n],t,r);return i.join("&").replace(At,"+")},oe.fn.extend({serialize:function(){return oe.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=oe.prop(this,"elements");return e?oe.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!oe(this).is(":disabled")&&Dt.test(this.nodeName)&&!Ot.test(e)&&(this.checked||!_e.test(e))}).map(function(e,t){var n=oe(this).val();return null==n?null:oe.isArray(n)?oe.map(n,function(e){return{name:t.name,value:e.replace(Lt,"\r\n")}}):{name:t.name,value:n.replace(Lt,"\r\n")}}).get()}}),oe.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},qt=oe.ajaxSettings.xhr();ie.cors=!!qt&&"withCredentials"in qt,ie.ajax=qt=!!qt,oe.ajaxTransport(function(t){var n,i;if(ie.cors||qt&&!t.crossDomain)return{send:function(r,o){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||r["X-Requested-With"]||(r["X-Requested-With"]="XMLHttpRequest");for(s in r)a.setRequestHeader(s,r[s]);n=function(e){return function(){n&&(n=i=a.onload=a.onerror=a.onabort=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?o(0,"error"):o(a.status,a.statusText):o(_t[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=n(),i=a.onerror=n("error"),void 0!==a.onabort?a.onabort=i:a.onreadystatechange=function(){4===a.readyState&&e.setTimeout(function(){n&&i()})},n=n("abort");try{a.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),oe.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return oe.globalEval(e),e}}}),oe.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),oe.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,r){t=oe("