diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 378eac2..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build diff --git a/01_bare_minimum/README.md b/01_bare_minimum/README.md deleted file mode 100644 index c79b16c..0000000 --- a/01_bare_minimum/README.md +++ /dev/null @@ -1,5 +0,0 @@ -To compile, run - -``` -npm build . -``` diff --git a/01_bare_minimum/binding.gyp b/01_bare_minimum/binding.gyp deleted file mode 100644 index 469aa6b..0000000 --- a/01_bare_minimum/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "modulename", - "sources": [ "modulename.cpp" ] - } - ] -} diff --git a/01_bare_minimum/modulename.cpp b/01_bare_minimum/modulename.cpp deleted file mode 100644 index b55f2d0..0000000 --- a/01_bare_minimum/modulename.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -void RegisterModule(v8::Handle target) { - // You can add properties to the module in this function. It is called - // when the module is required by node. -} - -// Register the module with node. Note that "modulename" must be the same as -// the basename of the resulting .node file. You can specify that name in -// binding.gyp ("target_name"). When you change it there, change it here too. -NODE_MODULE(modulename, RegisterModule); diff --git a/01_bare_minimum/package.json b/01_bare_minimum/package.json deleted file mode 100644 index 1b70c6d..0000000 --- a/01_bare_minimum/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "modulename", - "version": "1.0.0", - "main": "./build/Release/modulename" -} \ No newline at end of file diff --git a/01_bare_minimum/run.js b/01_bare_minimum/run.js deleted file mode 100644 index c9eb02c..0000000 --- a/01_bare_minimum/run.js +++ /dev/null @@ -1,3 +0,0 @@ -var modulename = require('./build/Release/modulename'); - -console.warn(modulename); diff --git a/02_functions/README.md b/02_functions/README.md deleted file mode 100644 index c79b16c..0000000 --- a/02_functions/README.md +++ /dev/null @@ -1,5 +0,0 @@ -To compile, run - -``` -npm build . -``` diff --git a/02_functions/binding.gyp b/02_functions/binding.gyp deleted file mode 100644 index 469aa6b..0000000 --- a/02_functions/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "modulename", - "sources": [ "modulename.cpp" ] - } - ] -} diff --git a/02_functions/modulename.cpp b/02_functions/modulename.cpp deleted file mode 100644 index 543b69c..0000000 --- a/02_functions/modulename.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include - -// C standard library -#include -#include - -using namespace v8; - -// This function returns a JavaScript number that is either 0 or 1. -Handle Random(const Arguments& args) { - // At the top of every function that uses anything about v8, include a - // definition like this. It ensures that any v8 handles you create in that - // function are properly cleaned up. If you see memory rising in your - // application, chances are that a scope isn't properly cleaned up. - HandleScope scope; - - // When returning a value from a function, make sure to wrap it in - // scope.Close(). This ensures that the handle stays valid after the current - // scope (declared with the previous statement) is cleaned up. - return scope.Close( - // Creating a new JavaScript integer is as simple as passing a C int - // (technically a int32_t) to this function. - Integer::New(rand() % 2) - ); -} - -void RegisterModule(Handle target) { - srand(time(NULL)); - - // target is the module object you see when require()ing the .node file. - target->Set(String::NewSymbol("random"), - FunctionTemplate::New(Random)->GetFunction()); -} - -NODE_MODULE(modulename, RegisterModule); diff --git a/02_functions/package.json b/02_functions/package.json deleted file mode 100644 index 1b70c6d..0000000 --- a/02_functions/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "modulename", - "version": "1.0.0", - "main": "./build/Release/modulename" -} \ No newline at end of file diff --git a/02_functions/run.js b/02_functions/run.js deleted file mode 100644 index 0e4a221..0000000 --- a/02_functions/run.js +++ /dev/null @@ -1,3 +0,0 @@ -var modulename = require('./build/Release/modulename'); - -console.warn(modulename.random()); diff --git a/03_function_arguments/README.md b/03_function_arguments/README.md deleted file mode 100644 index c79b16c..0000000 --- a/03_function_arguments/README.md +++ /dev/null @@ -1,5 +0,0 @@ -To compile, run - -``` -npm build . -``` diff --git a/03_function_arguments/binding.gyp b/03_function_arguments/binding.gyp deleted file mode 100644 index 469aa6b..0000000 --- a/03_function_arguments/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "modulename", - "sources": [ "modulename.cpp" ] - } - ] -} diff --git a/03_function_arguments/modulename.cpp b/03_function_arguments/modulename.cpp deleted file mode 100644 index 33d547a..0000000 --- a/03_function_arguments/modulename.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include - -using namespace v8; - -// Returns the Nth number in the fibonacci sequence where N is the first -// argument passed. -Handle Fibonacci(const Arguments& args) { - HandleScope scope; - - // Check that there are enough arguments. If we access an index that doesn't - // exist, it'll be Undefined(). - if (args.Length() < 1) { - // No argument was passed. Throw an exception to alert the user to - // incorrect usage. Alternatively, we could just use 0. - return ThrowException( - Exception::TypeError(String::New("First argument must be a number")) - ); - } - - // Cast a value to a specific type. See - // http://izs.me/v8-docs/classv8_1_1Value.html for available To*() functions - // and type checking functions. When converting to integer, make sure the - // POD type you use is big enough! - Local integer = args[0]->ToInteger(); - int32_t seq = integer->Value(); - - // Also possible in one call. (Don't forget HandleScope, otherwise the - // intermediate Local handle won't be cleaned up!) - // int32_t seq = args[0]->ToInteger()->Value(); - - // Check for invalid parameter. - if (seq < 0) { - return ThrowException(Exception::TypeError(String::New( - "Fibonacci sequence number must be positive"))); - } - - // The actual algorithm. - int32_t current = 1; - for (int32_t previous = -1, next = 0, i = 0; i <= seq; i++) { - next = previous + current; - previous = current; - current = next; - } - - return scope.Close(Integer::New(current)); -} - -void RegisterModule(Handle target) { - target->Set(String::NewSymbol("fibonacci"), - FunctionTemplate::New(Fibonacci)->GetFunction()); -} - -NODE_MODULE(modulename, RegisterModule); diff --git a/03_function_arguments/package.json b/03_function_arguments/package.json deleted file mode 100644 index 1b70c6d..0000000 --- a/03_function_arguments/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "modulename", - "version": "1.0.0", - "main": "./build/Release/modulename" -} \ No newline at end of file diff --git a/03_function_arguments/run.js b/03_function_arguments/run.js deleted file mode 100644 index cc5fa0f..0000000 --- a/03_function_arguments/run.js +++ /dev/null @@ -1,3 +0,0 @@ -var modulename = require('./build/Release/modulename'); - -console.warn(modulename.fibonacci(9)); diff --git a/04_callback_functions/README.md b/04_callback_functions/README.md deleted file mode 100644 index c79b16c..0000000 --- a/04_callback_functions/README.md +++ /dev/null @@ -1,5 +0,0 @@ -To compile, run - -``` -npm build . -``` diff --git a/04_callback_functions/binding.gyp b/04_callback_functions/binding.gyp deleted file mode 100644 index 469aa6b..0000000 --- a/04_callback_functions/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "modulename", - "sources": [ "modulename.cpp" ] - } - ] -} diff --git a/04_callback_functions/modulename.cpp b/04_callback_functions/modulename.cpp deleted file mode 100644 index 7822514..0000000 --- a/04_callback_functions/modulename.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include - -using namespace v8; - - -Handle Callback(const Arguments& args) { - HandleScope scope; - - // Ensure that we got a callback. Generally, your functions should have - // optional callbacks. In this case, you can declare an empty - // Local handle and check for content before calling. - if (!args[1]->IsFunction()) { - return ThrowException(Exception::TypeError( - String::New("Second argument must be a callback function"))); - } - // There's no ToFunction(), use a Cast instead. - Local callback = Local::Cast(args[1]); - - // Our fake API allows the user to tell us whether we should cause an error. - bool error = args[0]->BooleanValue(); - - if (error) { - Local err = Exception::Error(String::New("Something went wrong!")); - - // Optionally add more properties to the exception object. - err->ToObject()->Set(NODE_PSYMBOL("errno"), Integer::New(23)); - - // Prepare the parameters for the callback function. - const unsigned argc = 1; - Local argv[argc] = { err }; - - // Note: When calling this in an asynchronous function that just returned - // from the threadpool, you have to wrap this in a v8::TryCatch. - // You can also pass another handle as the "this" parameter. - callback->Call(Context::GetCurrent()->Global(), argc, argv); - } else { - // In case the operation succeeded, convention is to pass null as the - // first argument before the result arguments. - const unsigned argc = 2; - Local argv[argc] = { - Local::New(Null()), - Local::New(Integer::New(42)) - }; - - // Note: When calling this in an asynchronous function that just returned - // from the threadpool, you have to wrap this in a v8::TryCatch. - // You can also pass another handle as the "this" parameter. - callback->Call(Context::GetCurrent()->Global(), argc, argv); - } - - return Undefined(); -} - -void RegisterModule(Handle target) { - target->Set(String::NewSymbol("callback"), - FunctionTemplate::New(Callback)->GetFunction()); -} - -NODE_MODULE(modulename, RegisterModule); diff --git a/04_callback_functions/package.json b/04_callback_functions/package.json deleted file mode 100644 index 1b70c6d..0000000 --- a/04_callback_functions/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "modulename", - "version": "1.0.0", - "main": "./build/Release/modulename" -} \ No newline at end of file diff --git a/04_callback_functions/run.js b/04_callback_functions/run.js deleted file mode 100644 index c112a56..0000000 --- a/04_callback_functions/run.js +++ /dev/null @@ -1,5 +0,0 @@ -var modulename = require('./build/Release/modulename'); - -modulename.callback(false, function(err, result) { - console.warn(result); -}); diff --git a/05_threadpool/README.md b/05_threadpool/README.md deleted file mode 100644 index c79b16c..0000000 --- a/05_threadpool/README.md +++ /dev/null @@ -1,5 +0,0 @@ -To compile, run - -``` -npm build . -``` diff --git a/05_threadpool/binding.gyp b/05_threadpool/binding.gyp deleted file mode 100644 index 469aa6b..0000000 --- a/05_threadpool/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "modulename", - "sources": [ "modulename.cpp" ] - } - ] -} diff --git a/05_threadpool/modulename.cpp b/05_threadpool/modulename.cpp deleted file mode 100644 index cf49c1f..0000000 --- a/05_threadpool/modulename.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include - -using namespace v8; - - -// Forward declaration. Usually, you do this in a header file. -Handle Async(const Arguments& args); -void AsyncWork(uv_work_t* req); -void AsyncAfter(uv_work_t* req); - - -// We use a struct to store information about the asynchronous "work request". -struct Baton { - // This handle holds the callback function we'll call after the work request - // has been completed in a threadpool thread. It's persistent so that V8 - // doesn't garbage collect it away while our request waits to be processed. - // This means that we'll have to dispose of it later ourselves. - Persistent callback; - - // Tracking errors that happened in the worker function. You can use any - // variables you want. E.g. in some cases, it might be useful to report - // an error number. - bool error; - std::string error_message; - - // Custom data you can pass through. - int32_t result; -}; - -// This is the function called directly from JavaScript land. It creates a -// work request object and schedules it for execution. -Handle Async(const Arguments& args) { - HandleScope scope; - - if (!args[0]->IsFunction()) { - return ThrowException(Exception::TypeError( - String::New("First argument must be a callback function"))); - } - // There's no ToFunction(), use a Cast instead. - Local callback = Local::Cast(args[0]); - - // The baton holds our custom status information for this asynchronous call, - // like the callback function we want to call when returning to the main - // thread and the status information. - Baton* baton = new Baton(); - baton->error = false; - baton->callback = Persistent::New(callback); - - // This creates the work request struct. - uv_work_t *req = new uv_work_t(); - req->data = baton; - - // Schedule our work request with libuv. Here you can specify the functions - // that should be executed in the threadpool and back in the main thread - // after the threadpool function completed. - int status = uv_queue_work(uv_default_loop(), req, AsyncWork, - (uv_after_work_cb)AsyncAfter); - assert(status == 0); - - return Undefined(); -} - -// This function is executed in another thread at some point after it has been -// scheduled. IT MUST NOT USE ANY V8 FUNCTIONALITY. Otherwise your extension -// will crash randomly and you'll have a lot of fun debugging. -// If you want to use parameters passed into the original call, you have to -// convert them to PODs or some other fancy method. -void AsyncWork(uv_work_t* req) { - Baton* baton = static_cast(req->data); - - // Do work in threadpool here. - baton->result = 42; - - // If the work we do fails, set baton->error_message to the error string - // and baton->error to true. -} - -// This function is executed in the main V8/JavaScript thread. That means it's -// safe to use V8 functions again. Don't forget the HandleScope! -void AsyncAfter(uv_work_t* req) { - HandleScope scope; - Baton* baton = static_cast(req->data); - - if (baton->error) { - Local err = Exception::Error(String::New(baton->error_message.c_str())); - - // Prepare the parameters for the callback function. - const unsigned argc = 1; - Local argv[argc] = { err }; - - // Wrap the callback function call in a TryCatch so that we can call - // node's FatalException afterwards. This makes it possible to catch - // the exception from JavaScript land using the - // process.on('uncaughtException') event. - TryCatch try_catch; - baton->callback->Call(Context::GetCurrent()->Global(), argc, argv); - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - } else { - // In case the operation succeeded, convention is to pass null as the - // first argument before the result arguments. - // In case you produced more complex data, this is the place to convert - // your plain C++ data structures into JavaScript/V8 data structures. - const unsigned argc = 2; - Local argv[argc] = { - Local::New(Null()), - Local::New(Integer::New(baton->result)) - }; - - // Wrap the callback function call in a TryCatch so that we can call - // node's FatalException afterwards. This makes it possible to catch - // the exception from JavaScript land using the - // process.on('uncaughtException') event. - TryCatch try_catch; - baton->callback->Call(Context::GetCurrent()->Global(), argc, argv); - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - } - - // The callback is a permanent handle, so we have to dispose of it manually. - baton->callback.Dispose(); - - // We also created the baton and the work_req struct with new, so we have to - // manually delete both. - delete baton; - delete req; -} - -void RegisterModule(Handle target) { - target->Set(String::NewSymbol("async"), - FunctionTemplate::New(Async)->GetFunction()); -} - -NODE_MODULE(modulename, RegisterModule); diff --git a/05_threadpool/package.json b/05_threadpool/package.json deleted file mode 100644 index 1b70c6d..0000000 --- a/05_threadpool/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "modulename", - "version": "1.0.0", - "main": "./build/Release/modulename" -} \ No newline at end of file diff --git a/05_threadpool/run.js b/05_threadpool/run.js deleted file mode 100644 index 1152ca4..0000000 --- a/05_threadpool/run.js +++ /dev/null @@ -1,5 +0,0 @@ -var modulename = require('./build/Release/modulename'); - -modulename.async(function(err, result) { - console.warn(result); -}); diff --git a/06_objects/README.md b/06_objects/README.md deleted file mode 100644 index c79b16c..0000000 --- a/06_objects/README.md +++ /dev/null @@ -1,5 +0,0 @@ -To compile, run - -``` -npm build . -``` diff --git a/06_objects/binding.gyp b/06_objects/binding.gyp deleted file mode 100644 index 469aa6b..0000000 --- a/06_objects/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "modulename", - "sources": [ "modulename.cpp" ] - } - ] -} diff --git a/06_objects/modulename.cpp b/06_objects/modulename.cpp deleted file mode 100644 index b5943ae..0000000 --- a/06_objects/modulename.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include - -#include "modulename.hpp" - -using namespace v8; - - -Persistent MyObject::constructor; - -void MyObject::Init(Handle target) { - HandleScope scope; - - Local tpl = FunctionTemplate::New(New); - Local name = String::NewSymbol("MyObject"); - - constructor = Persistent::New(tpl); - // ObjectWrap uses the first internal field to store the wrapped pointer. - constructor->InstanceTemplate()->SetInternalFieldCount(1); - constructor->SetClassName(name); - - // Add all prototype methods, getters and setters here. - NODE_SET_PROTOTYPE_METHOD(constructor, "value", Value); - - // This has to be last, otherwise the properties won't show up on the - // object in JavaScript. - target->Set(name, constructor->GetFunction()); -} - -MyObject::MyObject(int val) - : ObjectWrap(), - value_(val) {} - - -Handle MyObject::New(const Arguments& args) { - HandleScope scope; - - if (!args.IsConstructCall()) { - return ThrowException(Exception::TypeError( - String::New("Use the new operator to create instances of this object.")) - ); - } - - if (args.Length() < 1) { - return ThrowException(Exception::TypeError( - String::New("First argument must be a number"))); - } - - // Creates a new instance object of this type and wraps it. - MyObject* obj = new MyObject(args[0]->ToInteger()->Value()); - obj->Wrap(args.This()); - - return args.This(); -} - - -Handle MyObject::Value(const Arguments& args) { - HandleScope scope; - - // Retrieves the pointer to the wrapped object instance. - MyObject* obj = ObjectWrap::Unwrap(args.This()); - - return scope.Close(Integer::New(obj->value_)); -} - - - - - - - - -void RegisterModule(Handle target) { - MyObject::Init(target); -} - -NODE_MODULE(modulename, RegisterModule); diff --git a/06_objects/modulename.hpp b/06_objects/modulename.hpp deleted file mode 100644 index 9335659..0000000 --- a/06_objects/modulename.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef MODULENAME_HPP -#define MODULENAME_HPP - -#include - - -// Do not include this line. It's generally frowned upon to use namespaces -// in header files as it may cause issues with other code that includes your -// header file. -// using namespace v8; - - -class MyObject : public node::ObjectWrap { -public: - static v8::Persistent constructor; - static void Init(v8::Handle target); - -protected: - MyObject(int val); - - static v8::Handle New(const v8::Arguments& args); - static v8::Handle Value(const v8::Arguments& args); - - // Your own object variables here - int value_; -}; - -#endif diff --git a/06_objects/package.json b/06_objects/package.json deleted file mode 100644 index 1b70c6d..0000000 --- a/06_objects/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "modulename", - "version": "1.0.0", - "main": "./build/Release/modulename" -} \ No newline at end of file diff --git a/06_objects/run.js b/06_objects/run.js deleted file mode 100644 index 21b8267..0000000 --- a/06_objects/run.js +++ /dev/null @@ -1,5 +0,0 @@ -var modulename = require('./build/Release/modulename'); - -var obj = new modulename.MyObject(42); -console.warn(obj); -console.warn(obj.value()); diff --git a/README.md b/README.md index 65f0fb8..7392f00 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,4 @@ -# How to write node.js modules using C++ +node-cpp-modules +================ -This is a tutorial for writing [node.js](http://nodejs.org/) modules in C++. It is the base and reference for my talk on writing node.js modules with V8 at [JSConf 2011 in Berlin](http://jsconf.eu/2011). - -Further references: - -* [V8 Doxygen](http://izs.me/v8-docs/main.html) -* [uv.h](https://github.com/joyent/libuv/blob/master/include/uv.h) -* [An introduction to libuv](http://nikhilm.github.com/uvbook/) -* [v8 Cookbook](http://create.tpsitulsa.com/wiki/V8_Cookbook) -* [Google's C++ style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml) +Guide for writing C++ node.js extensions diff --git a/deck/core/deck.core.css b/deck/core/deck.core.css new file mode 100644 index 0000000..29ab0d0 --- /dev/null +++ b/deck/core/deck.core.css @@ -0,0 +1,393 @@ +html { + height: 100%; +} + +.deck-container { + position: relative; + height: 100%; + width: 70%; + margin: 0 auto; + padding: 0 48px; + font-size: 16px; + line-height: 1.25; + overflow: hidden; + /* Resets and base styles from HTML5 Boilerplate */ + /* End HTML5 Boilerplate adaptations */ +} +.js .deck-container { + visibility: hidden; +} +.ready .deck-container { + visibility: visible; +} +.touch .deck-container { + -webkit-text-size-adjust: none; +} +.deck-container div, .deck-container span, .deck-container object, .deck-container iframe, +.deck-container h1, .deck-container h2, .deck-container h3, .deck-container h4, .deck-container h5, .deck-container h6, .deck-container p, .deck-container blockquote, .deck-container pre, +.deck-container abbr, .deck-container address, .deck-container cite, .deck-container code, .deck-container del, .deck-container dfn, .deck-container em, .deck-container img, .deck-container ins, .deck-container kbd, .deck-container q, .deck-container samp, +.deck-container small, .deck-container strong, .deck-container sub, .deck-container sup, .deck-container var, .deck-container b, .deck-container i, .deck-container dl, .deck-container dt, .deck-container dd, .deck-container ol, .deck-container ul, .deck-container li, +.deck-container fieldset, .deck-container form, .deck-container label, .deck-container legend, +.deck-container table, .deck-container caption, .deck-container tbody, .deck-container tfoot, .deck-container thead, .deck-container tr, .deck-container th, .deck-container td, +.deck-container article, .deck-container aside, .deck-container canvas, .deck-container details, .deck-container figcaption, .deck-container figure, +.deck-container footer, .deck-container header, .deck-container hgroup, .deck-container menu, .deck-container nav, .deck-container section, .deck-container summary, +.deck-container time, .deck-container mark, .deck-container audio, .deck-container video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +.deck-container article, .deck-container aside, .deck-container details, .deck-container figcaption, .deck-container figure, +.deck-container footer, .deck-container header, .deck-container hgroup, .deck-container menu, .deck-container nav, .deck-container section { + display: block; +} +.deck-container blockquote, .deck-container q { + quotes: none; +} +.deck-container blockquote:before, .deck-container blockquote:after, .deck-container q:before, .deck-container q:after { + content: ""; + content: none; +} +.deck-container ins { + background-color: #ff9; + color: #000; + text-decoration: none; +} +.deck-container mark { + background-color: #ff9; + color: #000; + font-style: italic; + font-weight: bold; +} +.deck-container del { + text-decoration: line-through; +} +.deck-container abbr[title], .deck-container dfn[title] { + border-bottom: 1px dotted; + cursor: help; +} +.deck-container table { + border-collapse: collapse; + border-spacing: 0; +} +.deck-container hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 1em 0; + padding: 0; +} +.deck-container input, .deck-container select { + vertical-align: middle; +} +.deck-container select, .deck-container input, .deck-container textarea, .deck-container button { + font: 99% sans-serif; +} +.deck-container pre, .deck-container code, .deck-container kbd, .deck-container samp { + font-family: monospace, sans-serif; +} +.deck-container a { + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +.deck-container a:hover, .deck-container a:active { + outline: none; +} +.deck-container ul, .deck-container ol { + margin-left: 2em; + vertical-align: top; +} +.deck-container ol { + list-style-type: decimal; +} +.deck-container nav ul, .deck-container nav li { + margin: 0; + list-style: none; + list-style-image: none; +} +.deck-container small { + font-size: 85%; +} +.deck-container strong, .deck-container th { + font-weight: bold; +} +.deck-container td { + vertical-align: top; +} +.deck-container sub, .deck-container sup { + font-size: 75%; + line-height: 0; + position: relative; +} +.deck-container sup { + top: -0.5em; +} +.deck-container sub { + bottom: -0.25em; +} +.deck-container textarea { + overflow: auto; +} +.ie6 .deck-container legend, .ie7 .deck-container legend { + margin-left: -7px; +} +.deck-container input[type="radio"] { + vertical-align: text-bottom; +} +.deck-container input[type="checkbox"] { + vertical-align: bottom; +} +.deck-container .ie7 input[type="checkbox"] { + vertical-align: baseline; +} +.deck-container .ie6 input { + vertical-align: text-bottom; +} +.deck-container label, .deck-container input[type="button"], .deck-container input[type="submit"], .deck-container input[type="image"], .deck-container button { + cursor: pointer; +} +.deck-container button, .deck-container input, .deck-container select, .deck-container textarea { + margin: 0; +} +.deck-container input:invalid, .deck-container textarea:invalid { + border-radius: 1px; + -moz-box-shadow: 0px 0px 5px red; + -webkit-box-shadow: 0px 0px 5px red; + box-shadow: 0px 0px 5px red; +} +.deck-container input:invalid .no-boxshadow, .deck-container textarea:invalid .no-boxshadow { + background-color: #f0dddd; +} +.deck-container button { + width: auto; + overflow: visible; +} +.ie7 .deck-container img { + -ms-interpolation-mode: bicubic; +} +.deck-container, .deck-container select, .deck-container input, .deck-container textarea { + color: #444; +} +.deck-container a { + color: #607890; +} +.deck-container a:hover, .deck-container a:focus { + color: #036; +} +.deck-container a:link { + -webkit-tap-highlight-color: #fff; +} +.deck-container h1 { + font-size: 4.5em; + font-weight: bold; + text-align: center; + padding-top: 1em; +} +.csstransforms .deck-container h1 { + padding: 0 48px; + position: absolute; + left: 0; + right: 0; + top: 50%; + -webkit-transform: translate3d(0, -50%, 0); + -moz-transform: translate(0, -50%); + -ms-transform: translate(0, -50%); + -o-transform: translate(0, -50%); + transform: translate3d(0, -50%, 0); +} +.deck-container h2 { + font-size: 2.25em; + font-weight: bold; + padding-top: .5em; + margin: 0 0 .66666em 0; + border-bottom: 3px solid #888; +} +.deck-container h3 { + font-size: 1.4375em; + font-weight: bold; + margin-bottom: .30435em; +} +.deck-container h4 { + font-size: 1.25em; + font-weight: bold; + margin-bottom: .25em; +} +.deck-container h5 { + font-size: 1.125em; + font-weight: bold; + margin-bottom: .2222em; +} +.deck-container h6 { + font-size: 1em; + font-weight: bold; +} +.deck-container img, .deck-container iframe, .deck-container video { + display: block; + max-width: 100%; +} +.deck-container video, .deck-container iframe, .deck-container img { + display: block; + margin: 0 auto; +} +.deck-container p, .deck-container blockquote, .deck-container iframe, .deck-container img, .deck-container ul, .deck-container ol, .deck-container pre, .deck-container video { + margin-bottom: 1em; +} +.deck-container pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; + padding: 1em; + border: 1px solid #888; +} +.deck-container em { + font-style: italic; +} +.deck-container li { + padding: .25em 0; + vertical-align: middle; +} +.deck-container.deck-loading { + display: none; +} + +.slide { + width: auto; + min-height: 100%; + position: relative; +} + +.deck-before, .deck-previous, .deck-next, .deck-after { + position: absolute; + left: -999em; + top: -999em; +} + +.deck-current { + z-index: 2; +} + +.slide .slide { + visibility: hidden; + position: static; + min-height: 0; +} + +.deck-child-current { + position: static; + z-index: 2; +} +.deck-child-current .slide { + visibility: hidden; +} +.deck-child-current .deck-previous, .deck-child-current .deck-before, .deck-child-current .deck-current { + visibility: visible; +} + +body.deck-container { + overflow: visible; +} + +@media all and (orientation:portrait) {} +@media all and (orientation:landscape) {} +@media screen and (max-device-width: 480px) { + /* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */ +} + +@media print { + * { + background: transparent !important; + color: black !important; + text-shadow: none !important; + filter: none !important; + -ms-filter: none !important; + -webkit-box-reflect: none !important; + -moz-box-reflect: none !important; + -webkit-box-shadow: none !important; + -moz-box-shadow: none !important; + box-shadow: none !important; + } + * :before, * :after { + display: none !important; + } + + a, a:visited { + color: #444 !important; + text-decoration: underline; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { + content: ""; + } + + pre, blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + thead { + display: table-header-group; + } + + tr, img { + page-break-inside: avoid; + } + + @page { + margin: 0.5cm; +} + + p, h2, h3 { + orphans: 3; + widows: 3; + } + + h2, h3 { + page-break-after: avoid; + } + + .slide { + position: static !important; + visibility: visible !important; + display: block !important; + -webkit-transform: none !important; + -moz-transform: none !important; + -o-transform: none !important; + -ms-transform: none !important; + transform: none !important; + } + + h1 { + -webkit-transform: none !important; + -moz-transform: none !important; + -o-transform: none !important; + -ms-transform: none !important; + transform: none !important; + padding: 0 !important; + position: static !important; + } + + .deck-container > .slide { + page-break-after: always; + } + + .deck-container { + width: 100% !important; + height: auto !important; + padding: 0 !important; + display: block !important; + } + + script { + display: none; + } +} diff --git a/deck/core/deck.core.js b/deck/core/deck.core.js new file mode 100644 index 0000000..f91d3c9 --- /dev/null +++ b/deck/core/deck.core.js @@ -0,0 +1,461 @@ +/*! +Deck JS - deck.core - v1.0 +Copyright (c) 2011 Caleb Troughton +Dual licensed under the MIT license and GPL license. +https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt +https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt +*/ + +/* +The deck.core module provides all the basic functionality for creating and +moving through a deck. It does so by applying classes to indicate the state of +the deck and its slides, allowing CSS to take care of the visual representation +of each state. It also provides methods for navigating the deck and inspecting +its state, as well as basic key bindings for going to the next and previous +slides. More functionality is provided by wholly separate extension modules +that use the API provided by core. +*/ +(function($, deck, document, undefined) { + var slides, // Array of all the uh, slides... + current, // Array index of the current slide + + events = { + /* + This event fires whenever the current slide changes, whether by way of + next, prev, or go. The callback function is passed two parameters, from + and to, equal to the indices of the old slide and the new slide + respectively. + + $(document).bind('deck.change', function(event, from, to) { + alert('Moving from slide ' + from + ' to ' + to); + }); + */ + change: 'deck.change', + + /* + This event fires at the end of deck initialization. Extensions should + implement any code that relies on user extensible options (key bindings, + element selectors, classes) within a handler for this event. Native + events associated with Deck JS should be scoped under a .deck event + namespace, as with the example below: + + var $d = $(document); + $.deck.defaults.keys.myExtensionKeycode = 70; // 'h' + $d.bind('deck.init', function() { + $d.bind('keydown.deck', function(event) { + if (event.which === $.deck.getOptions().keys.myExtensionKeycode) { + // Rock out + } + }); + }); + */ + initialize: 'deck.init' + }, + + options = {}, + $d = $(document), + + /* + Internal function. Updates slide and container classes based on which + slide is the current slide. + */ + updateStates = function() { + var oc = options.classes, + osc = options.selectors.container, + $container = $(osc), + old = $container.data('onSlide'), + $all = $(); + + // Container state + $container.removeClass(oc.onPrefix + old) + .addClass(oc.onPrefix + current) + .data('onSlide', current); + + // Remove and re-add child-current classes for nesting + $('.' + oc.current).parentsUntil(osc).removeClass(oc.childCurrent); + slides[current].parentsUntil(osc).addClass(oc.childCurrent); + + // Remove previous states + $.each(slides, function(i, el) { + $all = $all.add(el); + }); + $all.removeClass([ + oc.before, + oc.previous, + oc.current, + oc.next, + oc.after + ].join(" ")); + + // Add new states back in + slides[current].addClass(oc.current); + if (current > 0) { + slides[current-1].addClass(oc.previous); + } + if (current + 1 < slides.length) { + slides[current+1].addClass(oc.next); + } + if (current > 1) { + $.each(slides.slice(0, current - 1), function(i, el) { + el.addClass(oc.before); + }); + } + if (current + 2 < slides.length) { + $.each(slides.slice(current+2), function(i, el) { + el.addClass(oc.after); + }); + } + }, + + /* Methods exposed in the jQuery.deck namespace */ + methods = { + + /* + jQuery.deck(selector, options) + + selector: string | jQuery | array + options: object, optional + + Initializes the deck, using each element matched by selector as a slide. + May also be passed an array of string selectors or jQuery objects, in + which case each selector in the array is considered a slide. The second + parameter is an optional options object which will extend the default + values. + + $.deck('.slide'); + + or + + $.deck([ + '#first-slide', + '#second-slide', + '#etc' + ]); + */ + init: function(elements, opts) { + var startTouch, + $c, + tolerance, + esp = function(e) { + e.stopPropagation(); + }; + + options = $.extend(true, {}, $[deck].defaults, opts); + slides = []; + current = 0; + $c = $[deck]('getContainer'); + tolerance = options.touch.swipeTolerance; + + // Hide the deck while states are being applied to kill transitions + $c.addClass(options.classes.loading); + + // Fill slides array depending on parameter type + if ($.isArray(elements)) { + $.each(elements, function(i, e) { + slides.push($(e)); + }); + } + else { + $(elements).each(function(i, e) { + slides.push($(e)); + }); + } + + /* Remove any previous bindings, and rebind key events */ + $d.unbind('keydown.deck').bind('keydown.deck', function(e) { + if (e.which === options.keys.next || $.inArray(e.which, options.keys.next) > -1) { + methods.next(); + e.preventDefault(); + } + else if (e.which === options.keys.previous || $.inArray(e.which, options.keys.previous) > -1) { + methods.prev(); + e.preventDefault(); + } + }); + + /* Bind touch events for swiping between slides on touch devices */ + $c.unbind('touchstart.deck').bind('touchstart.deck', function(e) { + if (!startTouch) { + startTouch = $.extend({}, e.originalEvent.targetTouches[0]); + } + }) + .unbind('touchmove.deck').bind('touchmove.deck', function(e) { + $.each(e.originalEvent.changedTouches, function(i, t) { + if (startTouch && t.identifier === startTouch.identifier) { + if (t.screenX - startTouch.screenX > tolerance || t.screenY - startTouch.screenY > tolerance) { + $[deck]('prev'); + startTouch = undefined; + } + else if (t.screenX - startTouch.screenX < -1 * tolerance || t.screenY - startTouch.screenY < -1 * tolerance) { + $[deck]('next'); + startTouch = undefined; + } + return false; + } + }); + e.preventDefault(); + }) + .unbind('touchend.deck').bind('touchend.deck', function(t) { + $.each(t.originalEvent.changedTouches, function(i, t) { + if (startTouch && t.identifier === startTouch.identifier) { + startTouch = undefined; + } + }); + }) + .scrollLeft(0).scrollTop(0) + /* Stop propagation of key events within editable elements of slides */ + .undelegate('input, textarea, select, button, meter, progress, [contentEditable]', 'keydown', esp) + .delegate('input, textarea, select, button, meter, progress, [contentEditable]', 'keydown', esp); + + /* + Kick iframe videos, which dont like to redraw w/ transforms. + Remove this if Webkit ever fixes it. + */ + $.each(slides, function(i, $el) { + $el.unbind('webkitTransitionEnd.deck').bind('webkitTransitionEnd.deck', + function(event) { + if ($el.hasClass($[deck]('getOptions').classes.current)) { + var embeds = $(this).find('iframe').css('opacity', 0); + window.setTimeout(function() { + embeds.css('opacity', 1); + }, 100); + } + }); + }); + + updateStates(); + + // Show deck again now that slides are in place + $c.removeClass(options.classes.loading); + $d.trigger(events.initialize); + }, + + /* + jQuery.deck('go', index) + + index: integer + + Moves to the slide at the specified index. Index is 0-based, so + $.deck('go', 0); will move to the first slide. If index is out of bounds + or not a number the call is ignored. + */ + go: function(index) { + if (typeof index != 'number' || index < 0 || index >= slides.length) return; + + $d.trigger(events.change, [current, index]); + current = index; + updateStates(); + }, + + /* + jQuery.deck('next') + + Moves to the next slide. If the last slide is already active, the call + is ignored. + */ + next: function() { + methods.go(current+1); + }, + + /* + jQuery.deck('prev') + + Moves to the previous slide. If the first slide is already active, the + call is ignored. + */ + prev: function() { + methods.go(current-1); + }, + + /* + jQuery.deck('getSlide', index) + + index: integer, optional + + Returns a jQuery object containing the slide at index. If index is not + specified, the current slide is returned. + */ + getSlide: function(index) { + var i = typeof index !== 'undefined' ? index : current; + if (typeof i != 'number' || i < 0 || i >= slides.length) return null; + return slides[i]; + }, + + /* + jQuery.deck('getSlides') + + Returns all slides as an array of jQuery objects. + */ + getSlides: function() { + return slides; + }, + + /* + jQuery.deck('getContainer') + + Returns a jQuery object containing the deck container as defined by the + container option. + */ + getContainer: function() { + return $(options.selectors.container); + }, + + /* + jQuery.deck('getOptions') + + Returns the options object for the deck, including any overrides that + were defined at initialization. + */ + getOptions: function() { + return options; + }, + + /* + jQuery.deck('extend', name, method) + + name: string + method: function + + Adds method to the deck namespace with the key of name. This doesn’t + give access to any private member data — public methods must still be + used within method — but lets extension authors piggyback on the deck + namespace rather than pollute jQuery. + + $.deck('extend', 'alert', function(msg) { + alert(msg); + }); + + // Alerts 'boom' + $.deck('alert', 'boom'); + */ + extend: function(name, method) { + methods[name] = method; + } + }; + + /* jQuery extension */ + $[deck] = function(method, arg) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } + else { + return methods.init(method, arg); + } + }; + + /* + The default settings object for a deck. All deck extensions should extend + this object to add defaults for any of their options. + + options.classes.after + This class is added to all slides that appear after the 'next' slide. + + options.classes.before + This class is added to all slides that appear before the 'previous' + slide. + + options.classes.childCurrent + This class is added to all elements in the DOM tree between the + 'current' slide and the deck container. For standard slides, this is + mostly seen and used for nested slides. + + options.classes.current + This class is added to the current slide. + + options.classes.loading + This class is applied to the deck container during loading phases and is + primarily used as a way to short circuit transitions between states + where such transitions are distracting or unwanted. For example, this + class is applied during deck initialization and then removed to prevent + all the slides from appearing stacked and transitioning into place + on load. + + options.classes.next + This class is added to the slide immediately following the 'current' + slide. + + options.classes.onPrefix + This prefix, concatenated with the current slide index, is added to the + deck container as you change slides. + + options.classes.previous + This class is added to the slide immediately preceding the 'current' + slide. + + options.selectors.container + Elements matched by this CSS selector will be considered the deck + container. The deck container is used to scope certain states of the + deck, as with the onPrefix option, or with extensions such as deck.goto + and deck.menu. + + options.keys.next + The numeric keycode used to go to the next slide. + + options.keys.previous + The numeric keycode used to go to the previous slide. + + options.touch.swipeTolerance + The number of pixels the users finger must travel to produce a swipe + gesture. + */ + $[deck].defaults = { + classes: { + after: 'deck-after', + before: 'deck-before', + childCurrent: 'deck-child-current', + current: 'deck-current', + loading: 'deck-loading', + next: 'deck-next', + onPrefix: 'on-slide-', + previous: 'deck-previous' + }, + + selectors: { + container: '.deck-container' + }, + + keys: { + // enter, space, page down, right arrow, down arrow, + next: [13, 32, 34, 39, 40], + // backspace, page up, left arrow, up arrow + previous: [8, 33, 37, 38] + }, + + touch: { + swipeTolerance: 60 + } + }; + + $d.ready(function() { + $('html').addClass('ready'); + }); + + /* + FF + Transforms + Flash video don't get along... + Firefox will reload and start playing certain videos after a + transform. Blanking the src when a previously shown slide goes out + of view prevents this. + */ + $d.bind('deck.change', function(e, from, to) { + var oldFrames = $[deck]('getSlide', from).find('iframe'), + newFrames = $[deck]('getSlide', to).find('iframe'); + + oldFrames.each(function() { + var $this = $(this), + curSrc = $this.attr('src'); + + if(curSrc) { + $this.data('deck-src', curSrc).attr('src', ''); + } + }); + + newFrames.each(function() { + var $this = $(this), + originalSrc = $this.data('deck-src'); + + if (originalSrc) { + $this.attr('src', originalSrc); + } + }); + }); +})(jQuery, 'deck', document); diff --git a/deck/core/jquery-1.6.4.min.js b/deck/core/jquery-1.6.4.min.js new file mode 100644 index 0000000..628ed9b --- /dev/null +++ b/deck/core/jquery-1.6.4.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */ +(function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.4",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i=f.expando,j=typeof c=="string",k=a.nodeType,l=k?f.cache:a,m=k?a[f.expando]:a[f.expando]&&f.expando;if((!m||e&&m&&l[m]&&!l[m][i])&&j&&d===b)return;m||(k?a[f.expando]=m=++f.uuid:m=f.expando),l[m]||(l[m]={},k||(l[m].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?l[m][i]=f.extend(l[m][i],c):l[m]=f.extend(l[m],c);g=l[m],e&&(g[i]||(g[i]={}),g=g[i]),d!==b&&(g[f.camelCase(c)]=d);if(c==="events"&&!g[c])return g[i]&&g[i].events;j?(h=g[c],h==null&&(h=g[f.camelCase(c)])):h=g;return h}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e=f.expando,g=a.nodeType,h=g?f.cache:a,i=g?a[f.expando]:f.expando;if(!h[i])return;if(b){d=c?h[i][e]:h[i];if(d){d[b]||(b=f.camelCase(b)),delete d[b];if(!l(d))return}}if(c){delete h[i][e];if(!l(h[i]))return}var j=h[i][e];f.support.deleteExpando||!h.setInterval?delete h[i]:h[i]=null,j?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=j):g&&(f.support.deleteExpando?delete a[f.expando]:a.removeAttribute?a.removeAttribute(f.expando):a[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=v:u&&(i=u)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.attr(a,b,""),a.removeAttribute(b),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(u&&f.nodeName(a,"button"))return u.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(u&&f.nodeName(a,"button"))return u.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==null?g:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabIndex=f.propHooks.tabIndex,v={get:function(a,c){var d;return f.prop(a,c)===!0||(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(u=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=/\.(.*)$/,x=/^(?:textarea|input|select)$/i,y=/\./g,z=/ /g,A=/[^\w\s.|`]/g,B=function(a){return a.replace(A,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=C;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=C);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),B).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},I=function(c){var d=c.target,e,g;if(!!x.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=H(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:I,beforedeactivate:I,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&I.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&I.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",H(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in G)f.event.add(this,c+".specialChange",G[c]);return x.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return x.test(this.nodeName)}},G=f.event.special.change.filters,G.focus=G.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=S.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(U(c[0])||U(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=R.call(arguments);N.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!T[a]?f.unique(e):e,(this.length>1||P.test(d))&&O.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!be[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)g[h]&&bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=be[l]||be._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bm,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bv(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bw=function(a,c){var d,e,g;c=c.replace(bo,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bx=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bp.test(d)&&bq.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bv=bw||bx,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bz=/%20/g,bA=/\[\]$/,bB=/\r?\n/g,bC=/#.*$/,bD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bE=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bF=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bG=/^(?:GET|HEAD)$/,bH=/^\/\//,bI=/\?/,bJ=/)<[^<]*)*<\/script>/gi,bK=/^(?:select|textarea)/i,bL=/\s+/,bM=/([?&])_=[^&]*/,bN=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bO=f.fn.load,bP={},bQ={},bR,bS,bT=["*/"]+["*"];try{bR=e.href}catch(bU){bR=c.createElement("a"),bR.href="",bR=bR.href}bS=bN.exec(bR.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bO)return bO.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bJ,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bK.test(this.nodeName)||bE.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bB,"\r\n")}}):{name:b.name,value:c.replace(bB,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?bX(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),bX(a,b);return a},ajaxSettings:{url:bR,isLocal:bF.test(bS[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bT},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bV(bP),ajaxTransport:bV(bQ),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?bZ(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=b$(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bD.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bC,"").replace(bH,bS[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bL),d.crossDomain==null&&(r=bN.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bS[1]&&r[2]==bS[2]&&(r[3]||(r[1]==="http:"?80:443))==(bS[3]||(bS[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bW(bP,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bG.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bI.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bM,"$1_="+x);d.url=y+(y===d.url?(bI.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bT+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bW(bQ,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bz,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cq("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=ct.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!ct.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cu(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cu(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNaN(j)?i:j}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/deck/extensions/codemirror/MIT-LICENSE.txt b/deck/extensions/codemirror/MIT-LICENSE.txt new file mode 100644 index 0000000..fd29620 --- /dev/null +++ b/deck/extensions/codemirror/MIT-LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2011 Irene Ros + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/deck/extensions/codemirror/README.md b/deck/extensions/codemirror/README.md new file mode 100644 index 0000000..25ef154 --- /dev/null +++ b/deck/extensions/codemirror/README.md @@ -0,0 +1,90 @@ +Deck.js-CodeMirror Extension +============================ + +This extension allows you to embed codemirror code snippets in your slides. Those codeblocks +can also be executable, which is pretty exciting. + +An example is running here: http://ireneros.com/deck/deck.js-codemirror/introduction + +You can also see those slides in the `introduction` folder. + +# Installation: # + +Move all this into a folder called 'codemirror' in your deck.js/extensions/ folder. + +# Setup: # + +Include the stylesheet: + + + +Include the JS source: + + + + + + + + + + + + + + + + + +Include your favorite CodeMirror syntax style: + + + + Options are: + + cobalt.css + default.css + elegant.css + neat.css + night.css + + +# Use: # + +There are two ways to create code blocks: +Inside your slide: + +## Text Area: + +
+ +
+ +## Any other item: + +
+ +
+ +# Element Attributes: # + +Regardless of your element type, the following attributes should be set: + +* class - code (should always be set to code.) +* mode - language mode. This plugin now supports all modes. Look into the mode directory and include the ones you like. Note that some require additional modes so be sure to check the Codemirror site. +* theme (optional) - If you want multiple themes in your slides, include multiple stylesheets and set this attribute to the theme name. +* runnable (optiona) - If true, will add a Run button to the window and pipe the eval's console output to an output element right below. + +# Contact: # +Irene Ros (@ireneros) +http://bocoup.com + + diff --git a/deck/extensions/codemirror/VERSION.txt b/deck/extensions/codemirror/VERSION.txt new file mode 100644 index 0000000..8acdd82 --- /dev/null +++ b/deck/extensions/codemirror/VERSION.txt @@ -0,0 +1 @@ +0.0.1 diff --git a/deck/extensions/codemirror/codemirror.js b/deck/extensions/codemirror/codemirror.js new file mode 100644 index 0000000..5866606 --- /dev/null +++ b/deck/extensions/codemirror/codemirror.js @@ -0,0 +1,21 @@ +// Copyright (C) 2011 by Marijn Haverbeke + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +var CodeMirror=function(){function a(b,c){function bw(a){return a>=0&&a<$.length}function by(a){ba=null;var b={line:0,ch:0};bI(b,{line:$.length-1,ch:$[$.length-1].text.length},N(a),b,b),ba=new j,bg=!0}function bz(a){var b=[];for(var c=0,d=$.length;c=c.to||b.line-1&&setTimeout(cV(function(){cs(bc.to.line,"smart")}),50)}var c=a.keyCode;c==13?(g.readOnly||cp(),m(a)):!a.ctrlKey&&!a.altKey&&!a.metaKey&&c==9&&g.tabMode!="default"?m(a):bU(bp)}function bG(){if(g.readOnly=="nocursor")return;bb||(g.onFocus&&g.onFocus(bx),bb=!0,w.className.search(/\bCodeMirror-focused\b/)==-1&&(w.className+=" CodeMirror-focused"),bk||bW()),bT(),cK()}function bH(){bb&&(g.onBlur&&g.onBlur(bx),bb=!1,w.className=w.className.replace(" CodeMirror-focused","")),clearInterval(Y),setTimeout(function(){bb||(bd=null)},150)}function bI(a,b,c,d,e){if(ba){var f=[];for(var h=a.line,i=b.line+1;hg.undoDepth)ba.done.shift()}bM(a,b,c,d,e)}function bJ(a,b){var c=a.pop();if(c){var d=[],e=c.start+c.added;for(var f=c.start;fg&&(bs=o,g=o.length,bt=null,f=!1)}if(f){g=0,bs="",bt=null;for(var i=0,n=$.length;ig&&(g=o.length,bs=o)}}var p=[],q=c.length-j-1;for(var i=0,o=_.length;ib.line&&p.push(r+q)}c.length<5?(cP(a.line,a.line+c.length),p.push(a.line+c.length)):p.push(a.line),_=p,cR(100),bh.push({from:a.line,to:b.line+1,diff:q}),bi={from:a,to:b,text:c},cg(d,e,s(bc.from.line),s(bc.to.line)),J.style.height=$.length*cF()+2*cG()+"px"}function bN(a,b,c){function d(d){if(H(d,b))return d;if(!H(c,d))return e;var f=d.line+a.length-(c.line-b.line)-1,g=d.ch;return d.line==c.line&&(g+=a[a.length-1].length-(c.ch-(c.line==b.line?b.ch:0))),{line:f,ch:g}}b=cj(b),c?c=cj(c):c=b,a=N(a);var e;return bP(a,b,c,function(a){return e=a,{from:d(bc.from),to:d(bc.to)}}),e}function bO(a,b){bP(N(a),bc.from,bc.to,function(a){return b=="end"?{from:a,to:a}:b=="start"?{from:bc.from,to:bc.from}:{from:bc.from,to:a}})}function bP(a,b,c,d){var e=a.length==1?a[0].length+b.ch:a[a.length-1].length,f=d({line:b.line+a.length-1,ch:e});bI(b,c,a,f.from,f.to)}function bQ(a,b){var c=a.line,d=b.line;if(c==d)return $[c].text.slice(a.ch,b.ch);var e=[$[c].text.slice(a.ch)];for(var f=c+1;f=a)return{line:c,ch:a-d};++c,d=e+1}}if(bk||!bb)return;var a=!1,b=C.value,c=O(C);if(!c)return!1;var a=bq.text!=b,d=be,e=a||c.start!=bq.start||c.end!=(d?bq.start:bq.end);if(!e&&!d)return!1;if(a){bd=be=null;if(g.readOnly)return bg=!0,"changed"}var h=f(c.start,bq.from),i=f(c.end,bq.from);if(d){var j=c.start==d.anchor?i:h,k=bd?bc.to:c.start==d.anchor?h:i;(bc.inverted=H(j,k))?(h=j,i=k):(be=null,h=k,i=j)}h.line==i.line&&h.line==bc.from.line&&h.line==bc.to.line&&!bd&&(bg=!1);if(a){var l=0,m=b.length,n=Math.min(m,bq.text.length),o,p=bq.from,q=-1;while(l-1?l-q:l,s=bq.to-1,t=bq.text.length;for(;;){o=bq.text.charAt(t);if(b.charAt(m)!=o){++m,++t;break}o=="\n"&&s--;if(t<=l||m<=l)break;--m,--t}var q=bq.text.lastIndexOf("\n",t-1),u=q==-1?t:t-q-1;bI({line:p,ch:r},{line:s,ch:u},N(b.slice(l,m)),h,i);if(p!=s||h.line!=p)bg=!0}else cg(h,i);return bq.text=b,bq.start=c.start,bq.end=c.end,a?"changed":e?"moved":!1}function bW(){var a=[],b=Math.max(0,bc.from.line-1),c=Math.min($.length,bc.to.line+2);for(var d=b;db)&&U.scrollIntoView()}function bZ(){var a=cD(bc.inverted?bc.from:bc.to);return b$(a.x,a.y,a.x,a.yBot)}function b$(a,b,c,d){var e=cH(),f=cG(),h=cF();b+=f,d+=f,a+=e,c+=e;var i=D.clientHeight,j=D.scrollTop,k=!1,l=!0;bj+i&&(D.scrollTop=d+h-i,k=!0);var m=D.clientWidth,n=D.scrollLeft,o=g.fixedGutter?R.clientWidth:0;return am+n&&(D.scrollLeft=c+10-m,k=!0,c>J.clientWidth&&(l=!1)),k&&g.onScroll&&g.onScroll(bx),l}function b_(){var a=cF(),b=D.scrollTop-cG();return{from:Math.min($.length,Math.max(0,Math.floor(b/a))),to:Math.min($.length,Math.ceil((b+D.clientHeight)/a))}}function ca(a){if(!D.clientWidth){bm=bn=0;return}var b=a===!0?[]:[{from:bm,to:bn,domStart:0}];for(var c=0,d=a.length||0;cj.from&&f.push({from:j.from,to:e.from,domStart:j.domStart}),e.to=m)break;if(j.domStart>o||j.from>q)n.push({from:q,to:j.from,domSize:j.domStart-o,domStart:o}),r+=j.from-q;q=j.to,o=j.domStart+(j.to-j.from)}if(o!=p||q!=m)r+=Math.abs(m-q),n.push({from:q,to:m,domSize:p-o,domStart:o}),m-q!=p-o&&(bl=!0);if(!n.length)return;V.style.display="none",r>(k.to-k.from)*.3?cb(l=Math.max(k.from-10,0),m=Math.min(k.to+7,$.length)):cc(n),V.style.display="";var s=l!=bm||m!=bn||bo!=D.clientHeight;bm=l,bn=m,Q.style.top=l*cF()+"px",s&&(bo=D.clientHeight,J.style.height=$.length*cF()+2*cG()+"px"),(s||bl)&&cd(),bt==null&&(bt=cA(bs)),bt>D.clientWidth?(T.style.width=bt+"px",J.style.width="",J.style.width=D.scrollWidth+"px"):T.style.width=J.style.width="";if(V.childNodes.length!=bn-bm)throw new Error("BAD PATCH! "+JSON.stringify(n)+" size="+(bn-bm)+" nodes="+V.childNodes.length);ce()}function cb(a,b){var c=[],d={line:a,ch:0},e=H(bc.from,d)&&!H(bc.to,d);for(var f=a;f0;--k)V.removeChild(j?j.previousSibling:V.lastChild);else if(i){for(var k=Math.max(0,i);k>0;--k)V.insertBefore(n.createElement("pre"),j);for(var k=Math.max(0,-i);k>0;--k)V.removeChild(j?j.previousSibling:V.lastChild)}var l=V.childNodes[h.domStart+d],m=b=h.from;for(var k=h.from;k':"
",f,"
")}R.style.display="none",S.innerHTML=c.join("");var h=String($.length).length,i=S.firstChild,j=F(i),k="";while(j.length+k.length=$.length)return{line:$.length-1,ch:$[$.length-1].text.length};var b=a.ch,c=$[a.line].text.length;return b==null||b>c?{line:a.line,ch:c}:b<0?{line:a.line,ch:0}:a}function ck(a){var b=Math.floor(D.clientHeight/cF()),c=bc.inverted?bc.from:bc.to;ch(c.line+Math.max(b-1,1)*(a?1:-1),c.ch,!0)}function cl(a){var b=a?{line:0,ch:0}:{line:$.length-1,ch:$[$.length-1].text.length};cf(b,b)}function cm(){var a=$.length-1;cg({line:0,ch:0},{line:a,ch:$[a].text.length})}function cn(a){var b=$[a.line].text,c=a.ch,d=a.ch;while(c>0&&/\w/.test(b.charAt(c-1)))--c;while(d-1&&(a==null&&(a=f),b=f)}a!=null&&bh.push({from:a,to:b+1})}}function cw(a,b,c){return typeof a=="number"&&(a=$[ci(a)]),a.gutterMarker={text:b,style:c},bl=!0,a}function cx(a){typeof a=="number"&&(a=$[ci(a)]),a.gutterMarker=null,bl=!0}function cy(a,b){if(typeof a=="number"){var c=a;a=$[ci(a)]}else{var c=M($,a);if(c==-1)return null}return a.className!=b&&(a.className=b,bh.push({from:c,to:c+1})),a}function cz(a){if(typeof a=="number"){var b=a;a=$[a];if(!a)return null}else{var b=M($,a);if(b==-1)return null}var c=a.gutterMarker;return{line:b,text:a.text,markerText:c&&c.text,markerClass:c&&c.style}}function cA(a){return K.innerHTML="
x
",K.firstChild.firstChild.firstChild.nodeValue=a,K.firstChild.firstChild.offsetWidth||10}function cB(a,b){return b==0?0:(K.innerHTML="
"+$[a].getHTML(null,null,!1,b)+"
",K.firstChild.firstChild.offsetWidth)}function cC(a,b){function e(a){return K.innerHTML="
"+c.getHTML(null,null,!1,a)+"
",K.firstChild.firstChild.offsetWidth}if(b<=0)return 0;var c=$[a],d=c.text,f=0,g=0,h=d.length,i,j=Math.min(h,Math.ceil(b/cA("x")));for(;;){var k=e(j);if(k<=b&&ji)return h;j=Math.floor(h*.8),k=e(j),kb-g?f:h;var l=Math.ceil((f+h)/2),m=e(l);m>b?(h=l,i=m):(f=l,g=m)}}function cD(a,b){var c=cF(),d=a.line-(b?bm:0);return{x:cB(a.line,a.ch),y:d*c,yBot:(d+1)*c}}function cE(a){var b=cD(a,!0),c=E(T);return{x:c.left+b.x,y:c.top+b.y,yBot:c.top+b.yBot}}function cF(){var a=V.childNodes.length;return a?V.offsetHeight/a||1:(K.innerHTML="
x
",K.firstChild.offsetHeight||1)}function cG(){return T.offsetTop}function cH(){return T.offsetLeft}function cI(a,b){var c=E(D,!0),d,e;try{d=a.clientX,e=a.clientY}catch(a){return null}if(!b&&(d-c.left>D.clientWidth||e-c.top>D.clientHeight))return null;var f=E(T,!0),g=bm+Math.floor((e-f.top)/cF());return cj({line:g,ch:cC(ci(g),d-f.left)})}function cJ(a){function e(){var a=N(C.value).join("\n");a!=d&&cV(bO)(a,"end"),B.style.position="relative",C.style.cssText=c,bk=!1,bW(),bT()}var b=cI(a);if(!b||window.opera)return;(G(bc.from,bc.to)||H(b,bc.from)||!H(b,bc.to))&&cV(ch)(b.line,b.ch);var c=C.style.cssText;B.style.position="absolute",C.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(a.clientY-5)+"px; left: "+(a.clientX-5)+"px; z-index: 1000; background: white; "+"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",bk=!0;var d=C.value=bR();bX(),P(C,0,C.value.length);if(u){o(a);var f=r(window,"mouseup",function(){f(),setTimeout(e,20)},!0)}else setTimeout(e,50)}function cK(){clearInterval(Y);var a=!0;U.style.visibility="",Y=setInterval(function(){U.style.visibility=(a=!a)?"":"hidden"},650)}function cM(a){function p(a,b,c){if(!a.text)return;var d=a.styles,e=g?0:a.text.length-1,f;for(var i=g?0:d.length-2,j=g?d.length:-2;i!=j;i+=2*h){var k=d[i];if(d[i+1]!=null&&d[i+1]!=m){e+=h*k.length;continue}for(var l=g?0:k.length-1,p=g?k.length:-1;l!=p;l+=h,e+=h)if(e>=b&&e"==g)n.push(f);else{if(n.pop()!=q.charAt(0))return{pos:e,match:!1};if(!n.length)return{pos:e,match:!0}}}}}var b=bc.inverted?bc.from:bc.to,c=$[b.line],d=b.ch-1,e=d>=0&&cL[c.text.charAt(d)]||cL[c.text.charAt(++d)];if(!e)return;var f=e.charAt(0),g=e.charAt(1)==">",h=g?1:-1,i=c.styles;for(var j=d+1,k=0,l=i.length;ke;--d){if(d==0)return 0;var f=$[d-1];if(f.stateAfter)return d;var g=f.indentation();if(c==null||b>g)c=d-1,b=g}return c}function cO(a){var b=cN(a),c=b&&$[b-1].stateAfter;c?c=e(Z,c):c=f(Z);for(var d=b;d=$.length)continue;var d=cN(c),h=d&&$[d-1].stateAfter;h?h=e(Z,h):h=f(Z);var i=0,j=Z.compareStates,k=!1;for(var l=d,m=$.length;la){_.push(l),cR(g.workDelay),k&&bh.push({from:c,to:l+1});return}var p=n.highlight(Z,h);p&&(k=!0),n.stateAfter=e(Z,h);if(j){if(o&&j(o,h))break}else if(p!==!1||!o)i=0;else if(++i>3)break}k&&bh.push({from:c,to:l+1})}b&&g.onHighlightComplete&&g.onHighlightComplete(bx)}function cR(a){if(!_.length)return;X.set(a,cV(cQ))}function cS(){bg=null,bh=[],bi=bj=!1}function cT(){var a=!1;bj&&(a=!bZ()),bh.length?ca(bh):(bj&&ce(),bl&&cd()),a&&bZ(),bj&&(bY(),cK()),bb&&!bk&&(bg===!0||bg!==!1&&bj)&&bW(),bj&&g.matchBrackets&&setTimeout(cV(function(){br&&(br(),br=null),cM(!1)}),20);var b=bi;bj&&g.onCursorActivity&&g.onCursorActivity(bx),b&&g.onChange&&bx&&g.onChange(bx,b)}function cV(a){return function(){cU++||cS();try{var b=a.apply(this,arguments)}finally{--cU||cT()}return b}}function cW(a,b,c){this.atOccurrence=!1,c==null&&(c=typeof a=="string"&&a==a.toLowerCase()),b&&typeof b=="object"?b=cj(b):b={line:0,ch:0},this.pos={from:b,to:b};if(typeof a!="string")this.matches=function(b,c){if(b){var d=$[c.line].text.slice(0,c.ch),e=d.match(a),f=0;while(e){var g=d.indexOf(e[0]);f+=g,d=d.slice(g+1);var h=d.match(a);if(h)e=h;else break;f++}}else var d=$[c.line].text.slice(c.ch),e=d.match(a),f=e&&c.ch+d.indexOf(e[0]);if(e)return{from:{line:c.line,ch:f},to:{line:c.line,ch:f+e[0].length},match:e}};else{c&&(a=a.toLowerCase());var d=c?function(a){return a.toLowerCase()}:function(a){return a},e=a.split("\n");e.length==1?this.matches=function(b,c){var e=d($[c.line].text),f=a.length,g;if(b?c.ch>=f&&(g=e.lastIndexOf(a,c.ch-f))!=-1:(g=e.indexOf(a,c.ch))!=-1)return{from:{line:c.line,ch:g},to:{line:c.line,ch:g+f}}}:this.matches=function(a,b){var c=b.line,f=a?e.length-1:0,g=e[f],h=d($[c].text),i=a?h.indexOf(g)+g.length:h.lastIndexOf(g);if(a?i>=b.ch||i!=g.length:i<=b.ch||i!=h.length-g.length)return;for(;;){if(a?!c:c==$.length-1)return;h=d($[c+=a?-1:1].text),g=e[a?--f:++f];if(f>0&&f
'+'
'+'
'+'
'+'
'+'
'+'
 
'+"
"+"
",b.appendChild?b.appendChild(w):b(w);var B=w.firstChild,C=B.firstChild,D=w.lastChild,J=D.firstChild,K=J.firstChild,Q=K.nextSibling,R=Q.firstChild,S=R.firstChild,T=R.nextSibling.firstChild,U=T.firstChild,V=U.nextSibling;g.tabindex!=null&&(C.tabindex=g.tabindex),!g.gutter&&!g.lineNumbers&&(R.style.display="none");var W=new s,X=new s,Y,Z,$=[new h("")],_,ba=new j,bb;ct();var bc={from:{line:0,ch:0},to:{line:0,ch:0},inverted:!1},bd,be,bf,bg,bh,bi,bj,bk,bl,bm=0,bn=0,bo=0,bp=null,bq,br,bs="",bt;cV(function(){by(g.value||""),bg=!1})(),r(D,"mousedown",cV(bA)),u||r(D,"contextmenu",cJ),r(J,"dblclick",cV(bB)),r(D,"scroll",function(){ca([]),g.fixedGutter&&(R.style.left=D.scrollLeft+"px"),g.onScroll&&g.onScroll(bx)}),r(window,"resize",function(){ca(!0)}),r(C,"keyup",cV(bE)),r(C,"keydown",cV(bD)),r(C,"keypress",cV(bF)),r(C,"focus",bG),r(C,"blur",bH),r(D,"dragenter",o),r(D,"dragover",o),r(D,"drop",cV(bC)),r(D,"paste",function(){bX(),bU()}),r(C,"paste",function(){bU()}),r(C,"cut",function(){bU()});var bu;try{bu=n.activeElement==C}catch(bv){}bu?setTimeout(bG,20):bH();var bx=w.CodeMirror={getValue:bz,setValue:cV(by),getSelection:bR,replaceSelection:cV(bO),focus:function(){bX(),bG(),bU()},setOption:function(a,b){g[a]=b,a=="lineNumbers"||a=="gutter"||a=="firstLineNumber"?cV(cu)():a=="mode"||a=="indentUnit"?ct():a=="readOnly"&&b=="nocursor"?C.blur():a=="theme"&&(D.className=D.className.replace(/cm-s-\w+/,"cm-s-"+b))},getOption:function(a){return g[a]},undo:cV(bK),redo:cV(bL),indentLine:cV(function(a,b){bw(a)&&cs(a,b==null?"smart":b?"add":"subtract")}),historySize:function(){return{undo:ba.done.length,redo:ba.undone.length}},matchBrackets:cV(function(){cM(!0)}),getTokenAt:function(a){return a=cj(a),$[a.line].getTokenAt(Z,cO(a.line),a.ch)},getStateAfter:function(a){return a=ci(a==null?$.length-1:a),cO(a+1)},cursorCoords:function(a){return a==null&&(a=bc.inverted),cE(a?bc.from:bc.to)},charCoords:function(a){return cE(cj(a))},coordsChar:function(a){var b=E(T),c=ci(Math.min($.length-1,bm+Math.floor((a.y-b.top)/cF())));return cj({line:c,ch:cC(ci(c),a.x-b.left)})},getSearchCursor:function(a,b,c){return new cW(a,b,c)},markText:cV(function(a,b,c){return cV(cv(a,b,c))}),setMarker:cV(cw),clearMarker:cV(cx),setLineClass:cV(cy),lineInfo:cz,addWidget:function(a,b,c,d,e){a=cD(cj(a));var f=a.yBot,g=a.x;b.style.position="absolute",J.appendChild(b);if(d=="over")f=a.y;else if(d=="near"){var h=Math.max(D.offsetHeight,$.length*cF()),i=Math.max(J.clientWidth,T.clientWidth)-cH();a.yBot+b.offsetHeight>h&&a.y>b.offsetHeight&&(f=a.y-b.offsetHeight),g+b.offsetWidth>i&&(g=i-b.offsetWidth)}b.style.top=f+cG()+"px",b.style.left=b.style.right="",e=="right"?(g=J.clientWidth-b.offsetWidth,b.style.right="0px"):(e=="left"?g=0:e=="middle"&&(g=(J.clientWidth-b.offsetWidth)/2),b.style.left=g+cH()+"px"),c&&b$(g,f,g+b.offsetWidth,f+b.offsetHeight)},lineCount:function(){return $.length},getCursor:function(a){return a==null&&(a=bc.inverted),I(a?bc.from:bc.to)},somethingSelected:function(){return!G(bc.from,bc.to)},setCursor:cV(function(a,b){b==null&&typeof a.line=="number"?ch(a.line,a.ch):ch(a,b)}),setSelection:cV(function(a,b){cg(cj(a),cj(b||a))}),getLine:function(a){if(bw(a))return $[a].text},setLine:cV(function(a,b){bw(a)&&bN(b,{line:a,ch:0},{line:a,ch:$[a].text.length})}),removeLine:cV(function(a){bw(a)&&bN("",{line:a,ch:0},cj({line:a+1,ch:0}))}),replaceRange:cV(bN),getRange:function(a,b){return bQ(cj(a),cj(b))},operation:function(a){return cV(a)()},refresh:function(){ca(!0)},getInputField:function(){return C},getWrapperElement:function(){return w},getScrollerElement:function(){return D},getGutterElement:function(){return R}},bS=!1,cL={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},cU=0;cW.prototype={findNext:function(){return this.find(!1)},findPrevious:function(){return this.find(!0)},find:function(a){function d(a){var c={line:a,ch:0};return b.pos={from:c,to:c},b.atOccurrence=!1,!1}var b=this,c=cj(a?this.pos.from:this.pos.to);for(;;){if(this.pos=this.matches(a,c))return this.atOccurrence=!0,this.pos.match||!0;if(a){if(!c.line)return d(0);c={line:c.line-1,ch:$[c.line-1].text.length}}else{if(c.line==$.length-1)return d($.length);c={line:c.line+1,ch:0}}}},from:function(){if(this.atOccurrence)return I(this.pos.from)},to:function(){if(this.atOccurrence)return I(this.pos.to)},replace:function(a){var b=this;this.atOccurrence&&cV(function(){b.pos.to=bN(a,b.pos.from,b.pos.to)})()}};for(var cX in d)d.propertyIsEnumerable(cX)&&!bx.propertyIsEnumerable(cX)&&(bx[cX]=d[cX]);return bx}function e(a,b){if(b===!0)return b;if(a.copyState)return a.copyState(b);var c={};for(var d in b){var e=b[d];e instanceof Array&&(e=e.concat([])),c[d]=e}return c}function f(a,b,c){return a.startState?a.startState(b,c):!0}function g(a){this.pos=this.start=0,this.string=a}function h(a,b){this.styles=b||[a,null],this.stateAfter=null,this.text=a,this.marked=this.gutterMarker=this.className=null}function i(a,b,c,d){for(var e=0,f=0,g=0;fa&&d.push(h.slice(a-f,Math.min(h.length,b-f)),c[e+1]),i>=a&&(g=1)):g==1&&(i>b?d.push(h.slice(0,b-f),c[e+1]):d.push(h,c[e+1])),f=i}}function j(){this.time=0,this.done=[],this.undone=[]}function k(){o(this)}function l(a){return a.stop||(a.stop=k),a}function m(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function n(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}function o(a){m(a),n(a)}function p(a){return a.target||a.srcElement}function q(a){if(a.which)return a.which;if(a.button&1)return 1;if(a.button&2)return 3;if(a.button&4)return 2}function r(a,b,c,d){function e(a){c(a||window.event)}if(typeof a.addEventListener=="function"){a.addEventListener(b,e,!1);if(d)return function(){a.removeEventListener(b,e,!1)}}else{a.attachEvent("on"+b,e);if(d)return function(){a.detachEvent("on"+b,e)}}}function s(){this.id=null}function C(a,b){b==null&&(b=a.search(/[^\s\u00a0]/),b==-1&&(b=a.length));for(var c=0,d=0;c=0&&d>=0;--c,--d)if(a.charAt(c)!=b.charAt(d))break;return d+1}function M(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0,d=a.length;c=this.string.length},sol:function(){return this.pos==0},peek:function(){return this.string.charAt(this.pos)},next:function(){if(this.posb},eatSpace:function(){var a=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos)))++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){var b=this.string.indexOf(a,this.pos);if(b>-1)return this.pos=b,!0},backUp:function(a){this.pos-=a},column:function(){return C(this.string,this.start)},indentation:function(){return C(this.string)},match:function(a,b,c){if(typeof a!="string"){var e=this.string.slice(this.pos).match(a);return e&&b!==!1&&(this.pos+=e[0].length),e}function d(a){return c?a.toLowerCase():a}if(d(this.string).indexOf(d(a),this.pos)==this.pos)return b!==!1&&(this.pos+=a.length),!0},current:function(){return this.string.slice(this.start,this.pos)}},a.StringStream=g,h.prototype={replace:function(a,b,c){var d=[],e=this.marked;i(0,a,this.styles,d),c&&d.push(c,null),i(b,this.text.length,this.styles,d),this.styles=d,this.text=this.text.slice(0,a)+c+this.text.slice(b),this.stateAfter=null;if(e){var f=c.length-(b-a),g=this.text.length;function h(a){return a<=Math.min(b,b+f)?a:a+f}for(var j=0;j=g?l=!0:(k.from=h(k.from),k.to!=null&&(k.to=h(k.to)));if(l||k.from>=k.to)e.splice(j,1),j--}}},split:function(a,b){var c=[b,null];return i(a,this.text.length,this.styles,c),new h(b+this.text.slice(a),c)},addMark:function(a,b,c){var d=this.marked,e={from:a,to:b,style:c};return this.marked==null&&(this.marked=[]),this.marked.push(e),this.marked.sort(function(a,b){return a.from-b.from}),e},removeMark:function(a){var b=this.marked;if(!b)return;for(var c=0;c5e3){d[e++]=this.text.slice(c.pos),d[e++]=null;break}}return d.length!=e&&(d.length=e,f=!0),e&&d[e-2]!=i&&(f=!0),f||(d.length<5&&this.text.length<10?null:!1)},getTokenAt:function(a,b,c){var d=this.text,e=new g(d);while(e.pos',K(a),""):e.push(K(a))}var e=[];c&&e.push(this.className?'
':"
");var g=this.styles,h=this.text,i=this.marked;a==b&&(a=null);var j=h.length;d!=null&&(j=Math.min(d,j));if(!h&&d==null)f(" ",a!=null&&b==null?"CodeMirror-selected":null);else if(!i&&a==null)for(var k=0,l=0;lj&&(m=m.slice(0,j-l)),l+=n,f(m,"cm-"+g[k+1])}else{var o=0,k=0,p="",q,r=0,s=-1,t=null;function u(){i&&(s+=1,t=so)v=a;else if(b==null||b>o)w=" CodeMirror-selected",b!=null&&(v=Math.min(v,b));while(t&&t.to!=null&&t.to<=o)u();t&&(t.from>o?v=Math.min(v,t.from):(w+=" "+t.style,t.to!=null&&(v=Math.min(v,t.to))));for(;;){var x=o+p.length,y=q;w&&(y=q?q+w:w),f(x>v?p.slice(0,v-o):p,y);if(x>=v){p=p.slice(v-o),o=v;break}o=x,p=g[k++],q="cm-"+g[k++]}}a!=null&&b==null&&f(" ","CodeMirror-selected")}return c&&e.push("
"),e.join("")}},j.prototype={addChange:function(a,b,c){this.undone.length=0;var d=+(new Date),e=this.done[this.done.length-1];if(d-this.time>400||!e||e.start>a+b||e.start+e.added=0;--g)e.old.unshift(c[g]);e.added+=e.start-a,e.start=a}else e.start-1&&(x="\r\n")})();var y=8,z=/Mac/.test(navigator.platform),A={};for(var B=35;B<=40;++B)A[B]=A["c"+B]=!0;var J=document.createElement("div");a.htmlEscape=K;var N,O,P;return"\n\nb".split(/\n/).length!=3?N=function(a){var b=0,c,d=[];while((c=a.indexOf("\n",b))>-1)d.push(a.slice(b,a.charAt(c-1)=="\r"?c-1:c)),b=c+1;return d.push(a.slice(b)),d}:N=function(a){return a.split(/\r?\n/)},a.splitLines=N,window.getSelection?(O=function(a){try{return{start:a.selectionStart,end:a.selectionEnd}}catch(b){return null}},w?P=function(a,b,c){b==c?a.setSelectionRange(b,c):(a.setSelectionRange(b,c-1),window.getSelection().modify("extend","forward","character"))}:P=function(a,b,c){try{a.setSelectionRange(b,c)}catch(d){}}):(O=function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){return null}if(!b||b.parentElement()!=a)return null;var d=a.value,e=d.length,f=a.createTextRange();f.moveToBookmark(b.getBookmark());var g=a.createTextRange();g.collapse(!1);if(f.compareEndPoints("StartToEnd",g)>-1)return{start:e,end:e};var h=-f.moveStart("character",-e);for(var i=d.indexOf("\r");i>-1&&i-1)return{start:h,end:e};var j=-f.moveEnd("character",-e);for(var i=d.indexOf("\r");i>-1&&i-1&&h-1&&h"):b?g.push(''+CodeMirror.htmlEscape(a)+""):g.push(CodeMirror.htmlEscape(a))}}var h=CodeMirror.splitLines(a),i=CodeMirror.startState(d);for(var j=0,k=h.length;j', { + "class" : "button", + text : "Run" + }).prependTo(wrapper), + output = $('
', { + "class" : opts.classes.codemirrorresult + }).appendTo($(wrapper).parent()); + + button.click(function(editor, output){ + return function(event) { + + // save the default logging behavior. + var real_console_log = console.log; + + // Following Dean Edward's fantastic sandbox code: + // http://dean.edwards.name/weblog/2006/11/sandbox/+evaluating+js+in+an+iframe + // create an iframe sandbox for this element. + var iframe = $(" + + +
+ +
+ +
+
+

C++ is faster than JavaScript. + Is it?

+
+
+ +
+

+ If possible, write it in JavaScript.
+ JS ⟷ C++ boundary is slow to cross +

+ +
function() { return Math.floor(133.7 / Math.PI); }
+ + + + + + + + + + + + + + + + + + +
native JS ~83,333,333 calls/s
V8 return ~13,333,333 calls/s
V8 async ~1,745,200 calls/s
thread pool ~83,682 calls/s (0.1%)
+
+ +
+
+

Why C++?

+ +
    +
  • V8 is written in C++
  • +
  • Wrapping existing C/C++ libraries
  • +
  • Use more threads
  • +
+
+
+ +
+

The bare minimum

+
modulename.cpp
+ +
+ +
+

The bare minimum

+
wscript
+ +
+ +
+

https://github.com/
kkaefer/node-cpp-modules

+
+ +
+

Compiling

+
+$  node-waf configure 
+Setting srcdir to               : /.../minimum
+Setting blddir to               : /.../minimum/build
+Checking for program g++ or c++ : /usr/bin/g++
+Checking for program cpp        : /usr/bin/cpp
+Checking for program ar         : /usr/bin/ar
+Checking for program ranlib     : /usr/bin/ranlib
+Checking for g++                : ok
+Checking for node path          : not found
+Checking for node prefix        : ok /usr/local
+'configure' finished successfully (0.057s)
+$  node-waf build 
+Waf: Entering directory `/.../minimum/build'
+[1/2] cxx: modulename.cpp -> build/Release/modulename_1.o
+[2/2] cxx_link: build/Release/modulename_1.o ->
+          build/Release/modulename.node
+Waf: Leaving directory `/.../minimum/build'
+'build' finished successfully (0.539s)
+$  
+
+
+ + +
+

Requiring from JavaScript

+
+$ node
+>  require('./build/Release/modulename.node'); 
+{}
+>  
+
+
+ +
+

+ Develop with
+ $ CXX=clang node-waf configure
+ Also test with GCC +

+
+ +
+

Defining functions

+ +
modulename.cpp
+ + +
    +
  • HandleScope cleans up handles created in this function
  • +
  • Preserve returned value with scope.Close()
  • +
+
+ +
+

Exporting functions

+ +
modulename.cpp
+ + +
    +
  • target is what node.js calls exports
  • +
+ +
+$ node
+>  var mod = require('./build/Release/modulename.node'); 
+{ theAnswer: [Function] }
+>  mod.theAnswer(); 
+42
+>  
+
+
+ +
+

Function arguments

+ +
modulename.cpp
+ + +
    +
  • args contains elements of type Value
  • +
  • Cast to specific type with To* functions
  • +
+
+ +
+ +
+ +
+

Callback functions

+ +
modulename.cpp
+ + +
    +
  • Call automatically retains arguments
  • +
  • Don’t forget HandleScope scope at the top
  • +
+
+ +
+

The thread pool

+

+ + +
    +
  • JavaScript is single-threaded
  • +
  • I/O and CPU in thread pool
  • +
  • No V8 access from worker!
  • +
+
+ +
+

Passing data to the thread pool

+ + + +
    +
  • Not required, just a convention
  • +
  • Persistent is a Handle that stays around until diposed of
  • +
+
+ + + +
+

Calling asynchronously

+ + +
+ +
+

Worker function

+ + + +
    +
  • Function AsyncWork is blocking
  • +
  • Do not use any V8 code, not even variable reads
  • +
  • Convert values to POD or C++ types and store them in the baton
  • +
+ +
+ + +
+

After function

+ + + +
    +
  • callback function is Permanent, need to delete manually
  • +
+ +
+ +
+

Wrap callbacks in TryCatch

+ + + +
    +
  • node::FatalException throws at the top of the event loop
  • +
  • Catchable with process.on('uncaughtException', ...)
  • +
+ +
+ + +
+
+

API design

+
    +
  • Challenge: Synchronous ➞ Asynchronous
  • +
  • Use EventEmitter
  • +
  • Chainable calls
  • +
  • Instantiating objects vs. functions
  • +
  • Make it hard to misuse
  • +
  • Make it feel as “JavaScripty” as possible
  • +
+
+
+ + +
+

node-sqlite3 API

+ + + +
    +
  • No open() function, new implicitly opens
  • +
  • Statements are executed as soon as database is open
  • +
  • No need to “close” the database
  • +
  • No callback? 'error' event on the Database object
  • +
+ +
+

node-blend API

+
    +
  • Blends two images of the same size
  • +
+ + + +
    +
  • No need to create objects with new if you don’t require state
  • +
+
+ + +
+

More documentation

+
kkaefer
+ + +

+
    +
  • Thanks to @mraleph for answering lots of questions
    and @izs, @orlandov, and all other extension authors!
  • +
+
+ + + + + + + + + + + + + + + + + diff --git a/notes.md b/notes.md new file mode 100644 index 0000000..3e81de0 --- /dev/null +++ b/notes.md @@ -0,0 +1,83 @@ +basic module +- registering with node (v0.5!): `NODE_MODULE` +- When running `NODE_MODULE(sqlite3_bindings, RegisterModule);`, "sqlite3_bindings" must be the same as the basename of the resulting .node file +- basic wscript file + +General recommendations +- use clang to develop and gcc to test + +add a function +- putting it into the module's exports +- HandleScope +- Handle vs. Local vs. Persistent +- handles == auto_ptr? + +parsing arguments +- V8's Value object tree +- ThrowException + +callback functions +- call synchronously (called before original function returns!) + +threadpool +- libuv +- creating Batons to store request information +- uv_ref() so that node doesn't stop looping before +- don't call V8 stuff in the threadpool! + + +designing a good API +- asynchronous? + ==> for IO or CPU heavy tasks +- chainable +- EventEmitter as base class +- object vs. function +- when wrapping other libs, include their version + + +creating objects +- inheriting from node::ObjectWrap +- Wrapping/Unwrapping +- adding instance functions +- adding getters/setters +- v8::AdjustAmountOfExternalAllocatedMemory() + +EventEmitter +- inheriting from an eventemitter +- emitting events, responding to events + +speed +- how fast is crossing the JS/C++ boundary? +- don't copy around buffers +- increase thread count (default is 4) +- instanciating C objects (pooling?) + + +general C++ advice +- use std library, tr1 (shared_ptr) + +node-waf/wscript +- looking for 3rd party lib +- linking against a 3rd party lib + +installing with npm +- npm knows to call node-waf automatically + +upgrading from 0.4 +- EventEmitter removed from C++ +- libev/libeio --> libuv +- `rm -rf /usr/local/include/node /usr/local/lib/node /usr/local/bin/node-waf` and reinstall to clean up old cruft + +debugging +- Instruments: memory leaks + +Issues +- multiple copies of the same C++ extension don't play nice + + + +RESEARCH TASKS +- JS/C++ boundary +- retain buffers, buffer deleter +- inheriting from EventEmitter + diff --git a/worker-threads.png b/worker-threads.png new file mode 100644 index 0000000..afdf619 Binary files /dev/null and b/worker-threads.png differ diff --git a/xx_benchmark/binding.gyp b/xx_benchmark/binding.gyp deleted file mode 100644 index 469aa6b..0000000 --- a/xx_benchmark/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "modulename", - "sources": [ "modulename.cpp" ] - } - ] -} diff --git a/xx_benchmark/fn1.js b/xx_benchmark/fn1.js deleted file mode 100644 index c75f463..0000000 --- a/xx_benchmark/fn1.js +++ /dev/null @@ -1,9 +0,0 @@ -var modulename = require('./build/Release/modulename'); - -var start = Date.now(); -for (var i = 0; i < 1000000; i++) { - var val = modulename.fn1(); - if (val !== 42) throw new Error('invalid result!'); -} - -console.warn(Date.now() - start); \ No newline at end of file diff --git a/xx_benchmark/fn2.js b/xx_benchmark/fn2.js deleted file mode 100644 index 0aaa698..0000000 --- a/xx_benchmark/fn2.js +++ /dev/null @@ -1,10 +0,0 @@ -var modulename = require('./build/Release/modulename'); - -var start = Date.now(); -for (var i = 0; i < 1000000; i++) { - modulename.fn2(function(err, val) { - if (val !== 42) throw new Error('invalid result!'); - }); -} - -console.warn(Date.now() - start); \ No newline at end of file diff --git a/xx_benchmark/fn3.js b/xx_benchmark/fn3.js deleted file mode 100644 index d98ba4a..0000000 --- a/xx_benchmark/fn3.js +++ /dev/null @@ -1,10 +0,0 @@ -var modulename = require('./build/Release/modulename'); - -var start = Date.now(); -for (var i = 0; i < 1000000; i++) { - modulename.fn3(function(err, val) { - if (val !== 42) throw new Error('invalid result!'); - }); -} - -console.warn(Date.now() - start); \ No newline at end of file diff --git a/xx_benchmark/modulename.cpp b/xx_benchmark/modulename.cpp deleted file mode 100644 index 253344c..0000000 --- a/xx_benchmark/modulename.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include - -#include - -using namespace v8; - -struct Baton { - uv_work_t request; - Persistent callback; - int32_t result; -}; - - -Handle Fn1(const Arguments& args) { - HandleScope scope; - int answer = 133.7f / M_PI; - return scope.Close(Integer::New(answer)); -} - -Handle Fn2(const Arguments& args) { - HandleScope scope; - int answer = 133.7f / M_PI; - Local argv[] = { - Local::New(Null()), - Local::New(Integer::New(answer)) - }; - Local callback = Local::Cast(args[0]); - callback->Call(Context::GetCurrent()->Global(), 2, argv); - return Undefined(); -} - -void Fn3Work(uv_work_t* req) { - Baton* baton = static_cast(req->data); - baton->result = 133.7f / M_PI; -} - -void Fn3After(uv_work_t* req) { - HandleScope scope; - Baton* baton = static_cast(req->data); - Local argv[] = { - Local::New(Null()), - Local::New(Integer::New(baton->result)) - }; - TryCatch try_catch; - baton->callback->Call(Context::GetCurrent()->Global(), 2, argv); - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } - baton->callback.Dispose(); - delete baton; -} - -Handle Fn3(const Arguments& args) { - HandleScope scope; - Baton* baton = new Baton(); - baton->request.data = baton; - Local callback = Local::Cast(args[0]); - baton->callback = Persistent::New(callback); - uv_queue_work(uv_default_loop(), &baton->request, Fn3Work, - (uv_after_work_cb)Fn3After); - return Undefined(); -} - - -void RegisterModule(Handle target) { - NODE_SET_METHOD(target, "fn1", Fn1); - NODE_SET_METHOD(target, "fn2", Fn2); - NODE_SET_METHOD(target, "fn3", Fn3); -} - -NODE_MODULE(modulename, RegisterModule); diff --git a/xx_benchmark/native.js b/xx_benchmark/native.js deleted file mode 100644 index 9896a41..0000000 --- a/xx_benchmark/native.js +++ /dev/null @@ -1,11 +0,0 @@ -var modulename = { - fn: function() { return Math.floor(133.7 / Math.PI); } -}; - -var start = Date.now(); -for (var i = 0; i < 1000000; i++) { - var val = modulename.fn(); - if (val !== 42) throw new Error('invalid result!'); -} - -console.warn(Date.now() - start); \ No newline at end of file diff --git a/xx_benchmark/package.json b/xx_benchmark/package.json deleted file mode 100644 index f653406..0000000 --- a/xx_benchmark/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "benchmark", - "version": "1.0.0" -} diff --git a/xx_benchmark/results.txt b/xx_benchmark/results.txt deleted file mode 100644 index 7868ce6..0000000 --- a/xx_benchmark/results.txt +++ /dev/null @@ -1,18 +0,0 @@ -native: 90 -fn1: 3823 -fn2: 30406 - - -native: 6 1000000 / (6 / 1000) = 166,666,667 -fn1: 75 1000000 / (75 / 1000) = 13,333,333 -fn2: 573 1000000 / (573 / 1000) = 1,745,200 -fn3: 11950 1000000 / (11950 / 1000) = 83,682 - - - - - -native: 10 -fn1: 76 -fn2: 568 -fn3: \ No newline at end of file