From b60df56157ee1fd0bd4938799bac05a62fda91a1 Mon Sep 17 00:00:00 2001 From: lookshe Date: Sat, 14 Mar 2015 20:45:20 +0100 Subject: initial commit from working version --- .../node_modules/uglify-js/tmp/269.js | 13 + .../node_modules/uglify-js/tmp/app.js | 22315 +++++++++++++++++++ .../node_modules/uglify-js/tmp/embed-tokens.js | 15 + .../node_modules/uglify-js/tmp/goto.js | 26 + .../node_modules/uglify-js/tmp/goto2.js | 8 + .../node_modules/uglify-js/tmp/hoist.js | 33 + .../node_modules/uglify-js/tmp/instrument.js | 97 + .../node_modules/uglify-js/tmp/instrument2.js | 138 + .../node_modules/uglify-js/tmp/liftvars.js | 8 + .../node_modules/uglify-js/tmp/test.js | 30 + .../node_modules/uglify-js/tmp/uglify-hangs.js | 3930 ++++ .../node_modules/uglify-js/tmp/uglify-hangs2.js | 166 + 12 files changed, 26779 insertions(+) create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/269.js create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/app.js create mode 100755 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/embed-tokens.js create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto.js create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto2.js create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/hoist.js create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument.js create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument2.js create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/liftvars.js create mode 100755 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/test.js create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs.js create mode 100644 signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs2.js (limited to 'signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp') diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/269.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/269.js new file mode 100644 index 0000000..256ad1c --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/269.js @@ -0,0 +1,13 @@ +var jsp = require("uglify-js").parser; +var pro = require("uglify-js").uglify; + +var test_code = "var JSON;JSON||(JSON={});"; + +var ast = jsp.parse(test_code, false, false); +var nonembed_token_code = pro.gen_code(ast); +ast = jsp.parse(test_code, false, true); +var embed_token_code = pro.gen_code(ast); + +console.log("original: " + test_code); +console.log("no token: " + nonembed_token_code); +console.log(" token: " + embed_token_code); diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/app.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/app.js new file mode 100644 index 0000000..2c6257e --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/app.js @@ -0,0 +1,22315 @@ +/* Modernizr 2.0.6 (Custom Build) | MIT & BSD + * Build: http://www.modernizr.com/download/#-iepp + */ +;window.Modernizr=function(a,b,c){function w(a,b){return!!~(""+a).indexOf(b)}function v(a,b){return typeof a===b}function u(a,b){return t(prefixes.join(a+";")+(b||""))}function t(a){j.cssText=a}var d="2.0.6",e={},f=b.documentElement,g=b.head||b.getElementsByTagName("head")[0],h="modernizr",i=b.createElement(h),j=i.style,k,l=Object.prototype.toString,m={},n={},o={},p=[],q,r={}.hasOwnProperty,s;!v(r,c)&&!v(r.call,c)?s=function(a,b){return r.call(a,b)}:s=function(a,b){return b in a&&v(a.constructor.prototype[b],c)};for(var x in m)s(m,x)&&(q=x.toLowerCase(),e[q]=m[x](),p.push((e[q]?"":"no-")+q));t(""),i=k=null,a.attachEvent&&function(){var a=b.createElement("div");a.innerHTML="";return a.childNodes.length!==1}()&&function(a,b){function s(a){var b=-1;while(++b to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Check for digits + rdigit = /\d/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = (context ? context.ownerDocument || context : document); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return (context || rootjQuery).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if (selector.selector !== undefined) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.6.3", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + (this.selector ? " " : "") + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.done( fn ); + + return this; + }, + + eq: function( i ) { + return i === -1 ? + this.slice( i ) : + this.slice( i, +i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).unbind( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery._Deferred(); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === "object" && "setInterval" in obj; + }, + + isNaN: function( obj ) { + return obj == null || !rdigit.test( obj ) || isNaN( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw msg; + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return (new Function( "return " + data ))(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // The extra typeof function check is to prevent crashes + // in Safari 2 (See: #3039) + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array ) { + if ( !array ) { + return -1; + } + + if ( indexOf ) { + return indexOf.call( array, elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return (new Date()).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +var // Promise methods + promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ), + // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + // Create a simple deferred (one callbacks list) + _Deferred: function() { + var // callbacks list + callbacks = [], + // stored [ context , args ] + fired, + // to avoid firing when already doing so + firing, + // flag to know if the deferred has been cancelled + cancelled, + // the deferred itself + deferred = { + + // done( f1, f2, ...) + done: function() { + if ( !cancelled ) { + var args = arguments, + i, + length, + elem, + type, + _fired; + if ( fired ) { + _fired = fired; + fired = 0; + } + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + deferred.done.apply( deferred, elem ); + } else if ( type === "function" ) { + callbacks.push( elem ); + } + } + if ( _fired ) { + deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); + } + } + return this; + }, + + // resolve with given context and args + resolveWith: function( context, args ) { + if ( !cancelled && !fired && !firing ) { + // make sure args are available (#8421) + args = args || []; + firing = 1; + try { + while( callbacks[ 0 ] ) { + callbacks.shift().apply( context, args ); + } + } + finally { + fired = [ context, args ]; + firing = 0; + } + } + return this; + }, + + // resolve with this as context and given arguments + resolve: function() { + deferred.resolveWith( this, arguments ); + return this; + }, + + // Has this deferred been resolved? + isResolved: function() { + return !!( firing || fired ); + }, + + // Cancel + cancel: function() { + cancelled = 1; + callbacks = []; + return this; + } + }; + + return deferred; + }, + + // Full fledged deferred (two callbacks list) + Deferred: function( func ) { + var deferred = jQuery._Deferred(), + failDeferred = jQuery._Deferred(), + promise; + // Add errorDeferred methods, then and promise + jQuery.extend( deferred, { + then: function( doneCallbacks, failCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ); + return this; + }, + always: function() { + return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments ); + }, + fail: failDeferred.done, + rejectWith: failDeferred.resolveWith, + reject: failDeferred.resolve, + isRejected: failDeferred.isResolved, + pipe: function( fnDone, fnFail ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + if ( promise ) { + return promise; + } + promise = obj = {}; + } + var i = promiseMethods.length; + while( i-- ) { + obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; + } + return obj; + } + }); + // Make sure only one callback list will be used + deferred.done( failDeferred.cancel ).fail( deferred.cancel ); + // Unexpose cancel + delete deferred.cancel; + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = arguments, + i = 0, + length = args.length, + count = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + // Strange bug in FF4: + // Values changed onto the arguments object sometimes end up as undefined values + // outside the $.when method. Cloning the object into a fresh array solves the issue + deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) ); + } + }; + } + if ( length > 1 ) { + for( ; i < length; i++ ) { + if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return deferred.promise(); + } +}); + + + +jQuery.support = (function() { + + var div = document.createElement( "div" ), + documentElement = document.documentElement, + all, + a, + select, + opt, + input, + marginDiv, + support, + fragment, + body, + testElementParent, + testElement, + testElementStyle, + tds, + events, + eventName, + i, + isSupported; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
a"; + + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName( "tbody" ).length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName( "link" ).length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55$/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains it's value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.firstChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + div.innerHTML = ""; + + // Figure out if the W3C box model works as expected + div.style.width = div.style.paddingLeft = "1px"; + + body = document.getElementsByTagName( "body" )[ 0 ]; + // We use our own, invisible, body unless the body is already present + // in which case we use a div (#9239) + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + jQuery.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + support.boxModel = div.offsetWidth === 2; + + if ( "zoom" in div.style ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } + + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE < 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( document.defaultView && document.defaultView.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Remove the body element we added + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); + + // Technique from Juriy Zaytsev + // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + } ) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Null connected elements to avoid leaks in IE + testElement = fragment = select = opt = body = marginDiv = div = input = null; + + return support; +})(); + +// Keep track of boxModel +jQuery.boxModel = jQuery.support.boxModel; + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([a-z])([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || (pvt && id && (cache[ id ] && !cache[ id ][ internalKey ]))) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ jQuery.expando ] = id = ++jQuery.uuid; + } else { + id = jQuery.expando; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); + } else { + cache[ id ] = jQuery.extend(cache[ id ], name); + } + } + + thisCache = cache[ id ]; + + // Internal jQuery data is stored in a separate object inside the object's data + // cache in order to avoid key collisions between internal data and user-defined + // data + if ( pvt ) { + if ( !thisCache[ internalKey ] ) { + thisCache[ internalKey ] = {}; + } + + thisCache = thisCache[ internalKey ]; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should + // not attempt to inspect the internal events object using jQuery.data, as this + // internal data object is undocumented and subject to change. + if ( name === "events" && !thisCache[name] ) { + return thisCache[ internalKey ] && thisCache[ internalKey ].events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; + + if ( thisCache ) { + + // Support interoperable removal of hyphenated or camelcased keys + if ( !thisCache[ name ] ) { + name = jQuery.camelCase( name ); + } + + delete thisCache[ name ]; + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !isEmptyDataObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( pvt ) { + delete cache[ id ][ internalKey ]; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + var internalCache = cache[ id ][ internalKey ]; + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the entire user cache at once because it's faster than + // iterating through each key, but we need to continue to persist internal + // data if it existed + if ( internalCache ) { + cache[ id ] = {}; + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + + cache[ id ][ internalKey ] = internalCache; + + // Otherwise, we need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + } else if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ jQuery.expando ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( jQuery.expando ); + } else { + elem[ jQuery.expando ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 ) { + var attr = this[0].attributes, name; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( this[0], name, data[ name ] ); + } + } + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + var parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var $this = jQuery( this ), + args = [ parts[0], value ]; + + $this.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + $this.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + !jQuery.isNaN( data ) ? parseFloat( data ) : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON +// property to be considered empty objects; this property always exists in +// order to make sure JSON.stringify does not expose internal metadata +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery.data( elem, deferDataKey, undefined, true ); + if ( defer && + ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) && + ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery.data( elem, queueDataKey, undefined, true ) && + !jQuery.data( elem, markDataKey, undefined, true ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.resolve(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = (type || "fx") + "mark"; + jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 ); + if ( count ) { + jQuery.data( elem, key, count, true ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + if ( elem ) { + type = (type || "fx") + "queue"; + var q = jQuery.data( elem, type, undefined, true ); + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery.data( elem, type, jQuery.makeArray(data), true ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + defer; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift("inprogress"); + } + + fn.call(elem, function() { + jQuery.dequeue(elem, type); + }); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return jQuery.queue( this[0], type ); + } + return this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; + type = type || "fx"; + + return this.queue( type, function() { + var elem = this; + setTimeout(function() { + jQuery.dequeue( elem, type ); + }, time ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) { + count++; + tmp.done( resolve ); + } + } + resolve(); + return defer.promise(); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + nodeHook, boolHook; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.attr ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.prop ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = (value || "").split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " "; + for ( var i = 0, l = this.length; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return undefined; + } + + var isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attrFix: { + // Always normalize to ensure hook usage + tabindex: "tabIndex" + }, + + attr: function( elem, name, value, pass ) { + var nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return undefined; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( !("getAttribute" in elem) ) { + return jQuery.prop( elem, name, value ); + } + + var ret, hooks, + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // Normalize the name if needed + if ( notxml ) { + name = jQuery.attrFix[ name ] || name; + + hooks = jQuery.attrHooks[ name ]; + + if ( !hooks ) { + // Use boolHook for boolean attributes + if ( rboolean.test( name ) ) { + hooks = boolHook; + + // Use nodeHook if available( IE6/7 ) + } else if ( nodeHook ) { + hooks = nodeHook; + } + } + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return undefined; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, name ) { + var propName; + if ( elem.nodeType === 1 ) { + name = jQuery.attrFix[ name ] || name; + + jQuery.attr( elem, name, "" ); + elem.removeAttribute( name ); + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) { + elem[ propName ] = false; + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + 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( elem, name, value ) { + var nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return undefined; + } + + var ret, hooks, + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return (elem[ name ] = value); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabindex propHook to attrHooks for back-compat +jQuery.attrHooks.tabIndex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode; + return jQuery.prop( elem, name ) === true || ( attrNode = elem.getAttributeNode( name ) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !jQuery.support.getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + // Return undefined if nodeValue is empty string + return ret && ret.nodeValue !== "" ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return (ret.nodeValue = value + ""); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return (elem.style.cssText = "" + value); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0); + } + } + }); +}); + + + + +var rnamespaces = /\.(.*)$/, + rformElems = /^(?:textarea|input|select)$/i, + rperiod = /\./g, + rspaces = / /g, + rescape = /[^\w\s.|`]/g, + fcleanup = function( nm ) { + return nm.replace(rescape, "\\$&"); + }; + +/* + * A number of helper functions used for managing events. + * Many of the ideas behind this code originated from + * Dean Edwards' addEvent library. + */ +jQuery.event = { + + // Bind an event to an element + // Original by Dean Edwards + add: function( elem, types, handler, data ) { + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + if ( handler === false ) { + handler = returnFalse; + } else if ( !handler ) { + // Fixes bug #7229. Fix recommended by jdalton + return; + } + + var handleObjIn, handleObj; + + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the function being executed has a unique ID + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure + var elemData = jQuery._data( elem ); + + // If no elemData is found then we must be trying to bind to one of the + // banned noData elements + if ( !elemData ) { + return; + } + + var events = elemData.events, + eventHandle = elemData.handle; + + if ( !events ) { + elemData.events = events = {}; + } + + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.handle.apply( eventHandle.elem, arguments ) : + undefined; + }; + } + + // Add elem as a property of the handle function + // This is to prevent a memory leak with non-native events in IE. + eventHandle.elem = elem; + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = types.split(" "); + + var type, i = 0, namespaces; + + while ( (type = types[ i++ ]) ) { + handleObj = handleObjIn ? + jQuery.extend({}, handleObjIn) : + { handler: handler, data: data }; + + // Namespaced event handlers + if ( type.indexOf(".") > -1 ) { + namespaces = type.split("."); + type = namespaces.shift(); + handleObj.namespace = namespaces.slice(0).sort().join("."); + + } else { + namespaces = []; + handleObj.namespace = ""; + } + + handleObj.type = type; + if ( !handleObj.guid ) { + handleObj.guid = handler.guid; + } + + // Get the current list of functions bound to this event + var handlers = events[ type ], + special = jQuery.event.special[ type ] || {}; + + // Init the event handler queue + if ( !handlers ) { + handlers = events[ type ] = []; + + // Check for a special event handler + // Only use addEventListener/attachEvent if the special + // events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add the function to the element's handler list + handlers.push( handleObj ); + + // Keep track of which events have been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, pos ) { + // don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + if ( handler === false ) { + handler = returnFalse; + } + + var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + events = elemData && elemData.events; + + if ( !elemData || !events ) { + return; + } + + // types is actually an event object here + if ( types && types.type ) { + handler = types.handler; + types = types.type; + } + + // Unbind all events for the element + if ( !types || typeof types === "string" && types.charAt(0) === "." ) { + types = types || ""; + + for ( type in events ) { + jQuery.event.remove( elem, type + types ); + } + + return; + } + + // Handle multiple events separated by a space + // jQuery(...).unbind("mouseover mouseout", fn); + types = types.split(" "); + + while ( (type = types[ i++ ]) ) { + origType = type; + handleObj = null; + all = type.indexOf(".") < 0; + namespaces = []; + + if ( !all ) { + // Namespaced event handlers + namespaces = type.split("."); + type = namespaces.shift(); + + namespace = new RegExp("(^|\\.)" + + jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + eventType = events[ type ]; + + if ( !eventType ) { + continue; + } + + if ( !handler ) { + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( all || namespace.test( handleObj.namespace ) ) { + jQuery.event.remove( elem, origType, handleObj.handler, j ); + eventType.splice( j--, 1 ); + } + } + + continue; + } + + special = jQuery.event.special[ type ] || {}; + + for ( j = pos || 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( handler.guid === handleObj.guid ) { + // remove the given handler for the given type + if ( all || namespace.test( handleObj.namespace ) ) { + if ( pos == null ) { + eventType.splice( j--, 1 ); + } + + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + + if ( pos != null ) { + break; + } + } + } + + // remove generic event handler if no more handlers exist + if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + ret = null; + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + var handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + delete elemData.events; + delete elemData.handle; + + if ( jQuery.isEmptyObject( elemData ) ) { + jQuery.removeData( elem, undefined, true ); + } + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Event object or event type + var type = event.type || event, + namespaces = [], + exclusive; + + if ( type.indexOf("!") >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.exclusive = exclusive; + event.namespace = namespaces.join("."); + event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)"); + + // triggerHandler() and global events don't bubble or run the default action + if ( onlyHandlers || !elem ) { + event.preventDefault(); + event.stopPropagation(); + } + + // Handle a global trigger + if ( !elem ) { + // TODO: Stop taunting the data cache; remove global events and always attach to document + jQuery.each( jQuery.cache, function() { + // internalKey variable is just used to make it easier to find + // and potentially change this stuff later; currently it just + // points to jQuery.expando + var internalKey = jQuery.expando, + internalCache = this[ internalKey ]; + if ( internalCache && internalCache.events && internalCache.events[ type ] ) { + jQuery.event.trigger( event, data, internalCache.handle.elem ); + } + }); + return; + } + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + event.target = elem; + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + var cur = elem, + // IE doesn't like method names with a colon (#3533, #8272) + ontype = type.indexOf(":") < 0 ? "on" + type : ""; + + // Fire event on the current element, then bubble up the DOM tree + do { + var handle = jQuery._data( cur, "handle" ); + + event.currentTarget = cur; + if ( handle ) { + handle.apply( cur, data ); + } + + // Trigger an inline bound script + if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { + event.result = false; + event.preventDefault(); + } + + // Bubble up to document, then to window + cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; + } while ( cur && !event.isPropagationStopped() ); + + // If nobody prevented the default action, do it now + if ( !event.isDefaultPrevented() ) { + var old, + special = jQuery.event.special[ type ] || {}; + + if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction)() check here because IE6/7 fails that test. + // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch. + try { + if ( ontype && elem[ type ] ) { + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + jQuery.event.triggered = type; + elem[ type ](); + } + } catch ( ieError ) {} + + if ( old ) { + elem[ ontype ] = old; + } + + jQuery.event.triggered = undefined; + } + } + + return event.result; + }, + + handle: function( event ) { + event = jQuery.event.fix( event || window.event ); + // Snapshot the handlers list since a called handler may add/remove events. + var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0), + run_all = !event.exclusive && !event.namespace, + args = Array.prototype.slice.call( arguments, 0 ); + + // Use the fix-ed Event rather than the (read-only) native event + args[0] = event; + event.currentTarget = this; + + for ( var j = 0, l = handlers.length; j < l; j++ ) { + var handleObj = handlers[ j ]; + + // Triggered event must 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event. + if ( run_all || event.namespace_re.test( handleObj.namespace ) ) { + // Pass in a reference to the handler function itself + // So that we can later remove it + event.handler = handleObj.handler; + event.data = handleObj.data; + event.handleObj = handleObj; + + var ret = handleObj.handler.apply( this, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + + if ( event.isImmediatePropagationStopped() ) { + break; + } + } + } + return event.result; + }, + + props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // store a copy of the original event object + // and "clone" to set read-only properties + var originalEvent = event; + event = jQuery.Event( originalEvent ); + + for ( var i = this.props.length, prop; i; ) { + prop = this.props[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary + if ( !event.target ) { + // Fixes #1925 where srcElement might not be defined either + event.target = event.srcElement || document; + } + + // check if target is a textnode (safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && event.fromElement ) { + event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; + } + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && event.clientX != null ) { + var eventDocument = event.target.ownerDocument || document, + doc = eventDocument.documentElement, + body = eventDocument.body; + + event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); + event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); + } + + // Add which for key events + if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { + event.which = event.charCode != null ? event.charCode : event.keyCode; + } + + // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) + if ( !event.metaKey && event.ctrlKey ) { + event.metaKey = event.ctrlKey; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && event.button !== undefined ) { + event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); + } + + return event; + }, + + // Deprecated, use jQuery.guid instead + guid: 1E8, + + // Deprecated, use jQuery.proxy instead + proxy: jQuery.proxy, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady, + teardown: jQuery.noop + }, + + live: { + add: function( handleObj ) { + jQuery.event.add( this, + liveConvert( handleObj.origType, handleObj.selector ), + jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); + }, + + remove: function( handleObj ) { + jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); + } + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !this.preventDefault ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // timeStamp is buggy for some events on Firefox(#3843) + // So we won't rely on the native value + this.timeStamp = jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Checks if an event happened on an element within another element +// Used in jQuery.event.special.mouseenter and mouseleave handlers +var withinElement = function( event ) { + + // Check if mouse(over|out) are still within the same parent element + var related = event.relatedTarget, + inside = false, + eventType = event.type; + + event.type = event.data; + + if ( related !== this ) { + + if ( related ) { + inside = jQuery.contains( this, related ); + } + + if ( !inside ) { + + jQuery.event.handle.apply( this, arguments ); + + event.type = eventType; + } + } +}, + +// In case of event delegation, we only need to rename the event.type, +// liveHandler will take care of the rest. +delegate = function( event ) { + event.type = event.data; + jQuery.event.handle.apply( this, arguments ); +}; + +// Create mouseenter and mouseleave events +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + setup: function( data ) { + jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); + }, + teardown: function( data ) { + jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); + } + }; +}); + +// submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function( data, namespaces ) { + if ( !jQuery.nodeName( this, "form" ) ) { + jQuery.event.add(this, "click.specialSubmit", function( e ) { + var elem = e.target, + type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; + + if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { + trigger( "submit", this, arguments ); + } + }); + + jQuery.event.add(this, "keypress.specialSubmit", function( e ) { + var elem = e.target, + type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; + + if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { + trigger( "submit", this, arguments ); + } + }); + + } else { + return false; + } + }, + + teardown: function( namespaces ) { + jQuery.event.remove( this, ".specialSubmit" ); + } + }; + +} + +// change delegation, happens here so we have bind. +if ( !jQuery.support.changeBubbles ) { + + var changeFilters, + + getVal = function( elem ) { + var type = jQuery.nodeName( elem, "input" ) ? elem.type : "", + val = elem.value; + + if ( type === "radio" || type === "checkbox" ) { + val = elem.checked; + + } else if ( type === "select-multiple" ) { + val = elem.selectedIndex > -1 ? + jQuery.map( elem.options, function( elem ) { + return elem.selected; + }).join("-") : + ""; + + } else if ( jQuery.nodeName( elem, "select" ) ) { + val = elem.selectedIndex; + } + + return val; + }, + + testChange = function testChange( e ) { + var elem = e.target, data, val; + + if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { + return; + } + + data = jQuery._data( elem, "_change_data" ); + val = getVal(elem); + + // the current data will be also retrieved by beforeactivate + if ( e.type !== "focusout" || elem.type !== "radio" ) { + jQuery._data( elem, "_change_data", val ); + } + + if ( data === undefined || val === data ) { + return; + } + + if ( data != null || val ) { + e.type = "change"; + e.liveFired = undefined; + jQuery.event.trigger( e, arguments[1], elem ); + } + }; + + jQuery.event.special.change = { + filters: { + focusout: testChange, + + beforedeactivate: testChange, + + click: function( e ) { + var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; + + if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) { + testChange.call( this, e ); + } + }, + + // Change has to be called before submit + // Keydown will be called before keypress, which is used in submit-event delegation + keydown: function( e ) { + var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; + + if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) || + (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || + type === "select-multiple" ) { + testChange.call( this, e ); + } + }, + + // Beforeactivate happens also before the previous element is blurred + // with this event you can't trigger a change event, but you can store + // information + beforeactivate: function( e ) { + var elem = e.target; + jQuery._data( elem, "_change_data", getVal(elem) ); + } + }, + + setup: function( data, namespaces ) { + if ( this.type === "file" ) { + return false; + } + + for ( var type in changeFilters ) { + jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); + } + + return rformElems.test( this.nodeName ); + }, + + teardown: function( namespaces ) { + jQuery.event.remove( this, ".specialChange" ); + + return rformElems.test( this.nodeName ); + } + }; + + changeFilters = jQuery.event.special.change.filters; + + // Handle when the input is .focus()'d + changeFilters.focus = changeFilters.beforeactivate; +} + +function trigger( type, elem, args ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + // Don't pass args or remember liveFired; they apply to the donor event. + var event = jQuery.extend( {}, args[ 0 ] ); + event.type = type; + event.originalEvent = {}; + event.liveFired = undefined; + jQuery.event.handle.call( elem, event ); + if ( event.isDefaultPrevented() ) { + args[ 0 ].preventDefault(); + } +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + + function handler( donor ) { + // Donor event is always a native one; fix it and switch its type. + // Let focusin/out handler cancel the donor focus/blur event. + var e = jQuery.event.fix( donor ); + e.type = fix; + e.originalEvent = {}; + jQuery.event.trigger( e, null, e.target ); + if ( e.isDefaultPrevented() ) { + donor.preventDefault(); + } + } + }); +} + +jQuery.each(["bind", "one"], function( i, name ) { + jQuery.fn[ name ] = function( type, data, fn ) { + var handler; + + // Handle object literals + if ( typeof type === "object" ) { + for ( var key in type ) { + this[ name ](key, data, type[key], fn); + } + return this; + } + + if ( arguments.length === 2 || data === false ) { + fn = data; + data = undefined; + } + + if ( name === "one" ) { + handler = function( event ) { + jQuery( this ).unbind( event, handler ); + return fn.apply( this, arguments ); + }; + handler.guid = fn.guid || jQuery.guid++; + } else { + handler = fn; + } + + if ( type === "unload" && name !== "one" ) { + this.one( type, data, fn ); + + } else { + for ( var i = 0, l = this.length; i < l; i++ ) { + jQuery.event.add( this[i], type, handler, data ); + } + } + + return this; + }; +}); + +jQuery.fn.extend({ + unbind: function( type, fn ) { + // Handle object literals + if ( typeof type === "object" && !type.preventDefault ) { + for ( var key in type ) { + this.unbind(key, type[key]); + } + + } else { + for ( var i = 0, l = this.length; i < l; i++ ) { + jQuery.event.remove( this[i], type, fn ); + } + } + + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.live( types, data, fn, selector ); + }, + + undelegate: function( selector, types, fn ) { + if ( arguments.length === 0 ) { + return this.unbind( "live" ); + + } else { + return this.die( types, null, fn, selector ); + } + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +var liveMap = { + focus: "focusin", + blur: "focusout", + mouseenter: "mouseover", + mouseleave: "mouseout" +}; + +jQuery.each(["live", "die"], function( i, name ) { + jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { + var type, i = 0, match, namespaces, preType, + selector = origSelector || this.selector, + context = origSelector ? this : jQuery( this.context ); + + if ( typeof types === "object" && !types.preventDefault ) { + for ( var key in types ) { + context[ name ]( key, data, types[key], selector ); + } + + return this; + } + + if ( name === "die" && !types && + origSelector && origSelector.charAt(0) === "." ) { + + context.unbind( origSelector ); + + return this; + } + + if ( data === false || jQuery.isFunction( data ) ) { + fn = data || returnFalse; + data = undefined; + } + + types = (types || "").split(" "); + + while ( (type = types[ i++ ]) != null ) { + match = rnamespaces.exec( type ); + namespaces = ""; + + if ( match ) { + namespaces = match[0]; + type = type.replace( rnamespaces, "" ); + } + + if ( type === "hover" ) { + types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); + continue; + } + + preType = type; + + if ( liveMap[ type ] ) { + types.push( liveMap[ type ] + namespaces ); + type = type + namespaces; + + } else { + type = (liveMap[ type ] || type) + namespaces; + } + + if ( name === "live" ) { + // bind live handler + for ( var j = 0, l = context.length; j < l; j++ ) { + jQuery.event.add( context[j], "live." + liveConvert( type, selector ), + { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); + } + + } else { + // unbind live handler + context.unbind( "live." + liveConvert( type, selector ), fn ); + } + } + + return this; + }; +}); + +function liveHandler( event ) { + var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, + elems = [], + selectors = [], + events = jQuery._data( this, "events" ); + + // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) + if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { + return; + } + + if ( event.namespace ) { + namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + event.liveFired = this; + + var live = events.live.slice(0); + + for ( j = 0; j < live.length; j++ ) { + handleObj = live[j]; + + if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { + selectors.push( handleObj.selector ); + + } else { + live.splice( j--, 1 ); + } + } + + match = jQuery( event.target ).closest( selectors, event.currentTarget ); + + for ( i = 0, l = match.length; i < l; i++ ) { + close = match[i]; + + for ( j = 0; j < live.length; j++ ) { + handleObj = live[j]; + + if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { + elem = close.elem; + related = null; + + // Those two events require additional checking + if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { + event.type = handleObj.preType; + related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; + + // Make sure not to accidentally match a child element with the same selector + if ( related && jQuery.contains( elem, related ) ) { + related = elem; + } + } + + if ( !related || related !== elem ) { + elems.push({ elem: elem, handleObj: handleObj, level: close.level }); + } + } + } + } + + for ( i = 0, l = elems.length; i < l; i++ ) { + match = elems[i]; + + if ( maxLevel && match.level > maxLevel ) { + break; + } + + event.currentTarget = match.elem; + event.data = match.handleObj.data; + event.handleObj = match.handleObj; + + ret = match.handleObj.origHandler.apply( match.elem, arguments ); + + if ( ret === false || event.isPropagationStopped() ) { + maxLevel = match.level; + + if ( ret === false ) { + stop = false; + } + if ( event.isImmediatePropagationStopped() ) { + break; + } + } + } + + return stop; +} + +function liveConvert( type, selector ) { + return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&"); +} + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.bind( name, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set; + + if ( !expr ) { + return []; + } + + for ( var i = 0, l = Expr.order.length; i < l; i++ ) { + var match, + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + var left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( var type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + var found, item, + filter = Expr.filter[ type ], + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( var i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + var pass = not ^ !!found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw "Syntax error, unrecognized expression: " + msg; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + var first = match[2], + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + var doneName = match[0], + parent = elem.parentNode; + + if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { + var count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent.sizcache = doneName; + } + + var diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Utility function for retreiving the text value of an array of DOM nodes +Sizzle.getText = function( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += Sizzle.getText( elem.childNodes ); + } + } + + return ret; +}; + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( typeof selector === "string" ? + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array + if ( jQuery.isArray( selectors ) ) { + var match, selector, + matches = {}, + level = 1; + + if ( cur && selectors.length ) { + for ( i = 0, l = selectors.length; i < l; i++ ) { + selector = selectors[i]; + + if ( !matches[ selector ] ) { + matches[ selector ] = POS.test( selector ) ? + jQuery( selector, context || this.context ) : + selector; + } + } + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( selector in matches ) { + match = matches[ selector ]; + + if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) { + ret.push({ selector: selector, elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ), + // The variable 'args' was introduced in + // https://github.com/jquery/jquery/commit/52a0238 + // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. + // http://code.google.com/p/v8/issues/detail?id=1050 + args = slice.call(arguments); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, args.join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return (elem === qualifier) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return (jQuery.inArray( elem, qualifier ) >= 0) === keep; + }); +} + + + + +var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }; + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + */ + +(function() { + this.loggly = function(opts) { + this.user_agent = get_agent(); + this.browser_size = get_size(); + log_methods = {'error': 5, 'warn': 4, 'info': 3, 'debug': 2, 'log': 1}; + if (!opts.url) throw new Error("Please include a Loggly HTTP URL."); + if (!opts.level) { + this.level = log_methods['info']; + } else { + this.level = log_methods[opts.level]; + } + this.log = function(data) { + if (log_methods['log'] == this.level) { + opts.data = data; + janky(opts); + } + }; + this.debug = function(data) { + if (log_methods['debug'] >= this.level) { + opts.data = data; + janky(opts); + } + }; + this.info = function(data) { + if (log_methods['info'] >= this.level) { + opts.data = data; + janky(opts); + } + }; + this.warn = function(data) { + if (log_methods['warn'] >= this.level) { + opts.data = data; + janky(opts); + } + }; + this.error = function(data) { + if (log_methods['error'] >= this.level) { + opts.data = data; + janky(opts); + } + }; + }; + this.janky = function(opts) { + janky._form(function(iframe, form) { + form.setAttribute("action", opts.url); + form.setAttribute("method", "post"); + janky._input(iframe, form, opts.data); + form.submit(); + setTimeout(function(){ + document.body.removeChild(iframe); + }, 2000); + }); + }; + this.janky._form = function(cb) { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + iframe.style.display = "none"; + setTimeout(function() { + var form = iframe.contentWindow.document.createElement("form"); + iframe.contentWindow.document.body.appendChild(form); + cb(iframe, form); + }, 0); + }; + this.janky._input = function(iframe, form, data) { + var inp = iframe.contentWindow.document.createElement("input"); + inp.setAttribute("type", "hidden"); + inp.setAttribute("name", "source"); + inp.value = "castor " + data; + form.appendChild(inp); + }; + this.get_agent = function () { + return navigator.appCodeName + navigator.appName + navigator.appVersion; + }; + this.get_size = function () { + var width = 0; var height = 0; + if( typeof( window.innerWidth ) == 'number' ) { + width = window.innerWidth; height = window.innerHeight; + } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { + width = document.documentElement.clientWidth; height = document.documentElement.clientHeight; + } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { + width = document.body.clientWidth; height = document.body.clientHeight; + } + return {'height': height, 'width': width}; + }; +})(); + + +jsworld={};jsworld.formatIsoDateTime=function(a,b){if(typeof a==="undefined")a=new Date;if(typeof b==="undefined")b=false;var c=jsworld.formatIsoDate(a)+" "+jsworld.formatIsoTime(a);if(b){var d=a.getHours()-a.getUTCHours();var e=Math.abs(d);var f=a.getUTCMinutes();var g=a.getMinutes();if(g!=f&&f<30&&d<0)e--;if(g!=f&&f>30&&d>0)e--;var h;if(g!=f)h=":30";else h=":00";var i;if(e<10)i="0"+e+h;else i=""+e+h;if(d<0)i="-"+i;else i="+"+i;c=c+i}return c};jsworld.formatIsoDate=function(a){if(typeof a==="undefined")a=new Date;var b=a.getFullYear();var c=a.getMonth()+1;var d=a.getDate();return b+"-"+jsworld._zeroPad(c,2)+"-"+jsworld._zeroPad(d,2)};jsworld.formatIsoTime=function(a){if(typeof a==="undefined")a=new Date;var b=a.getHours();var c=a.getMinutes();var d=a.getSeconds();return jsworld._zeroPad(b,2)+":"+jsworld._zeroPad(c,2)+":"+jsworld._zeroPad(d,2)};jsworld.parseIsoDateTime=function(a){if(typeof a!="string")throw"Error: The parameter must be a string";var b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)(\d\d)(\d\d)[T ](\d\d)(\d\d)(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d)(\d\d)(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/);if(b===null)throw"Error: Invalid ISO-8601 date/time string";var c=parseInt(b[1],10);var d=parseInt(b[2],10);var e=parseInt(b[3],10);var f=parseInt(b[4],10);var g=parseInt(b[5],10);var h=parseInt(b[6],10);if(d<1||d>12||e<1||e>31||f<0||f>23||g<0||g>59||h<0||h>59)throw"Error: Invalid ISO-8601 date/time value";var i=new Date(c,d-1,e,f,g,h);if(i.getDate()!=e||i.getMonth()+1!=d)throw"Error: Invalid date";return i};jsworld.parseIsoDate=function(a){if(typeof a!="string")throw"Error: The parameter must be a string";var b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)(\d\d)(\d\d)/);if(b===null)throw"Error: Invalid ISO-8601 date string";var c=parseInt(b[1],10);var d=parseInt(b[2],10);var e=parseInt(b[3],10);if(d<1||d>12||e<1||e>31)throw"Error: Invalid ISO-8601 date value";var f=new Date(c,d-1,e);if(f.getDate()!=e||f.getMonth()+1!=d)throw"Error: Invalid date";return f};jsworld.parseIsoTime=function(a){if(typeof a!="string")throw"Error: The parameter must be a string";var b=a.match(/^(\d\d):(\d\d):(\d\d)/);if(b===null)b=a.match(/^(\d\d)(\d\d)(\d\d)/);if(b===null)throw"Error: Invalid ISO-8601 date/time string";var c=parseInt(b[1],10);var d=parseInt(b[2],10);var e=parseInt(b[3],10);if(c<0||c>23||d<0||d>59||e<0||e>59)throw"Error: Invalid ISO-8601 time value";return new Date(0,0,0,c,d,e)};jsworld._trim=function(a){var b=" \n\r\t\f \u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";for(var c=0;c=0;c--){if(b.indexOf(a.charAt(c))===-1){a=a.substring(0,c+1);break}}return b.indexOf(a.charAt(0))===-1?a:""};jsworld._isNumber=function(a){if(typeof a=="number")return true;if(typeof a!="string")return false;var b=a+"";return/^-?(\d+|\d*\.\d+)$/.test(b)};jsworld._isInteger=function(a){if(typeof a!="number"&&typeof a!="string")return false;var b=a+"";return/^-?\d+$/.test(b)};jsworld._isFloat=function(a){if(typeof a!="number"&&typeof a!="string")return false;var b=a+"";return/^-?\.\d+?$/.test(b)};jsworld._hasOption=function(a,b){if(typeof a!="string"||typeof b!="string")return false;if(b.indexOf(a)!=-1)return true;else return false};jsworld._stringReplaceAll=function(a,b,c){var d;if(b.length==1&&c.length==1){d="";for(var e=0;e0){if(d.length>0)g=parseInt(d.shift(),10);if(isNaN(g))throw"Error: Invalid grouping";if(g==-1){e=a.substring(0,f)+e;break}f-=g;if(f<1){e=a.substring(0,f+g)+e;break}e=c+a.substring(f,f+g)+e}return e};jsworld._formatFractionPart=function(a,b){for(var c=0;a.length0)return a;else throw"Empty or no string"};if(a==null||typeof a!="object")throw"Error: Invalid/missing locale properties";if(typeof a.decimal_point!="string")throw"Error: Invalid/missing decimal_point property";this.decimal_point=a.decimal_point;if(typeof a.thousands_sep!="string")throw"Error: Invalid/missing thousands_sep property";this.thousands_sep=a.thousands_sep;if(typeof a.grouping!="string")throw"Error: Invalid/missing grouping property";this.grouping=a.grouping;if(typeof a.int_curr_symbol!="string")throw"Error: Invalid/missing int_curr_symbol property";if(!/[A-Za-z]{3}.?/.test(a.int_curr_symbol))throw"Error: Invalid int_curr_symbol property";this.int_curr_symbol=a.int_curr_symbol;if(typeof a.currency_symbol!="string")throw"Error: Invalid/missing currency_symbol property";this.currency_symbol=a.currency_symbol;if(typeof a.frac_digits!="number"&&a.frac_digits<0)throw"Error: Invalid/missing frac_digits property";this.frac_digits=a.frac_digits;if(a.mon_decimal_point===null||a.mon_decimal_point==""){if(this.frac_digits>0)throw"Error: Undefined mon_decimal_point property";else a.mon_decimal_point=""}if(typeof a.mon_decimal_point!="string")throw"Error: Invalid/missing mon_decimal_point property";this.mon_decimal_point=a.mon_decimal_point;if(typeof a.mon_thousands_sep!="string")throw"Error: Invalid/missing mon_thousands_sep property";this.mon_thousands_sep=a.mon_thousands_sep;if(typeof a.mon_grouping!="string")throw"Error: Invalid/missing mon_grouping property";this.mon_grouping=a.mon_grouping;if(typeof a.positive_sign!="string")throw"Error: Invalid/missing positive_sign property";this.positive_sign=a.positive_sign;if(typeof a.negative_sign!="string")throw"Error: Invalid/missing negative_sign property";this.negative_sign=a.negative_sign;if(a.p_cs_precedes!==0&&a.p_cs_precedes!==1)throw"Error: Invalid/missing p_cs_precedes property, must be 0 or 1";this.p_cs_precedes=a.p_cs_precedes;if(a.n_cs_precedes!==0&&a.n_cs_precedes!==1)throw"Error: Invalid/missing n_cs_precedes, must be 0 or 1";this.n_cs_precedes=a.n_cs_precedes;if(a.p_sep_by_space!==0&&a.p_sep_by_space!==1&&a.p_sep_by_space!==2)throw"Error: Invalid/missing p_sep_by_space property, must be 0, 1 or 2";this.p_sep_by_space=a.p_sep_by_space;if(a.n_sep_by_space!==0&&a.n_sep_by_space!==1&&a.n_sep_by_space!==2)throw"Error: Invalid/missing n_sep_by_space property, must be 0, 1, or 2";this.n_sep_by_space=a.n_sep_by_space;if(a.p_sign_posn!==0&&a.p_sign_posn!==1&&a.p_sign_posn!==2&&a.p_sign_posn!==3&&a.p_sign_posn!==4)throw"Error: Invalid/missing p_sign_posn property, must be 0, 1, 2, 3 or 4";this.p_sign_posn=a.p_sign_posn;if(a.n_sign_posn!==0&&a.n_sign_posn!==1&&a.n_sign_posn!==2&&a.n_sign_posn!==3&&a.n_sign_posn!==4)throw"Error: Invalid/missing n_sign_posn property, must be 0, 1, 2, 3 or 4";this.n_sign_posn=a.n_sign_posn;if(typeof a.int_frac_digits!="number"&&a.int_frac_digits<0)throw"Error: Invalid/missing int_frac_digits property";this.int_frac_digits=a.int_frac_digits;if(a.int_p_cs_precedes!==0&&a.int_p_cs_precedes!==1)throw"Error: Invalid/missing int_p_cs_precedes property, must be 0 or 1";this.int_p_cs_precedes=a.int_p_cs_precedes;if(a.int_n_cs_precedes!==0&&a.int_n_cs_precedes!==1)throw"Error: Invalid/missing int_n_cs_precedes property, must be 0 or 1";this.int_n_cs_precedes=a.int_n_cs_precedes;if(a.int_p_sep_by_space!==0&&a.int_p_sep_by_space!==1&&a.int_p_sep_by_space!==2)throw"Error: Invalid/missing int_p_sep_by_spacev, must be 0, 1 or 2";this.int_p_sep_by_space=a.int_p_sep_by_space;if(a.int_n_sep_by_space!==0&&a.int_n_sep_by_space!==1&&a.int_n_sep_by_space!==2)throw"Error: Invalid/missing int_n_sep_by_space property, must be 0, 1, or 2";this.int_n_sep_by_space=a.int_n_sep_by_space;if(a.int_p_sign_posn!==0&&a.int_p_sign_posn!==1&&a.int_p_sign_posn!==2&&a.int_p_sign_posn!==3&&a.int_p_sign_posn!==4)throw"Error: Invalid/missing int_p_sign_posn property, must be 0, 1, 2, 3 or 4";this.int_p_sign_posn=a.int_p_sign_posn;if(a.int_n_sign_posn!==0&&a.int_n_sign_posn!==1&&a.int_n_sign_posn!==2&&a.int_n_sign_posn!==3&&a.int_n_sign_posn!==4)throw"Error: Invalid/missing int_n_sign_posn property, must be 0, 1, 2, 3 or 4";this.int_n_sign_posn=a.int_n_sign_posn;if(a==null||typeof a!="object")throw"Error: Invalid/missing time locale properties";try{this.abday=this._parseList(a.abday,7)}catch(b){throw"Error: Invalid abday property: "+b}try{this.day=this._parseList(a.day,7)}catch(b){throw"Error: Invalid day property: "+b}try{this.abmon=this._parseList(a.abmon,12)}catch(b){throw"Error: Invalid abmon property: "+b}try{this.mon=this._parseList(a.mon,12)}catch(b){throw"Error: Invalid mon property: "+b}try{this.d_fmt=this._validateFormatString(a.d_fmt)}catch(b){throw"Error: Invalid d_fmt property: "+b}try{this.t_fmt=this._validateFormatString(a.t_fmt)}catch(b){throw"Error: Invalid t_fmt property: "+b}try{this.d_t_fmt=this._validateFormatString(a.d_t_fmt)}catch(b){throw"Error: Invalid d_t_fmt property: "+b}try{var c=this._parseList(a.am_pm,2);this.am=c[0];this.pm=c[1]}catch(b){this.am="";this.pm=""}this.getAbbreviatedWeekdayName=function(a){if(typeof a=="undefined"||a===null)return this.abday;if(!jsworld._isInteger(a)||a<0||a>6)throw"Error: Invalid weekday argument, must be an integer [0..6]";return this.abday[a]};this.getWeekdayName=function(a){if(typeof a=="undefined"||a===null)return this.day;if(!jsworld._isInteger(a)||a<0||a>6)throw"Error: Invalid weekday argument, must be an integer [0..6]";return this.day[a]};this.getAbbreviatedMonthName=function(a){if(typeof a=="undefined"||a===null)return this.abmon;if(!jsworld._isInteger(a)||a<0||a>11)throw"Error: Invalid month argument, must be an integer [0..11]";return this.abmon[a]};this.getMonthName=function(a){if(typeof a=="undefined"||a===null)return this.mon;if(!jsworld._isInteger(a)||a<0||a>11)throw"Error: Invalid month argument, must be an integer [0..11]";return this.mon[a]};this.getDecimalPoint=function(){return this.decimal_point};this.getCurrencySymbol=function(){return this.currency_symbol};this.getIntCurrencySymbol=function(){return this.int_curr_symbol.substring(0,3)};this.currencySymbolPrecedes=function(){if(this.p_cs_precedes==1)return true;else return false};this.intCurrencySymbolPrecedes=function(){if(this.int_p_cs_precedes==1)return true;else return false};this.getMonetaryDecimalPoint=function(){return this.mon_decimal_point};this.getFractionalDigits=function(){return this.frac_digits};this.getIntFractionalDigits=function(){return this.int_frac_digits}};jsworld.NumericFormatter=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.format=function(a,b){if(typeof a=="string")a=jsworld._trim(a);if(!jsworld._isNumber(a))throw"Error: The input is not a number";var c=parseFloat(a,10);var d=jsworld._getPrecision(b);if(d!=-1)c=Math.round(c*Math.pow(10,d))/Math.pow(10,d);var e=jsworld._splitNumber(String(c));var f;if(c===0)f="0";else f=jsworld._hasOption("^",b)?e.integer:jsworld._formatIntegerPart(e.integer,this.lc.grouping,this.lc.thousands_sep);var g=d!=-1?jsworld._formatFractionPart(e.fraction,d):e.fraction;var h=g.length?f+this.lc.decimal_point+g:f;if(jsworld._hasOption("~",b)||c===0){return h}else{if(jsworld._hasOption("+",b)||c<0){if(c>0)return"+"+h;else if(c<0)return"-"+h;else return h}else{return h}}}};jsworld.DateTimeFormatter=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance.";this.lc=a;this.formatDate=function(a){var b=null;if(typeof a=="string"){try{b=jsworld.parseIsoDate(a)}catch(c){b=jsworld.parseIsoDateTime(a)}}else if(a!==null&&typeof a=="object"){b=a}else{throw"Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"}return this._applyFormatting(b,this.lc.d_fmt)};this.formatTime=function(a){var b=null;if(typeof a=="string"){try{b=jsworld.parseIsoTime(a)}catch(c){b=jsworld.parseIsoDateTime(a)}}else if(a!==null&&typeof a=="object"){b=a}else{throw"Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"}return this._applyFormatting(b,this.lc.t_fmt)};this.formatDateTime=function(a){var b=null;if(typeof a=="string"){b=jsworld.parseIsoDateTime(a)}else if(a!==null&&typeof a=="object"){b=a}else{throw"Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"}return this._applyFormatting(b,this.lc.d_t_fmt)};this._applyFormatting=function(a,b){b=b.replace(/%%/g,"%");b=b.replace(/%a/g,this.lc.abday[a.getDay()]);b=b.replace(/%A/g,this.lc.day[a.getDay()]);b=b.replace(/%b/g,this.lc.abmon[a.getMonth()]);b=b.replace(/%B/g,this.lc.mon[a.getMonth()]);b=b.replace(/%d/g,jsworld._zeroPad(a.getDate(),2));b=b.replace(/%e/g,jsworld._spacePad(a.getDate(),2));b=b.replace(/%F/g,a.getFullYear()+"-"+jsworld._zeroPad(a.getMonth()+1,2)+"-"+jsworld._zeroPad(a.getDate(),2));b=b.replace(/%h/g,this.lc.abmon[a.getMonth()]);b=b.replace(/%H/g,jsworld._zeroPad(a.getHours(),2));b=b.replace(/%I/g,jsworld._zeroPad(this._hours12(a.getHours()),2));b=b.replace(/%k/g,a.getHours());b=b.replace(/%l/g,this._hours12(a.getHours()));b=b.replace(/%m/g,jsworld._zeroPad(a.getMonth()+1,2));b=b.replace(/%n/g,"\n");b=b.replace(/%M/g,jsworld._zeroPad(a.getMinutes(),2));b=b.replace(/%p/g,this._getAmPm(a.getHours()));b=b.replace(/%P/g,this._getAmPm(a.getHours()).toLocaleLowerCase());b=b.replace(/%R/g,jsworld._zeroPad(a.getHours(),2)+":"+jsworld._zeroPad(a.getMinutes(),2));b=b.replace(/%S/g,jsworld._zeroPad(a.getSeconds(),2));b=b.replace(/%T/g,jsworld._zeroPad(a.getHours(),2)+":"+jsworld._zeroPad(a.getMinutes(),2)+":"+jsworld._zeroPad(a.getSeconds(),2));b=b.replace(/%w/g,this.lc.day[a.getDay()]);b=b.replace(/%y/g,(new String(a.getFullYear())).substring(2));b=b.replace(/%Y/g,a.getFullYear());b=b.replace(/%Z/g,"");b=b.replace(/%[a-zA-Z]/g,"");return b};this._hours12=function(a){if(a===0)return 12;else if(a>12)return a-12;else return a};this._getAmPm=function(a){if(a===0||a>12)return this.lc.pm;else return this.lc.am}};jsworld.MonetaryFormatter=function(a,b,c){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.currencyFractionDigits={AFN:0,ALL:0,AMD:0,BHD:3,BIF:0,BYR:0,CLF:0,CLP:0,COP:0,CRC:0,DJF:0,GNF:0,GYD:0,HUF:0,IDR:0,IQD:0,IRR:0,ISK:0,JOD:3,JPY:0,KMF:0,KRW:0,KWD:3,LAK:0,LBP:0,LYD:3,MGA:0,MMK:0,MNT:0,MRO:0,MUR:0,OMR:3,PKR:0,PYG:0,RSD:0,RWF:0,SLL:0,SOS:0,STD:0,SYP:0,TND:3,TWD:0,TZS:0,UGX:0,UZS:0,VND:0,VUV:0,XAF:0,XOF:0,XPF:0,YER:0,ZMK:0};if(typeof b=="string"){this.currencyCode=b.toUpperCase();var d=this.currencyFractionDigits[this.currencyCode];if(typeof d!="number")d=2;this.lc.frac_digits=d;this.lc.int_frac_digits=d}else{this.currencyCode=this.lc.int_curr_symbol.substring(0,3).toUpperCase()}this.intSep=this.lc.int_curr_symbol.charAt(3);if(this.currencyCode==this.lc.int_curr_symbol.substring(0,3)){this.internationalFormatting=false;this.curSym=this.lc.currency_symbol}else{if(typeof c=="string"){this.curSym=c;this.internationalFormatting=false}else{this.internationalFormatting=true}}this.getCurrencySymbol=function(){return this.curSym};this.currencySymbolPrecedes=function(a){if(typeof a=="string"&&a=="i"){if(this.lc.int_p_cs_precedes==1)return true;else return false}else{if(this.internationalFormatting){if(this.lc.int_p_cs_precedes==1)return true;else return false}else{if(this.lc.p_cs_precedes==1)return true;else return false}}};this.getDecimalPoint=function(){return this.lc.mon_decimal_point};this.getFractionalDigits=function(a){if(typeof a=="string"&&a=="i"){return this.lc.int_frac_digits}else{if(this.internationalFormatting)return this.lc.int_frac_digits;else return this.lc.frac_digits}};this.format=function(a,b){var c;if(typeof a=="string"){a=jsworld._trim(a);c=parseFloat(a);if(typeof c!="number"||isNaN(c))throw"Error: Amount string not a number"}else if(typeof a=="number"){c=a}else{throw"Error: Amount not a number"}var d=jsworld._getPrecision(b);if(d==-1){if(this.internationalFormatting||jsworld._hasOption("i",b))d=this.lc.int_frac_digits;else d=this.lc.frac_digits}c=Math.round(c*Math.pow(10,d))/Math.pow(10,d);var e=jsworld._splitNumber(String(c));var f;if(c===0)f="0";else f=jsworld._hasOption("^",b)?e.integer:jsworld._formatIntegerPart(e.integer,this.lc.mon_grouping,this.lc.mon_thousands_sep);var g;if(d==-1){if(this.internationalFormatting||jsworld._hasOption("i",b))g=jsworld._formatFractionPart(e.fraction,this.lc.int_frac_digits);else g=jsworld._formatFractionPart(e.fraction,this.lc.frac_digits)}else{g=jsworld._formatFractionPart(e.fraction,d)}var h;if(this.lc.frac_digits>0||g.length)h=f+this.lc.mon_decimal_point+g;else h=f;if(jsworld._hasOption("~",b)){return h}else{var i=jsworld._hasOption("!",b)?true:false;var j=c<0?"-":"+";if(this.internationalFormatting||jsworld._hasOption("i",b)){if(i)return this._formatAsInternationalCurrencyWithNoSym(j,h);else return this._formatAsInternationalCurrency(j,h)}else{if(i)return this._formatAsLocalCurrencyWithNoSym(j,h);else return this._formatAsLocalCurrency(j,h)}}};this._formatAsLocalCurrency=function(a,b){if(a=="+"){if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return"("+b+this.curSym+")"}else if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return"("+this.curSym+b+")"}else if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return"("+b+" "+this.curSym+")"}else if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return"("+this.curSym+" "+b+")"}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b+this.curSym}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b+" "+this.curSym}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+" "+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+" "+b+this.curSym}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+this.curSym+b}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.curSym+b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.curSym+" "+b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.curSym+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.curSym+b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign+this.curSym}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign+this.curSym}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+" "+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign+" "+this.curSym}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+this.curSym+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.curSym+this.lc.positive_sign+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.curSym+this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.curSym+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.curSym+" "+this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return"("+b+this.curSym+")"}else if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return"("+this.curSym+b+")"}else if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return"("+b+" "+this.curSym+")"}else if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return"("+this.curSym+" "+b+")"}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b+this.curSym}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b+" "+this.curSym}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+" "+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+" "+b+this.curSym}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+this.curSym+b}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.curSym+b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.curSym+" "+b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.curSym+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.curSym+b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign+this.curSym}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign+this.curSym}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+" "+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign+" "+this.curSym}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+this.curSym+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.curSym+this.lc.negative_sign+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.curSym+this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.curSym+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.curSym+" "+this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC MONETARY definition"};this._formatAsInternationalCurrency=function(a,b){if(a=="+"){if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return"("+b+this.currencyCode+")"}else if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return"("+this.currencyCode+b+")"}else if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return"("+b+this.intSep+this.currencyCode+")"}else if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return"("+this.currencyCode+this.intSep+b+")"}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b+this.currencyCode}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b+this.intSep+this.currencyCode}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+this.intSep+b+this.currencyCode}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.currencyCode+b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.intSep+b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.currencyCode+b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign+this.currencyCode}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign+this.currencyCode}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign+this.intSep+this.currencyCode}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.intSep+this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return"("+b+this.currencyCode+")"}else if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return"("+this.currencyCode+b+")"}else if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return"("+b+this.intSep+this.currencyCode+")"}else if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return"("+this.currencyCode+this.intSep+b+")"}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b+this.currencyCode}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b+this.intSep+this.currencyCode}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+this.intSep+b+this.currencyCode}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.currencyCode+b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.intSep+b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.currencyCode+b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign+this.currencyCode}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign+this.currencyCode}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign+this.intSep+this.currencyCode}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.intSep+this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC MONETARY definition"};this._formatAsLocalCurrencyWithNoSym=function(a,b){if(a=="+"){if(this.lc.p_sign_posn===0){return"("+b+")"}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.n_sign_posn===0){return"("+b+")"}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC MONETARY definition"};this._formatAsInternationalCurrencyWithNoSym=function(a,b){if(a=="+"){if(this.lc.int_p_sign_posn===0){return"("+b+")"}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.int_n_sign_posn===0){return"("+b+")"}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC_MONETARY definition"}};jsworld.NumericParser=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.parse=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=jsworld._trim(a);b=jsworld._stringReplaceAll(a,this.lc.thousands_sep,"");b=jsworld._stringReplaceAll(b,this.lc.decimal_point,".");if(jsworld._isNumber(b))return parseFloat(b,10);else throw"Parse error: Invalid number string"}};jsworld.DateTimeParser=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance.";this.lc=a;this.parseTime=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._extractTokens(this.lc.t_fmt,a);var c=false;if(b.hour!==null&&b.minute!==null&&b.second!==null){c=true}else if(b.hourAmPm!==null&&b.am!==null&&b.minute!==null&&b.second!==null){if(b.am){b.hour=parseInt(b.hourAmPm,10)}else{if(b.hourAmPm==12)b.hour=0;else b.hour=parseInt(b.hourAmPm,10)+12}c=true}if(c)return jsworld._zeroPad(b.hour,2)+":"+jsworld._zeroPad(b.minute,2)+":"+jsworld._zeroPad(b.second,2);else throw"Parse error: Invalid/ambiguous time string"};this.parseDate=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._extractTokens(this.lc.d_fmt,a);var c=false;if(b.year!==null&&b.month!==null&&b.day!==null){c=true}if(c)return jsworld._zeroPad(b.year,4)+"-"+jsworld._zeroPad(b.month,2)+"-"+jsworld._zeroPad(b.day,2);else throw"Parse error: Invalid date string"};this.parseDateTime=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._extractTokens(this.lc.d_t_fmt,a);var c=false;var d=false;if(b.hour!==null&&b.minute!==null&&b.second!==null){c=true}else if(b.hourAmPm!==null&&b.am!==null&&b.minute!==null&&b.second!==null){if(b.am){b.hour=parseInt(b.hourAmPm,10)}else{if(b.hourAmPm==12)b.hour=0;else b.hour=parseInt(b.hourAmPm,10)+12}c=true}if(b.year!==null&&b.month!==null&&b.day!==null){d=true}if(d&&c)return jsworld._zeroPad(b.year,4)+"-"+jsworld._zeroPad(b.month,2)+"-"+jsworld._zeroPad(b.day,2)+" "+jsworld._zeroPad(b.hour,2)+":"+jsworld._zeroPad(b.minute,2)+":"+jsworld._zeroPad(b.second,2);else throw"Parse error: Invalid/ambiguous date/time string"};this._extractTokens=function(a,b){var c={year:null,month:null,day:null,hour:null,hourAmPm:null,am:null,minute:null,second:null,weekday:null};while(a.length>0){if(a.charAt(0)=="%"&&a.charAt(1)!=""){var d=a.substring(0,2);if(d=="%%"){b=b.substring(1)}else if(d=="%a"){for(var e=0;e31)throw"Parse error: Unrecognised day of the month (%e)";b=b.substring(f.length)}else if(d=="%F"){if(/^\d\d\d\d/.test(b)){c.year=parseInt(b.substring(0,4),10);b=b.substring(4)}else{throw"Parse error: Unrecognised date (%F)"}if(jsworld._stringStartsWith(b,"-"))b=b.substring(1);else throw"Parse error: Unrecognised date (%F)";if(/^0[1-9]|1[0-2]/.test(b)){c.month=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised date (%F)";if(jsworld._stringStartsWith(b,"-"))b=b.substring(1);else throw"Parse error: Unrecognised date (%F)";if(/^0[1-9]|[1-2][0-9]|3[0-1]/.test(b)){c.day=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised date (%F)"}else if(d=="%H"){if(/^[0-1][0-9]|2[0-3]/.test(b)){c.hour=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised hour (%H)"}else if(d=="%I"){if(/^0[1-9]|1[0-2]/.test(b)){c.hourAmPm=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised hour (%I)"}else if(d=="%k"){var g=b.match(/^(\d{1,2})/);c.hour=parseInt(g,10);if(isNaN(c.hour)||c.hour<0||c.hour>23)throw"Parse error: Unrecognised hour (%k)";b=b.substring(g.length)}else if(d=="%l"){var g=b.match(/^(\d{1,2})/);c.hourAmPm=parseInt(g,10);if(isNaN(c.hourAmPm)||c.hourAmPm<1||c.hourAmPm>12)throw"Parse error: Unrecognised hour (%l)";b=b.substring(g.length)}else if(d=="%m"){if(/^0[1-9]|1[0-2]/.test(b)){c.month=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised month (%m)"}else if(d=="%M"){if(/^[0-5][0-9]/.test(b)){c.minute=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised minute (%M)"}else if(d=="%n"){if(b.charAt(0)=="\n")b=b.substring(1);else throw"Parse error: Unrecognised new line (%n)"}else if(d=="%p"){if(jsworld._stringStartsWith(b,this.lc.am)){c.am=true;b=b.substring(this.lc.am.length)}else if(jsworld._stringStartsWith(b,this.lc.pm)){c.am=false;b=b.substring(this.lc.pm.length)}else throw"Parse error: Unrecognised AM/PM value (%p)"}else if(d=="%P"){if(jsworld._stringStartsWith(b,this.lc.am.toLowerCase())){c.am=true;b=b.substring(this.lc.am.length)}else if(jsworld._stringStartsWith(b,this.lc.pm.toLowerCase())){c.am=false;b=b.substring(this.lc.pm.length)}else throw"Parse error: Unrecognised AM/PM value (%P)"}else if(d=="%R"){if(/^[0-1][0-9]|2[0-3]/.test(b)){c.hour=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%R)";if(jsworld._stringStartsWith(b,":"))b=b.substring(1);else throw"Parse error: Unrecognised time (%R)";if(/^[0-5][0-9]/.test(b)){c.minute=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%R)"}else if(d=="%S"){if(/^[0-5][0-9]/.test(b)){c.second=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised second (%S)"}else if(d=="%T"){if(/^[0-1][0-9]|2[0-3]/.test(b)){c.hour=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%T)";if(jsworld._stringStartsWith(b,":"))b=b.substring(1);else throw"Parse error: Unrecognised time (%T)";if(/^[0-5][0-9]/.test(b)){c.minute=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%T)";if(jsworld._stringStartsWith(b,":"))b=b.substring(1);else throw"Parse error: Unrecognised time (%T)";if(/^[0-5][0-9]/.test(b)){c.second=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%T)"}else if(d=="%w"){if(/^\d/.test(b)){c.weekday=parseInt(b.substring(0,1),10);b=b.substring(1)}else throw"Parse error: Unrecognised weekday number (%w)"}else if(d=="%y"){if(/^\d\d/.test(b)){var h=parseInt(b.substring(0,2),10);if(h>50)c.year=1900+h;else c.year=2e3+h;b=b.substring(2)}else throw"Parse error: Unrecognised year (%y)"}else if(d=="%Y"){if(/^\d\d\d\d/.test(b)){c.year=parseInt(b.substring(0,4),10);b=b.substring(4)}else throw"Parse error: Unrecognised year (%Y)"}else if(d=="%Z"){if(a.length===0)break}a=a.substring(2)}else{if(a.charAt(0)!=b.charAt(0))throw'Parse error: Unexpected symbol "'+b.charAt(0)+'" in date/time string';a=a.substring(1);b=b.substring(1)}}return c}};jsworld.MonetaryParser=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.parse=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._detectCurrencySymbolType(a);var c,d;if(b=="local"){c="local";d=a.replace(this.lc.getCurrencySymbol(),"")}else if(b=="int"){c="int";d=a.replace(this.lc.getIntCurrencySymbol(),"")}else if(b=="none"){c="local";d=a}else throw"Parse error: Internal assert failure";d=jsworld._stringReplaceAll(d,this.lc.mon_thousands_sep,"");d=d.replace(this.lc.mon_decimal_point,".");d=d.replace(/\s*/g,"");d=this._removeLocalNonNegativeSign(d,c);d=this._normaliseNegativeSign(d,c);if(jsworld._isNumber(d))return parseFloat(d,10);else throw"Parse error: Invalid currency amount string"};this._detectCurrencySymbolType=function(a){if(this.lc.getCurrencySymbol().length>this.lc.getIntCurrencySymbol().length){if(a.indexOf(this.lc.getCurrencySymbol())!=-1)return"local";else if(a.indexOf(this.lc.getIntCurrencySymbol())!=-1)return"int";else return"none"}else{if(a.indexOf(this.lc.getIntCurrencySymbol())!=-1)return"int";else if(a.indexOf(this.lc.getCurrencySymbol())!=-1)return"local";else return"none"}};this._removeLocalNonNegativeSign=function(a,b){a=a.replace(this.lc.positive_sign,"");if((b=="local"&&this.lc.p_sign_posn===0||b=="int"&&this.lc.int_p_sign_posn===0)&&/\(\d+\.?\d*\)/.test(a)){a=a.replace("(","");a=a.replace(")","")}return a};this._normaliseNegativeSign=function(a,b){a=a.replace(this.lc.negative_sign,"-");if(b=="local"&&this.lc.n_sign_posn===0||b=="int"&&this.lc.int_n_sign_posn===0){if(/^\(\d+\.?\d*\)$/.test(a)){a=a.replace("(","");a=a.replace(")","");return"-"+a}}if(b=="local"&&this.lc.n_sign_posn==2||b=="int"&&this.lc.int_n_sign_posn==2){if(/^\d+\.?\d*-$/.test(a)){a=a.replace("-","");return"-"+a}}if(b=="local"&&this.lc.n_cs_precedes===0&&this.lc.n_sign_posn==3||b=="local"&&this.lc.n_cs_precedes===0&&this.lc.n_sign_posn==4||b=="int"&&this.lc.int_n_cs_precedes===0&&this.lc.int_n_sign_posn==3||b=="int"&&this.lc.int_n_cs_precedes===0&&this.lc.int_n_sign_posn==4){if(/^\d+\.?\d*-$/.test(a)){a=a.replace("-","");return"-"+a}}return a}} + + +if(typeof POSIX_LC == "undefined") var POSIX_LC = {}; + +POSIX_LC.en_US = { + "decimal_point" : ".", + "thousands_sep" : ",", + "grouping" : "3", + "abday" : ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + "day" : ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + "abmon" : ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"], + "mon" : ["January","February","March","April","May","June","July","August","September","October","November","December"], + "d_fmt" : "%m/%e/%y", + "t_fmt" : "%I:%M:%S %p", + "d_t_fmt" : "%B %e, %Y %I:%M:%S %p %Z", + "am_pm" : ["AM","PM"], + "int_curr_symbol" : "USD ", + "currency_symbol" : "\u0024", + "mon_decimal_point" : ".", + "mon_thousands_sep" : ",", + "mon_grouping" : "3", + "positive_sign" : "", + "negative_sign" : "-", + "int_frac_digits" : 2, + "frac_digits" : 2, + "p_cs_precedes" : 1, + "n_cs_precedes" : 1, + "p_sep_by_space" : 0, + "n_sep_by_space" : 0, + "p_sign_posn" : 1, + "n_sign_posn" : 1, + "int_p_cs_precedes" : 1, + "int_n_cs_precedes" : 1, + "int_p_sep_by_space" : 0, + "int_n_sep_by_space" : 0, + "int_p_sign_posn" : 1, + "int_n_sign_posn" : 1 +} + +if(typeof POSIX_LC == "undefined") var POSIX_LC = {}; + +POSIX_LC.fr_FR = { + "decimal_point" : ",", + "thousands_sep" : "\u00a0", + "grouping" : "3", + "abday" : ["dim.","lun.","mar.", + "mer.","jeu.","ven.", + "sam."], + "day" : ["dimanche","lundi","mardi", + "mercredi","jeudi","vendredi", + "samedi"], + "abmon" : ["janv.","f\u00e9vr.","mars", + "avr.","mai","juin", + "juil.","ao\u00fbt","sept.", + "oct.","nov.","d\u00e9c."], + "mon" : ["janvier","f\u00e9vrier","mars", + "avril","mai","juin", + "juillet","ao\u00fbt","septembre", + "octobre","novembre","d\u00e9cembre"], + "d_fmt" : "%d/%m/%y", + "t_fmt" : "%H:%M:%S", + "d_t_fmt" : "%e %B %Y %H:%M:%S %Z", + "am_pm" : ["AM","PM"], + "int_curr_symbol" : "EUR ", + "currency_symbol" : "\u20ac", + "mon_decimal_point" : ",", + "mon_thousands_sep" : "\u00a0", + "mon_grouping" : "3", + "positive_sign" : "", + "negative_sign" : "-", + "int_frac_digits" : 2, + "frac_digits" : 2, + "p_cs_precedes" : 0, + "n_cs_precedes" : 0, + "p_sep_by_space" : 1, + "n_sep_by_space" : 1, + "p_sign_posn" : 1, + "n_sign_posn" : 1, + "int_p_cs_precedes" : 0, + "int_n_cs_precedes" : 0, + "int_p_sep_by_space" : 1, + "int_n_sep_by_space" : 1, + "int_p_sign_posn" : 1, + "int_n_sign_posn" : 1 +}; + +/** https://github.com/csnover/js-iso8601 */(function(n,f){var u=n.parse,c=[1,4,5,6,7,10,11];n.parse=function(t){var i,o,a=0;if(o=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(t)){for(var v=0,r;r=c[v];++v)o[r]=+o[r]||0;o[2]=(+o[2]||1)-1,o[3]=+o[3]||1,o[8]!=="Z"&&o[9]!==f&&(a=o[10]*60+o[11],o[9]==="+"&&(a=0-a)),i=n.UTC(o[1],o[2],o[3],o[4],o[5]+a,o[6],o[7])}else i=u?u(t):NaN;return i}})(Date) + +/*! + * geo-location-javascript v0.4.3 + * http://code.google.com/p/geo-location-javascript/ + * + * Copyright (c) 2009 Stan Wiechers + * Licensed under the MIT licenses. + * + * Revision: $Rev: 68 $: + * Author: $Author: whoisstan $: + * Date: $Date: 2010-02-15 13:42:19 +0100 (Mon, 15 Feb 2010) $: + */ +var geo_position_js=function() { + + var pub = {}; + var provider=null; + + pub.getCurrentPosition = function(successCallback,errorCallback,options) + { + provider.getCurrentPosition(successCallback, errorCallback,options); + } + + pub.init = function() + { + try + { + if (typeof(geo_position_js_simulator)!="undefined") + { + provider=geo_position_js_simulator; + } + else if (typeof(bondi)!="undefined" && typeof(bondi.geolocation)!="undefined") + { + provider=bondi.geolocation; + } + else if (typeof(navigator.geolocation)!="undefined") + { + provider=navigator.geolocation; + pub.getCurrentPosition = function(successCallback, errorCallback, options) + { + function _successCallback(p) + { + //for mozilla geode,it returns the coordinates slightly differently + if(typeof(p.latitude)!="undefined") + { + successCallback({timestamp:p.timestamp, coords: {latitude:p.latitude,longitude:p.longitude}}); + } + else + { + successCallback(p); + } + } + provider.getCurrentPosition(_successCallback,errorCallback,options); + } + } + else if(typeof(window.google)!="undefined" && typeof(google.gears)!="undefined") + { + provider=google.gears.factory.create('beta.geolocation'); + } + else if ( typeof(Mojo) !="undefined" && typeof(Mojo.Service.Request)!="Mojo.Service.Request") + { + provider=true; + pub.getCurrentPosition = function(successCallback, errorCallback, options) + { + + parameters={}; + if(options) + { + //http://developer.palm.com/index.php?option=com_content&view=article&id=1673#GPS-getCurrentPosition + if (options.enableHighAccuracy && options.enableHighAccuracy==true) + { + parameters.accuracy=1; + } + if (options.maximumAge) + { + parameters.maximumAge=options.maximumAge; + } + if (options.responseTime) + { + if(options.responseTime<5) + { + parameters.responseTime=1; + } + else if (options.responseTime<20) + { + parameters.responseTime=2; + } + else + { + parameters.timeout=3; + } + } + } + + + r=new Mojo.Service.Request('palm://com.palm.location', { + method:"getCurrentPosition", + parameters:parameters, + onSuccess: function(p){successCallback({timestamp:p.timestamp, coords: {latitude:p.latitude, longitude:p.longitude,heading:p.heading}});}, + onFailure: function(e){ + if (e.errorCode==1) + { + errorCallback({code:3,message:"Timeout"}); + } + else if (e.errorCode==2) + { + errorCallback({code:2,message:"Position Unavailable"}); + } + else + { + errorCallback({code:0,message:"Unknown Error: webOS-code"+errorCode}); + } + } + }); + } + + } + else if (typeof(device)!="undefined" && typeof(device.getServiceObject)!="undefined") + { + provider=device.getServiceObject("Service.Location", "ILocation"); + + //override default method implementation + pub.getCurrentPosition = function(successCallback, errorCallback, options) + { + function callback(transId, eventCode, result) { + if (eventCode == 4) + { + errorCallback({message:"Position unavailable", code:2}); + } + else + { + //no timestamp of location given? + successCallback({timestamp:null, coords: {latitude:result.ReturnValue.Latitude, longitude:result.ReturnValue.Longitude, altitude:result.ReturnValue.Altitude,heading:result.ReturnValue.Heading}}); + } + } + //location criteria + var criteria = new Object(); + criteria.LocationInformationClass = "BasicLocationInformation"; + //make the call + provider.ILocation.GetLocation(criteria,callback); + } + } + } + catch (e){ + alert("error="+e); + if(typeof(console)!="undefined") + { + console.log(e); + } + return false; + } + return provider!=null; + } + + + return pub; +}(); +// Couldn't get unminified version to work , go here for docs => https://github.com/iamnoah/writeCapture +(function(E,a){var j=a.document;function A(Q){var Z=j.createElement("div");j.body.insertBefore(Z,null);E.replaceWith(Z,'\n \n
\n
\n \n\n
\n
\n \n
\n

'); + __out.push(__sanitize(t('Invite Link'))); + __out.push(' '); + __out.push(__sanitize(USER.referral_url)); + __out.push('

\n\n \n\n
\n\n'); + }).call(this); + + }).call(__obj); + __obj.safe = __objSafe, __obj.escape = __escape; + return __out.join(''); +}}, "templates/clients/login": function(exports, require, module) {module.exports = function(__obj) { + if (!__obj) __obj = {}; + var __out = [], __capture = function(callback) { + var out = __out, result; + __out = []; + callback.call(this); + result = __out.join(''); + __out = out; + return __safe(result); + }, __sanitize = function(value) { + if (value && value.ecoSafe) { + return value; + } else if (typeof value !== 'undefined' && value != null) { + return __escape(value); + } else { + return ''; + } + }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; + __safe = __obj.safe = function(value) { + if (value && value.ecoSafe) { + return value; + } else { + if (!(typeof value !== 'undefined' && value != null)) value = ''; + var result = new String(value); + result.ecoSafe = true; + return result; + } + }; + if (!__escape) { + __escape = __obj.escape = function(value) { + return ('' + value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + }; + } + (function() { + (function() { + __out.push('
\n\t

'); + __out.push(__sanitize(t('Sign In'))); + __out.push('

\n\t
\n\t\t
\n\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\n\t\t\t
\n\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\n\t\t\t
\n\n
\n\n

'); + __out.push(__sanitize(t('Forgot Password?'))); + __out.push('

\n\n\t\t
\n\t
\n
\n\n
\n
\n'); + }).call(this); + + }).call(__obj); + __obj.safe = __objSafe, __obj.escape = __escape; + return __out.join(''); +}}, "templates/clients/modules/credit_card": function(exports, require, module) {module.exports = function(__obj) { + if (!__obj) __obj = {}; + var __out = [], __capture = function(callback) { + var out = __out, result; + __out = []; + callback.call(this); + result = __out.join(''); + __out = out; + return __safe(result); + }, __sanitize = function(value) { + if (value && value.ecoSafe) { + return value; + } else if (typeof value !== 'undefined' && value != null) { + return __escape(value); + } else { + return ''; + } + }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; + __safe = __obj.safe = function(value) { + if (value && value.ecoSafe) { + return value; + } else { + if (!(typeof value !== 'undefined' && value != null)) value = ''; + var result = new String(value); + result.ecoSafe = true; + return result; + } + }; + if (!__escape) { + __escape = __obj.escape = function(value) { + return ('' + value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + }; + } + (function() { + (function() { + var printCard; + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + if (this.cards === "new") { + __out.push('\n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n \n
\n
\n
\n'); + } else { + __out.push('\n '); + printCard = __bind(function(card, index) { + var exp, style; + __out.push('\n \n \n '); + style = "background-position:-173px"; + __out.push('\n '); + if (card.get("card_type") === "Visa") { + style = "background-position:0px"; + } + __out.push('\n '); + if (card.get("card_type") === "MasterCard") { + style = "background-position:-42px"; + } + __out.push('\n '); + if (card.get("card_type") === "American Express") { + style = "background-position:-130px"; + } + __out.push('\n '); + if (card.get("card_type") === "Discover Card") { + style = "background-position:-85px"; + } + __out.push('\n
\n \n \n ****'); + __out.push(__sanitize(card.get("card_number"))); + __out.push('\n \n \n '); + if (card.get("card_expiration")) { + __out.push('\n '); + __out.push(__sanitize(t('Expiry'))); + __out.push('\n '); + exp = card.get('card_expiration').split('-'); + __out.push('\n '); + __out.push(__sanitize("" + exp[0] + "-" + exp[1])); + __out.push('\n '); + } + __out.push('\n \n \n \n \n \n '); + if (card.get("default")) { + __out.push('\n ('); + __out.push(__sanitize(t('default card'))); + __out.push(')\n '); + } + __out.push('\n '); + if (this.cards.length > 1 && !card.get("default")) { + __out.push('\n '); + __out.push(__sanitize(t('make default'))); + __out.push('\n '); + } + __out.push('\n \n \n '); + __out.push(__sanitize(t('Edit'))); + __out.push('\n \n \n '); + if (this.cards.length > 1) { + __out.push('\n '); + __out.push(__sanitize(t('Delete'))); + __out.push('\n '); + } + __out.push('\n \n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n \n
\n \n '); + }, this); + __out.push('\n\n
\n \n '); + _.each(this.cards.models, printCard); + __out.push('\n
\n
\n\n'); + } + __out.push('\n'); + }).call(this); + + }).call(__obj); + __obj.safe = __objSafe, __obj.escape = __escape; + return __out.join(''); +}}, "templates/clients/modules/sub_header": function(exports, require, module) {module.exports = function(__obj) { + if (!__obj) __obj = {}; + var __out = [], __capture = function(callback) { + var out = __out, result; + __out = []; + callback.call(this); + result = __out.join(''); + __out = out; + return __safe(result); + }, __sanitize = function(value) { + if (value && value.ecoSafe) { + return value; + } else if (typeof value !== 'undefined' && value != null) { + return __escape(value); + } else { + return ''; + } + }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; + __safe = __obj.safe = function(value) { + if (value && value.ecoSafe) { + return value; + } else { + if (!(typeof value !== 'undefined' && value != null)) value = ''; + var result = new String(value); + result.ecoSafe = true; + return result; + } + }; + if (!__escape) { + __escape = __obj.escape = function(value) { + return ('' + value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + }; + } + (function() { + (function() { + __out.push('
\n
'); + __out.push(__sanitize(this.heading)); + __out.push('
\n
\n '); + if (window.USER.first_name) { + __out.push('\n '); + __out.push(__sanitize(t('Hello Greeting', { + name: USER.first_name + }))); + __out.push('\n '); + } + __out.push('\n
\n
\n
\n'); + }).call(this); + + }).call(__obj); + __obj.safe = __objSafe, __obj.escape = __escape; + return __out.join(''); +}}, "templates/clients/promotions": function(exports, require, module) {module.exports = function(__obj) { + if (!__obj) __obj = {}; + var __out = [], __capture = function(callback) { + var out = __out, result; + __out = []; + callback.call(this); + result = __out.join(''); + __out = out; + return __safe(result); + }, __sanitize = function(value) { + if (value && value.ecoSafe) { + return value; + } else if (typeof value !== 'undefined' && value != null) { + return __escape(value); + } else { + return ''; + } + }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; + __safe = __obj.safe = function(value) { + if (value && value.ecoSafe) { + return value; + } else { + if (!(typeof value !== 'undefined' && value != null)) value = ''; + var result = new String(value); + result.ecoSafe = true; + return result; + } + }; + if (!__escape) { + __escape = __obj.escape = function(value) { + return ('' + value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + }; + } + (function() { + (function() { + var promo, _i, _len, _ref; + __out.push(require('templates/clients/modules/sub_header').call(this, { + heading: t("Promotions") + })); + __out.push('\n\n
\n
\n
\n \n \n
\n
\n \n \n\n \n
\n '); + if (this.promos.length > 0) { + __out.push('\n
\n

'); + __out.push(__sanitize(t('Your Available Promotions'))); + __out.push('

\n \n \n\n \n \n \n \n \n \n \n \n '); + _ref = this.promos; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + promo = _ref[_i]; + __out.push('\n \n \n \n \n \n \n '); + } + __out.push('\n \n
'); + __out.push(__sanitize(t('Code'))); + __out.push(''); + __out.push(__sanitize(t('Details'))); + __out.push(''); + __out.push(__sanitize(t('Starts'))); + __out.push(''); + __out.push(__sanitize(t('Expires'))); + __out.push('
'); + __out.push(__sanitize(promo.code)); + __out.push(''); + __out.push(__sanitize(promo.description)); + __out.push(''); + __out.push(__sanitize(app.helpers.formatDate(promo.starts_at, true, "America/Los_Angeles"))); + __out.push(''); + __out.push(__sanitize(app.helpers.formatDate(promo.ends_at, true, "America/Los_Angeles"))); + __out.push('
\n
\n '); + } else { + __out.push('\n\n

'); + __out.push(__sanitize(t('No Active Promotions'))); + __out.push('

\n '); + } + __out.push('\n\n
\n
\n
\n'); + }).call(this); + + }).call(__obj); + __obj.safe = __objSafe, __obj.escape = __escape; + return __out.join(''); +}}, "templates/clients/request": function(exports, require, module) {module.exports = function(__obj) { + if (!__obj) __obj = {}; + var __out = [], __capture = function(callback) { + var out = __out, result; + __out = []; + callback.call(this); + result = __out.join(''); + __out = out; + return __safe(result); + }, __sanitize = function(value) { + if (value && value.ecoSafe) { + return value; + } else if (typeof value !== 'undefined' && value != null) { + return __escape(value); + } else { + return ''; + } + }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; + __safe = __obj.safe = function(value) { + if (value && value.ecoSafe) { + return value; + } else { + if (!(typeof value !== 'undefined' && value != null)) value = ''; + var result = new String(value); + result.ecoSafe = true; + return result; + } + }; + if (!__escape) { + __escape = __obj.escape = function(value) { + return ('' + value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + }; + } + (function() { + (function() { + var showFavoriteLocation; + showFavoriteLocation = function(location, index) { + var alphabet; + __out.push('\n '); + alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + __out.push('\n \n \n \n \n \n '); + __out.push(__sanitize(location.nickname)); + return __out.push('\n \n \n'); + }; + __out.push('\n\n'); + __out.push(require('templates/clients/modules/sub_header').call(this, { + heading: t("Ride Request") + })); + __out.push('\n\n\n
\n
\n
\n
\n \n \n \n
\n
\n\n \n
\n
\n
\n
\n'); + }).call(this); + + }).call(__obj); + __obj.safe = __objSafe, __obj.escape = __escape; + return __out.join(''); +}}, "templates/shared/menu": function(exports, require, module) {module.exports = function(__obj) { + if (!__obj) __obj = {}; + var __out = [], __capture = function(callback) { + var out = __out, result; + __out = []; + callback.call(this); + result = __out.join(''); + __out = out; + return __safe(result); + }, __sanitize = function(value) { + if (value && value.ecoSafe) { + return value; + } else if (typeof value !== 'undefined' && value != null) { + return __escape(value); + } else { + return ''; + } + }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; + __safe = __obj.safe = function(value) { + if (value && value.ecoSafe) { + return value; + } else { + if (!(typeof value !== 'undefined' && value != null)) value = ''; + var result = new String(value); + result.ecoSafe = true; + return result; + } + }; + if (!__escape) { + __escape = __obj.escape = function(value) { + return ('' + value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + }; + } + (function() { + (function() { + __out.push('\n'); + }).call(this); + + }).call(__obj); + __obj.safe = __objSafe, __obj.escape = __escape; + return __out.join(''); +}}, "translations/en": function(exports, require, module) {(function() { + exports.translations = { + "Uber": "Uber", + "Sign Up": "Sign Up", + "Ride Request": "Ride Request", + "Invite Friends": "Invite Friends", + "Promotions": "Promotions", + "Billing": "Billing", + "Settings": "Settings", + "Forgot Password?": "Forgot Password?", + "Password Recovery": "Password Recovery", + "Login": "Login", + "Trip Detail": "Trip Detail", + "Password Reset": "Password Reset", + "Confirm Email": "Confirm Email", + "Request Ride": "Request Ride", + "Credit Card Number": "Credit Card Number", + "month": "month", + "01-Jan": "01-Jan", + "02-Feb": "02-Feb", + "03-Mar": "03-Mar", + "04-Apr": "04-Apr", + "05-May": "05-May", + "06-Jun": "06-Jun", + "07-Jul": "07-Jul", + "08-Aug": "08-Aug", + "09-Sep": "09-Sep", + "10-Oct": "10-Oct", + "11-Nov": "11-Nov", + "12-Dec": "12-Dec", + "year": "year", + "CVV": "CVV", + "Category": "Category", + "personal": "personal", + "business": "business", + "Default Credit Card": "Default Credit Card", + "Add Credit Card": "Add Credit Card", + "Expiry": "Expiry", + "default card": "default card", + "make default": "make default", + "Edit": "Edit", + "Delete": "Delete", + "Expiry Month": "Expiry Month", + "Expiry Year": "Expiry Year", + "Unable to Verify Card": "Unable to verify card at this time. Please try again later.", + "Credit Card Update Succeeded": "Your card has been successfully updated!", + "Credit Card Update Failed": "We couldn't save your changes. Please try again in a few minutes.", + "Credit Card Delete Succeeded": "Your card has been deleted!", + "Credit Card Delete Failed": "We were unable to delete your card. Please try again later.", + "Credit Card Update Category Succeeded": "Successfully changed card category!", + "Credit Card Update Category Failed": "We couldn't change your card category. Please try again in a few minutes.", + "Credit Card Update Default Succeeded": "Successfully changed default card!", + "Credit Card Update Default Failed": "We couldn't change your default card. Please try again in a few minutes.", + "Hello Greeting": "Hello, <%= name %>", + "Card Ending in": "Card Ending in", + "Trip Map": "Trip Map", + "Amount": "Amount: <%= amount %>", + "Last Attempt to Bill": "Last Attempt to Bill: <%= date %>", + "Charge": "Charge", + "Uber Credit Balance Note": "Your account has an UberCredit balance of <%= amount %>. When billing for trips, we'll deplete your UberCredit balance before applying charges to your credit card.", + "Please Add Credit Card": "Please add a credit card to bill your outstanding charges.", + "Credit Cards": "Credit Cards", + "add a new credit card": "add a new credit card", + "Account Balance": "Account Balance", + "Arrears": "Arrears", + "Billing Succeeded": "Your card was successfully billed.", + "Confirm Email Succeeded": "Successfully confirmed email token, redirecting to log in page...", + "Confirm Email Failed": "Unable to confirm email. Please contact support@uber.com if this problem persists.", + "Email Already Confirmed": "Your email address has already been confirmed, redirecting to log in page...", + "Credit Card Added": "Credit Card Added", + "No Credit Card": "No Credit Card", + "Mobile Number Confirmed": "Mobile Number Confirmed", + "No Confirmed Mobile": "No Confirmed Mobile", + "E-mail Address Confirmed": "E-mail Address Confirmed", + "No Confirmed E-mail": "No Confirmed E-mail", + 'Reply to sign up text': 'Reply "GO" to the text message you received at sign up.', + "Resend text message": "Resend text message", + "Click sign up link": "Click the link in the email you received at sign up.", + "Resend email": "Resend email", + "Add a credit card to ride": "Add a credit card and you'll be ready to ride Uber.", + "Your Most Recent Trip": "Your Most Recent Trip", + "details": "details", + "Your Trip History ": "Your Trip History ", + "Status": "Status", + "Here's how it works:": "Here's how it works:", + "Show all trips": "Show all trips", + "Set your location:": "Set your location:", + "App search for address": "iPhone/Android app: fix the pin or search for an address", + "SMS text address": "SMS: text your address to UBRCAB (827222)", + "Confirm pickup request": "Confirm your pickup request", + "Uber sends ETA": "Uber will send you an ETA (usually within 5-10 minutes)", + "Car arrives": "When your car is arriving, Uber will inform you again.", + "Ride to destination": "Hop in the car and tell the driver your destination.", + "Thank your driver": "That’s it! Please thank your driver but remember that your tip is included and no cash is necessary.", + "Trip started here": "Trip started here", + "Trip ended here": "Trip ended here", + "Sending Email": "Sending email...", + "Resend Email Succeeded": "We just sent the email. Please click on the confirmation link you recieve.", + "Resend Email Failed": "There was an error sending the email. Please contact support if the problem persists.", + "Resend Text Succeeded": 'We just sent the text message. Please reply "GO" to the message you recieve. It may take a few minutes for the message to reach you phone.', + "Resend Text Failed": "There was an error sending the text message. Please contact support if the problem persists.", + "Password Reset Error": "There was an error processing your password reset request.", + "New Password": "New Password", + "Forgot Password": "Forgot Password", + "Forgot Password Error": "Your email address could not be found. Please make sure to use the same email address you used when you signed up.", + "Forgot Password Success": "Please check your email for a link to reset your password.", + "Forgot Password Enter Email": 'Enter your email address and Uber will send you a link to reset your password. If you remember your password, you can sign in here.', + "Invite friends": "Invite friends", + "Give $ Get $": "Give $10, Get $10", + "Give $ Get $ Description": "Every friend you invite to Uber gets $10 of Uber credit. After someone you’ve invited takes his/her first ride, you get $10 of Uber credits too!", + "What are you waiting for?": "So, what are you waiting for? Invite away!", + "Tweet": "Tweet", + "Invite Link": "Email or IM this link to your friends:", + "Email Address": "Email Address", + "Reset Password": "Reset Password", + "Enter Promotion Code": "If you have a promotion code, enter it here:", + "Your Active Promotions": "Your Active Promotions", + "Code": "Code", + "Details": "Details", + "Trips Remaining": "Trips Remaining", + "Expires": "Expires", + "No Active Promotions": "There are no active promotions on your account.", + "Your Available Promotions": "Your Available Promotions", + "Where do you want us to pick you up?": "Where do you want us to pick you up?", + "Address to search": "Address to search", + "Search": "Search", + "Driver Name:": "Driver Name:", + "Driver #:": "Driver #:", + "Pickup Address:": "Pickup Address:", + "Add to Favorite Locations": "Add to Favorite Locations", + "Star": "Star", + "Nickname:": "Nickname:", + "Add": "Add", + "Your last trip": "Your last trip", + "Please rate your driver:": "Please rate your driver:", + "Comments: (optional)": "Comments: (optional)", + "Rate Trip": "Rate Trip", + "Pickup time:": "Pickup time:", + "Miles:": "Miles:", + "Trip time:": "Trip time:", + "Fare:": "Fare:", + "Favorite Locations": "Favorite Locations", + "Search Results": "Search Results", + "You have no favorite locations saved.": "You have no favorite locations saved.", + "Loading...": "Loading...", + "Request Pickup": "Request Pickup", + "Cancel Pickup": "Cancel Pickup", + "Requesting Closest Driver": "Requesting the closest driver to pick you up...", + "En Route": "You are currently en route...", + "Rate Last Trip": "Please rate your trip to make another request", + "Rate Before Submitting": "Please rate your trip before submitting the form", + "Address too short": "Address too short", + "or did you mean": "or did you mean", + "Search Address Failed": "Unable to find the given address. Please enter another address close to your location.", + "Sending pickup request...": "Sending pickup request...", + "Cancel Request Prompt": "Are you sure you want to cancel your request?", + "Cancel Request Arrived Prompt": 'Are you sure you want to cancel your request? Your driver has arrived so there is a $10 cancellation fee. It may help to call your driver now', + "Favorite Location Nickname Length Error": "Nickname has to be atleast 3 characters", + "Favorite Location Save Succeeded": "Location Saved!", + "Favorite Location Save Failed": "Unable to save your location. Please try again later.", + "Favorite Location Title": "Favorite Location <%= id %>", + "Search Location Title": "Search Location <%= id %>", + "ETA Message": "ETA: Around <%= minutes %> Minutes", + "Nearest Cab Message": "The closest driver is approximately <%= minutes %> minute(s) away", + "Arrival ETA Message": "Your Uber will arrive in about <%= minutes %> minute(s)", + "Arriving Now Message": "Your Uber is arriving now...", + "Rating Driver Failed": "Unable to contact server. Please try again later or email support if this issue persists.", + "Account Information": "Account Information", + "Mobile Phone Information": "Mobile Phone Information", + "settings": "settings", + "Information": "Information", + "Picture": "Picture", + "Change password": "Change password", + "Your current Picture": "Your current Picture", + "Your Favorite Locations": "Your Favorite Locations", + "You have no favorite locations saved.": "You have no favorite locations saved.", + "Purpose of Mobile": "We send text messages to your mobile phone to tell you when your driver is arriving. You can also request trips using text messages.", + "Country": "Country", + "Mobile Number": "Mobile Number", + "Submit": "Submit", + "Favorite Location": "Favorite Location", + "No Approximate Address": "Could not find an approximate address", + "Address:": "Address:", + "Information Update Succeeded": "Your information has been updated!", + "Information Update Failed": "We couldn't update your information. Please try again in few minutes or contact support if the problem persists.", + "Location Delete Succeeded": "Location deleted!", + "Location Delete Failed": "We were unable to delete your favorite location. Please try again later or contact support of the issue persists.", + "Location Edit Succeeded": "Changes Saved!", + "Location Edit Failed": "We couldn't save your changes. Please try again in a few minutes.", + "Picture Update Succeeded": "Your picture has been updated!", + "Picture Update Failed": "We couldn't change your picture. Please try again in a few minutes.", + "Personal Information": "Personal Information", + "Mobile Phone Number": "Mobile Phone Number", + "Payment Information": "Payment Information", + "Purpose of Credit Card": "We keep your credit card on file so that your trip go as fast as possible. You will not be charged until you take a trip.", + "Your card will not be charged until you take a trip.": "Your card will not be charged until you take a trip.", + "Credit Card Number": "Credit Card Number", + "Expiration Date": "Expiration Date", + "Promotion Code": "Promotion Code", + "Enter Promo Here": "If you have a code for a promotion, invitation or group deal, you can enter it here.", + "Promotion Code Input Label": "Promotion, Invite or Groupon Code (optional)", + "Terms and Conditions": "Terms and Conditions", + "HELP": "HELP", + "STOP": "STOP", + "Legal Information": "Legal Information", + "Sign Up Agreement": "By signing up, I agree to the Uber <%= terms_link %> and <%= privacy_link %> and understand that Uber is a request tool, not a transportation carrier.", + "Sign Up Agreement Error": "You must agree to the Uber Terms and Conditions and Privacy Policy to continue.", + "Message and Data Rates Disclosure": "Message and Data Rates May Apply. Reply <%= help_string %> to 827-222 for help. Reply <%= stop_string %> to 827-222 to stop texts. For additional assistance, visit support.uber.com or call (866) 576-1039. Supported Carriers: AT&T, Sprint, Verizon, and T-Mobile.", + "I Agree": "I agree to the Terms & Conditions and Privacy Policy", + "Security Code": "Security Code", + "Type of Card": "Type of Card", + "Personal": "Personal", + "Business": "Business", + "Code": "Code", + "Zip or Postal Code": "Zip or Postal Code", + "Your Trip": "Your Trip", + "Trip Info": "Trip Info", + "Request a fare review": "Request a fare review", + "Fare Review Submitted": "Your fare review has been submitted. We'll get back to you soon about your request. Sorry for any inconvenience this may have caused!", + "Fair Price Consideration": "We're committed to delivering Uber service at a fair price. Before requesting a fare review, please consider:", + "Your Fare Calculation": "Your Fare Calculation", + "Charges": "Charges", + "Discounts": "Discounts", + "Total Charge": "Total Charge", + "Uber pricing information": "Uber pricing information", + "Uber Pricing Information Message": "<%= learn_link %> is published on our website.", + "GPS Point Capture Disclosure": "Due to a finite number of GPS point captures, corners on your trip map may appear cut off or rounded. These minor inaccuracies result in a shorter measured distance, which always results in a cheaper trip.", + "Fare Review Note": "Please elaborate on why this trip requires a fare review. Your comments below will help us better establish the correct price for your trip:", + "Fare Review Error": "There was an error submitting the review. Please ensure that you have a message.", + "Sign In": "Sign In" + }; +}).call(this); +}, "translations/fr": function(exports, require, module) {(function() { + exports.translations = { + "Uber": "Uber", + "Sign Up": "Inscription", + "Ride Request": "Passer une Commande", + "Invite Friends": "Inviter vos Amis", + "Promotions": "Promotions", + "Billing": "Paiement", + "Settings": "Paramètres", + "Forgot Password?": "Mot de passe oublié ?", + "Password Recovery": "Récupération du mot de passe", + "Login": "Connexion", + "Trip Detail": "Détail de la Course", + "Password Reset": "Réinitialisation du mot de passe", + "Confirm Email": "Confirmation de l’e-mail", + "Request Ride": "Passer une Commande", + "Credit Card Number": "Numéro de Carte de Crédit", + "month": "mois", + "01-Jan": "01-Jan", + "02-Feb": "02-Fév", + "03-Mar": "03-Mar", + "04-Apr": "04-Avr", + "05-May": "05-Mai", + "06-Jun": "06-Juin", + "07-Jul": "07-Jui", + "08-Aug": "08-Aoû", + "09-Sep": "09-Sep", + "10-Oct": "10-Oct", + "11-Nov": "11-Nov", + "12-Dec": "12-Déc", + "year": "année", + "CVV": "Code de Sécurité", + "Category": "Type", + "personal": "personnel", + "business": "entreprise", + "Default Credit Card": "Carte par Défaut", + "Add Credit Card": "Ajouter une Carte", + "Expiry": "Expire", + "default card": "carte par défaut", + "make default": "choisir par défaut", + "Edit": "Modifier", + "Delete": "Supprimer", + "Expiry Month": "Mois d’Expiration", + "Expiry Year": "Année d’Expiration", + "Unable to Verify Card": "Impossible de vérifier la carte pour le moment. Merci de réessayer un peu plus tard.", + "Credit Card Update Succeeded": "Votre carte a été mise à jour avec succès !", + "Credit Card Update Failed": "Nous ne pouvons enregistrer vos changements. Merci de réessayer dans quelques minutes.", + "Credit Card Delete Succeeded": "Votre carte a été supprimée !", + "Credit Card Delete Failed": "Nous n’avons pas été en mesure de supprimer votre carte. Merci de réessayer plus tard.", + "Credit Card Update Category Succeeded": "Changement de catégorie de carte réussi !", + "Credit Card Update Category Failed": "Nous ne pouvons pas changer la catégorie de votre carte. Merci de réessayer dans quelques minutes.", + "Credit Card Update Default Succeeded": "Carte par défaut changée avec succès !", + "Credit Card Update Default Failed": "Nous ne pouvons pas changer votre carte par défaut. Merci de réessayer dans quelques minutes.", + "Hello Greeting": "Bonjour, <%= name %>", + "Card Ending in": "La carte expire dans", + "Trip Map": "Carte des Courses", + "Amount": "Montant: <%= amount %>", + "Last Attempt to Bill": "Dernière tentative de prélèvement : <%= date %>", + "Charge": "Débit", + "Uber Credit Balance Note": "Votre compte a un solde de <%= amount %> UberCredits. Lorsque nous facturons des courses, nous réduirons votre solde d’UberCredits avant de prélever votre carte de crédit.", + "Please Add Credit Card": "Merci d’ajouter une carte de crédit pour que nous puissions vous facturer.", + "Credit Cards": "Cartes de crédit", + "add a new credit card": "Ajouter une nouvelle carte de crédit", + "Account Balance": "Solde du compte", + "Arrears": "Arriérés", + "Billing Succeeded": "Votre carte a été correctement débitée.", + "Confirm Email Succeeded": "L’adresse e-mail a bien été validée, vous êtes redirigé vers le tableau de bord...", + "Confirm Email Failed": "Impossible de confirmer l’adresse e-mail. Merci de contacter support@uber.com si le problème persiste.", + "Credit Card Added": "Carte de crédit ajoutée", + "No Credit Card": "Pas de carte de crédit", + "Mobile Number Confirmed": "Numéro de téléphone confirmé", + "No Confirmed Mobile": "Pas de numéro de téléphone confirmé", + "E-mail Address Confirmed": "Adresse e-mail confirmée", + "No Confirmed E-mail": "Pas d’adresse e-mail confirmée", + 'Reply to sign up text': 'Répondre "GO" au SMS que vous avez reçu à l’inscription.', + "Resend text message": "Renvoyer le SMS", + "Click sign up link": "Cliquez sur le lien contenu dans l’e-mail reçu à l’inscription.", + "Resend email": "Renvoyer l’e-mail", + "Add a credit card to ride": "Ajouter une carte de crédit et vous serez prêt à voyager avec Uber.", + "Your Most Recent Trip": "Votre course la plus récente", + "details": "détails", + "Your Trip History": "Historique de votre trajet", + "Status": "Statut", + "Here's how it works:": "Voici comment ça marche :", + "Show all trips": "Montrer toutes les courses", + "Set your location:": "Définir votre position :", + "App search for address": "Application iPhone/Android : positionner la punaise ou rechercher une adresse", + "SMS text address": "SMS : envoyez votre adresse à UBRCAB (827222)", + "Confirm pickup request": "Validez la commande", + "Uber sends ETA": "Uber envoie un temps d’attente estimé (habituellement entre 5 et 10 minutes)", + "Car arrives": "Lorsque votre voiture arrive, Uber vous en informera encore..", + "Ride to destination": "Montez dans la voiture et donnez votre destination au chauffeur.", + "Thank your driver": "C’est tout ! Remerciez le chauffeur mais souvenez-vous que les pourboires sont compris et qu’il n’est pas nécessaire d’avoir du liquide sur soi.", + "Trip started here": "La course a commencé ici.", + "Trip ended here": "La course s’est terminée ici.", + "Sending Email": "Envoi de l’e-mail...", + "Resend Email Succeeded": "Nous venons d’envoyer l’e-mail. Merci de cliquer sur le lien de confirmation que vous avez reçu.", + "Resend Email Failed": "Il y a eu un problème lors de l’envoi de l’email. Merci de contacter le support si le problème persiste.", + "Resend Text Succeeded": 'Nous venons d’envoyer le SMS. Merci de répondre "GO" au message que vous avez reçu. Il se peut que cela prenne quelques minutes pour que le message arrive sur votre téléphone.', + "Resend Text Failed": "Il y a eu un problème lors de l’envoi du SMS. Merci de contacter le support si le problème persiste.", + "Password Reset Error": "Il y a eu une error lors de la réinitialisation de votre mot de passe.", + "New Password:": "Nouveau mot de passe:", + "Forgot Password Error": "Votre nom d’utilisateur / adresse email ne peut être trouvé. Merci d’utiliser la même qu’à l’inscription.", + "Forgot Password Success": "Merci de consulter votre boîte mail pour suivre la demande de ‘réinitialisation de mot de passe.", + "Forgot Password Enter Email": "Merci de saisir votre adresse email et nous vous enverrons un lien vous permettant de réinitialiser votre mot de passe :", + "Invite friends": "Inviter vos amis", + "Give $ Get $": "Donnez $10, Recevez $10", + "Give $ Get $ Description": "Chaque ami que vous invitez à Uber recevra $10 de crédits Uber. Dès lors qu’une personne que vous aurez invité aura utilisé Uber pour la première, vous recevrez $10 de crédits Uber également !", + "What are you waiting for?": "N’attendez plus ! Lancez les invitations !", + "Tweet": "Tweeter", + "Invite Link": "Envoyez ce lien par email ou messagerie instantanée à vos amis :", + "Enter Promotion Code": "Si vous avez un code promo, saisissez-le ici:", + "Your Active Promotions": "Vos Codes Promos Actifs", + "Code": "Code", + "Details": "Détails", + "Trips Remaining": "Courses restantes", + "Expires": "Expire", + "No Active Promotions": "Vous n’avez pas de code promo actif.", + "Your Available Promotions": "Votres Promos Disponibles", + "Where do you want us to pick you up?": "Où souhaitez-vous que nous vous prenions en charge ?", + "Address to search": "Adresse à rechercher", + "Search": "Chercher", + "Driver Name:": "Nom du chauffeur:", + "Driver #:": "# Chauffeur:", + "Pickup Address:": "Lieu de prise en charge:", + "Add to Favorite Locations": "Ajoutez aux Lieux Favoris", + "Star": "Étoiles", + "Nickname:": "Pseudo", + "Add": "Ajouter", + "Your last trip": "Votre dernière course", + "Please rate your driver:": "Merci de noter votre chauffeur :", + "Comments: (optional)": "Commentaires: (optionnel)", + "Rate Trip": "Notez votre course", + "Pickup time:": "Heure de Prise en Charge :", + "Miles:": "Kilomètres :", + "Trip time:": "Temps de course :", + "Fare:": "Tarif :", + "Favorite Locations": "Lieux Favoris", + "Search Results": "Résultats", + "You have no favorite locations saved.": "Vous n’avez pas de lieux de prise en charge favoris.", + "Loading...": "Chargement...", + "Request Pickup": "Commander ici", + "Cancel Pickup": "Annuler", + "Requesting Closest Driver": "Nous demandons au chauffeur le plus proche de vous prendre en charge...", + "En Route": "Vous êtes actuellement en route...", + "Rate Last Trip": "Merci de noter votre précédent trajet pour faire une autre course.", + "Rate Before Submitting": "Merci de noter votre trajet avant de le valider.", + "Address too short": "L’adresse est trop courte", + "or did you mean": "ou vouliez-vous dire", + "Search Address Failed": "Impossible de trouver l’adresse spécifiée. Merci de saisir une autre adresse proche de l’endroit où vous vous trouvez.", + "Sending pickup request...": "Envoi de la demande de prise en charge...", + "Cancel Request Prompt": "Voulez-vous vraiment annuler votre demande ?", + "Cancel Request Arrived Prompt": 'Voulez-vous vraiment annuler votre demande ? Votre chauffeur est arrivé, vous serez donc facturé de $10 de frais d’annulation. Il pourrait être utile que vous appeliez votre chauffeur maintenant.', + "Favorite Location Nickname Length Error": "Le pseudo doit faire au moins 3 caractères de long", + "Favorite Location Save Succeeded": "Adresse enregistrée !", + "Favorite Location Save Failed": "Impossible d’enregistrer votre adresse. Merci de réessayer ultérieurement.", + "Favorite Location Title": "Adresse favorie <%= id %>", + "Search Location Title": "Recherche d’adresse <%= id %>", + "ETA Message": "Temps d’attente estimé: environ <%= minutes %> minutes", + "Nearest Cab Message": "Le chauffeur le plus proche sera là dans <%= minutes %> minute(s)", + "Arrival ETA Message": "Votre chauffeur arrivera dans <%= minutes %> minute(s)", + "Arriving Now Message": "Votre chauffeur est en approche...", + "Rating Driver Failed": "Impossible de contacter le serveur. Merci de réessayer ultérieurement ou de contacter le support si le problème persiste.", + "settings": "Paramètres", + "Information": "Information", + "Picture": "Photo", + "Change password": "Modifier votre mot de passe", + "Your current Picture": "Votre photo", + "Your Favorite Locations": "Vos lieux favoris", + "You have no favorite locations saved.": "Vous n’avez pas de lieu favori", + "Account Information": "Informations Personnelles", + "Mobile Phone Information": "Informations de Mobile", + "Change Your Password": "Changez votre mot de passe.", + "Country": "Pays", + "Language": "Langue", + "Favorite Location": "Lieu favori", + "No Approximate Address": "Impossible de trouver une adresse même approximative", + "Address:": "Adresse :", + "Information Update Succeeded": "Vos informations ont été mises à jour !", + "Information Update Failed": "Nous n’avons pas pu mettre à jour vos informations. Merci de réessayer dans quelques instants ou de contacter le support si le problème persiste.", + "Location Delete Succeeded": "Adresse supprimée !", + "Location Delete Failed": "Nous n’avons pas pu supprimée votre adresse favorie. Merci de réessayer plus tard ou de contacter le support si le problème persiste.", + "Location Edit Succeeded": "Modifications sauvegardées !", + "Location Edit Failed": "Nous n’avons pas pu sauvegarder vos modifications. Merci de réessayer dans quelques minutes.", + "Picture Update Succeeded": "Votre photo a été mise à jour !", + "Picture Update Failed": "Nous n’avons pas pu mettre à jour votre photo. Merci de réessayer dans quelques instants.", + "Personal Information": "Informations Personnelles", + "Mobile Phone Number": "Numéro de Téléphone Portable", + "Payment Information": "Informations de Facturation", + "Your card will not be charged until you take a trip.": "Votre carte ne sera pas débitée avant votre premier trajet.", + "Card Number": "Numéro de Carte", + "Promotion Code Input Label": "Code promo, code d’invitation ou “deal” acheté en ligne (optionnel)", + "Terms and Conditions": "Conditions Générales", + "HELP": "HELP", + "STOP": "STOP", + "Sign Up Agreement": "En souscrivant, j’accepte les <%= terms_link %> et <%= privacy_link %> et comprends qu’Uber est un outil de commande de chauffeur, et non un transporteur.", + "Sign Up Agreement Error": "Vous devez accepter les Conditions Générales d’utilisation d’Uber Terms and Conditions et la Politique de Confidentialité pour continuer.", + "Message and Data Rates Disclosure": "Les frais d’envoi de SMS et de consommation de données peuvent s’appliquer. Répondez <%= help_string %> au 827-222 pour obtenir de l’aide. Répondez <%= stop_string %> au 827-222 pour ne plus recevoir de SMS. Pour plus d’aide, visitez support.uber.com ou appelez le (866) 576-1039. Opérateurs supportés: AT&T, Sprint, Verizon, T-Mobile, Orange, SFR et Bouygues Telecom.", + "Zip/Postal Code": "Code Postal", + "Expiration Date": "Date D'expiration", + "Security Code": "Code de Sécurité", + "Type of Card": "Type", + "Personal": "Personnel", + "Business": "Entreprise", + "Promotion Code": "Code Promo", + "Legal Information": "Mentions Légales", + "I Agree": "J'accepte.", + "Your Trip": "Votre Course", + "Trip Info": "Informations de la Course", + "Request a fare review": "Demander un contrôle du tarif", + "Fare Review Submitted": "Votre demande de contrôle du tarif a été soumis. Nous reviendrons vers vous rapidement concernant cette demande. Nous nous excusons pour les dérangements éventuellement occasionnés !", + "Fair Price Consideration": "Nous nous engageons à proposer Uber à un tarif juste. Avant de demander un contrôle du tarif, merci de prendre en compte :", + "Your Fare Calculation": "Calcul du Prix", + "Charges": "Coûts", + "Discounts": "Réductions", + "Total Charge": "Coût total", + "Uber pricing information": "Information sur les prix d’Uber", + "Uber Pricing Information Message": "<%= learn_link %> est disponible sur notre site web.", + "GPS Point Capture Disclosure": "A cause d’un nombre limité de coordonnées GPS sauvegardées, les angles de votre trajet sur la carte peuvent apparaître coupés ou arrondis. Ces légères incohérences débouchent sur des distances mesurées plus courtes, ce qui implique toujours un prix du trajet moins élevé.", + "Fare Review Note": "Merci de nous expliquer pourquoi le tarif de cette course nécessite d’être contrôlé. Vos commentaires ci-dessous nous aideront à établir un prix plus juste si nécessaire :", + "Fare Review Error": "Il y a eu une erreur lors de l’envoi de la demande. Assurez-vous d’avoir bien ajouté une description à votre demande." + }; +}).call(this); +}, "views/clients/billing": function(exports, require, module) {(function() { + var clientsBillingTemplate; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + clientsBillingTemplate = require('templates/clients/billing'); + exports.ClientsBillingView = (function() { + __extends(ClientsBillingView, UberView); + function ClientsBillingView() { + ClientsBillingView.__super__.constructor.apply(this, arguments); + } + ClientsBillingView.prototype.id = 'billing_view'; + ClientsBillingView.prototype.className = 'view_container'; + ClientsBillingView.prototype.events = { + 'click a#add_card': 'addCard', + 'click .charge_arrear': 'chargeArrear' + }; + ClientsBillingView.prototype.render = function() { + this.RefreshUserInfo(__bind(function() { + var cards, newForm; + this.HideSpinner(); + $(this.el).html(clientsBillingTemplate()); + if (USER.payment_gateway.payment_profiles.length === 0) { + newForm = new app.views.clients.modules.creditcard; + $(this.el).find("#add_card_wrapper").html(newForm.render(0).el); + } else { + cards = new app.views.clients.modules.creditcard; + $("#cards").html(cards.render("all").el); + } + return this.delegateEvents(); + }, this)); + return this; + }; + ClientsBillingView.prototype.addCard = function(e) { + var newCard; + e.preventDefault(); + newCard = new app.views.clients.modules.creditcard; + $('#cards').append(newCard.render("new").el); + return $("a#add_card").hide(); + }; + ClientsBillingView.prototype.chargeArrear = function(e) { + var $el, arrearId, attrs, cardId, options, tryCharge; + e.preventDefault(); + $(".error_message").text(""); + $el = $(e.currentTarget); + arrearId = $el.attr('id'); + cardId = $el.parent().find('#card_to_charge').val(); + this.ShowSpinner('submit'); + tryCharge = new app.models.clientbills({ + id: arrearId + }); + attrs = { + payment_profile_id: cardId, + dataType: 'json' + }; + options = { + success: __bind(function(data, textStatus, jqXHR) { + $el.parent().find(".success_message").text(t("Billing Succeeded")); + $el.hide(); + return $el.parent().find('#card_to_charge').hide(); + }, this), + error: __bind(function(jqXHR, status, errorThrown) { + return $el.parent().find(".error_message").text(JSON.parse(status.responseText).error); + }, this), + complete: __bind(function() { + return this.HideSpinner(); + }, this) + }; + return tryCharge.save(attrs, options); + }; + return ClientsBillingView; + })(); +}).call(this); +}, "views/clients/confirm_email": function(exports, require, module) {(function() { + var clientsConfirmEmailTemplate; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + clientsConfirmEmailTemplate = require('templates/clients/confirm_email'); + exports.ClientsConfirmEmailView = (function() { + __extends(ClientsConfirmEmailView, UberView); + function ClientsConfirmEmailView() { + ClientsConfirmEmailView.__super__.constructor.apply(this, arguments); + } + ClientsConfirmEmailView.prototype.id = 'confirm_email_view'; + ClientsConfirmEmailView.prototype.className = 'view_container'; + ClientsConfirmEmailView.prototype.render = function(token) { + var attrs; + $(this.el).html(clientsConfirmEmailTemplate()); + attrs = { + data: { + email_token: token + }, + success: __bind(function(data, textStatus, jqXHR) { + var show_dashboard; + this.HideSpinner(); + show_dashboard = function() { + return app.routers.clients.navigate('!/dashboard', true); + }; + if (data.status === 'OK') { + $('.success_message').show(); + return _.delay(show_dashboard, 3000); + } else if (data.status === 'ALREADY_COMFIRMED') { + $('.already_confirmed_message').show(); + return _.delay(show_dashboard, 3000); + } else { + return $('.error_message').show(); + } + }, this), + error: __bind(function(e) { + this.HideSpinner(); + return $('.error_message').show(); + }, this), + complete: function(status) { + return $('#attempt_text').hide(); + }, + dataType: 'json', + type: 'PUT', + url: "" + API + "/users/self" + }; + $.ajax(attrs); + this.ShowSpinner('submit'); + return this; + }; + return ClientsConfirmEmailView; + })(); +}).call(this); +}, "views/clients/dashboard": function(exports, require, module) {(function() { + var clientsDashboardTemplate; + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + clientsDashboardTemplate = require('templates/clients/dashboard'); + exports.ClientsDashboardView = (function() { + var displayFirstTrip; + __extends(ClientsDashboardView, UberView); + function ClientsDashboardView() { + this.showAllTrips = __bind(this.showAllTrips, this); + this.render = __bind(this.render, this); + ClientsDashboardView.__super__.constructor.apply(this, arguments); + } + ClientsDashboardView.prototype.id = 'dashboard_view'; + ClientsDashboardView.prototype.className = 'view_container'; + ClientsDashboardView.prototype.events = { + 'click a.confirmation': 'confirmationClick', + 'click #resend_email': 'resendEmail', + 'click #resend_mobile': 'resendMobile', + 'click #show_all_trips': 'showAllTrips' + }; + ClientsDashboardView.prototype.render = function() { + var displayPage, downloadTrips; + this.HideSpinner(); + displayPage = __bind(function() { + $(this.el).html(clientsDashboardTemplate()); + this.confirmationsSetup(); + return this.RequireMaps(__bind(function() { + if (USER.trips.models[0]) { + if (!USER.trips.models[0].get("points")) { + return USER.trips.models[0].fetch({ + data: { + relationships: 'points' + }, + success: __bind(function() { + this.CacheData("USERtrips", USER.trips); + return displayFirstTrip(); + }, this) + }); + } else { + return displayFirstTrip(); + } + } + }, this)); + }, this); + downloadTrips = __bind(function() { + return this.DownloadUserTrips(displayPage, false, 10); + }, this); + this.RefreshUserInfo(downloadTrips); + return this; + }; + displayFirstTrip = __bind(function() { + var bounds, endPos, map, myOptions, path, polyline, startPos; + myOptions = { + zoom: 12, + mapTypeId: google.maps.MapTypeId.ROADMAP, + zoomControl: false, + rotateControl: false, + panControl: false, + mapTypeControl: false, + scrollwheel: false + }; + if (USER.trips.length === 10) { + $("#show_all_trips").show(); + } + if (USER.trips.length > 0) { + map = new google.maps.Map(document.getElementById("trip_details_map"), myOptions); + bounds = new google.maps.LatLngBounds(); + path = []; + _.each(USER.trips.models[0].get('points'), __bind(function(point) { + path.push(new google.maps.LatLng(point.lat, point.lng)); + return bounds.extend(_.last(path)); + }, this)); + map.fitBounds(bounds); + startPos = new google.maps.Marker({ + position: _.first(path), + map: map, + title: t('Trip started here'), + icon: 'https://uber-static.s3.amazonaws.com/marker_start.png' + }); + endPos = new google.maps.Marker({ + position: _.last(path), + map: map, + title: t('Trip ended here'), + icon: 'https://uber-static.s3.amazonaws.com/marker_end.png' + }); + polyline = new google.maps.Polyline({ + path: path, + strokeColor: '#003F87', + strokeOpacity: 1, + strokeWeight: 5 + }); + return polyline.setMap(map); + } + }, ClientsDashboardView); + ClientsDashboardView.prototype.confirmationsSetup = function() { + var blink, cardForm, element, _ref, _ref2, _ref3, _ref4, _ref5; + blink = function(element) { + var opacity; + opacity = 0.5; + if (element.css('opacity') === "0.5") { + opacity = 1.0; + } + return element.fadeTo(2000, opacity, function() { + return blink(element); + }); + }; + if (((_ref = window.USER) != null ? (_ref2 = _ref.payment_gateway) != null ? (_ref3 = _ref2.payment_profiles) != null ? _ref3.length : void 0 : void 0 : void 0) === 0) { + element = $('#confirmed_credit_card'); + cardForm = new app.views.clients.modules.creditcard; + $('#card.info').append(cardForm.render().el); + blink(element); + } + if (((_ref4 = window.USER) != null ? _ref4.confirm_email : void 0) === false) { + element = $('#confirmed_email'); + blink(element); + } + if ((((_ref5 = window.USER) != null ? _ref5.confirm_mobile : void 0) != null) === false) { + element = $('#confirmed_mobile'); + return blink(element); + } + }; + ClientsDashboardView.prototype.confirmationClick = function(e) { + e.preventDefault(); + $('.info').hide(); + $('#more_info').show(); + switch (e.currentTarget.id) { + case "card": + return $('#card.info').slideToggle(); + case "mobile": + return $('#mobile.info').slideToggle(); + case "email": + return $('#email.info').slideToggle(); + } + }; + ClientsDashboardView.prototype.resendEmail = function(e) { + var $el; + e.preventDefault(); + $el = $(e.currentTarget); + $el.removeAttr('href').prop({ + disabled: true + }); + $el.html(t("Sending Email")); + return $.ajax({ + type: 'GET', + url: API + '/users/request_confirm_email', + data: { + token: USER.token + }, + dataType: 'json', + success: __bind(function(data, textStatus, jqXHR) { + return $el.html(t("Resend Email Succeeded")); + }, this), + error: __bind(function(jqXHR, textStatus, errorThrown) { + return $el.html(t("Resend Email Failed")); + }, this) + }); + }; + ClientsDashboardView.prototype.resendMobile = function(e) { + var $el; + e.preventDefault(); + $el = $(e.currentTarget); + $el.removeAttr('href').prop({ + disabled: true + }); + $el.html("Sending message..."); + return $.ajax({ + type: 'GET', + url: API + '/users/request_confirm_mobile', + data: { + token: USER.token + }, + dataType: 'json', + success: __bind(function(data, textStatus, jqXHR) { + return $el.html(t("Resend Text Succeeded")); + }, this), + error: __bind(function(jqXHR, textStatus, errorThrown) { + return $el.html(t("Resend Text Failed")); + }, this) + }); + }; + ClientsDashboardView.prototype.showAllTrips = function(e) { + e.preventDefault(); + $(e.currentTarget).hide(); + return this.DownloadUserTrips(this.render, true, 1000); + }; + return ClientsDashboardView; + }).call(this); +}).call(this); +}, "views/clients/forgot_password": function(exports, require, module) {(function() { + var clientsForgotPasswordTemplate; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + clientsForgotPasswordTemplate = require('templates/clients/forgot_password'); + exports.ClientsForgotPasswordView = (function() { + __extends(ClientsForgotPasswordView, UberView); + function ClientsForgotPasswordView() { + ClientsForgotPasswordView.__super__.constructor.apply(this, arguments); + } + ClientsForgotPasswordView.prototype.id = 'forgotpassword_view'; + ClientsForgotPasswordView.prototype.className = 'view_container modal_view_container'; + ClientsForgotPasswordView.prototype.events = { + "submit #password_reset": "passwordReset", + "click #password_reset_submit": "passwordReset", + "submit #forgot_password": "forgotPassword", + "click #forgot_password_submit": "forgotPassword" + }; + ClientsForgotPasswordView.prototype.render = function(token) { + this.HideSpinner(); + $(this.el).html(clientsForgotPasswordTemplate({ + token: token + })); + this.delegateEvents(); + return this; + }; + ClientsForgotPasswordView.prototype.forgotPassword = function(e) { + var attrs; + e.preventDefault(); + $('.success_message').hide(); + $(".error_message").hide(); + attrs = { + data: { + login: $("#login").val() + }, + success: __bind(function(data, textStatus, jqXHR) { + this.HideSpinner(); + $('.success_message').show(); + return $("#forgot_password").hide(); + }, this), + error: __bind(function(e) { + this.HideSpinner(); + return $('.error_message').show(); + }, this), + dataType: 'json', + type: 'PUT', + url: "" + API + "/users/forgot_password" + }; + $.ajax(attrs); + return this.ShowSpinner('submit'); + }; + ClientsForgotPasswordView.prototype.passwordReset = function(e) { + var attrs; + e.preventDefault(); + attrs = { + data: { + email_token: $("#token").val(), + password: $("#password").val() + }, + success: __bind(function(data, textStatus, jqXHR) { + this.HideSpinner(); + $.cookie('token', data.token); + amplify.store('USERjson', data); + app.refreshMenu(); + return location.hash = '!/dashboard'; + }, this), + error: __bind(function(e) { + this.HideSpinner(); + return $('#error_reset').show(); + }, this), + dataType: 'json', + type: 'PUT', + url: "" + API + "/users/self" + }; + $.ajax(attrs); + return this.ShowSpinner('submit'); + }; + return ClientsForgotPasswordView; + })(); +}).call(this); +}, "views/clients/invite": function(exports, require, module) {(function() { + var clientsInviteTemplate; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + clientsInviteTemplate = require('templates/clients/invite'); + exports.ClientsInviteView = (function() { + __extends(ClientsInviteView, UberView); + function ClientsInviteView() { + ClientsInviteView.__super__.constructor.apply(this, arguments); + } + ClientsInviteView.prototype.id = 'invite_view'; + ClientsInviteView.prototype.className = 'view_container'; + ClientsInviteView.prototype.render = function() { + this.ReadUserInfo(); + this.HideSpinner(); + $(this.el).html(clientsInviteTemplate()); + console.log(screen); + return this; + }; + return ClientsInviteView; + })(); +}).call(this); +}, "views/clients/login": function(exports, require, module) {(function() { + var clientsLoginTemplate; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + clientsLoginTemplate = require('templates/clients/login'); + exports.ClientsLoginView = (function() { + __extends(ClientsLoginView, UberView); + function ClientsLoginView() { + ClientsLoginView.__super__.constructor.apply(this, arguments); + } + ClientsLoginView.prototype.id = 'login_view'; + ClientsLoginView.prototype.className = 'view_container modal_view_container'; + ClientsLoginView.prototype.events = { + 'submit form': 'authenticate', + 'click button': 'authenticate' + }; + ClientsLoginView.prototype.initialize = function() { + _.bindAll(this, 'render'); + return this.render(); + }; + ClientsLoginView.prototype.render = function() { + this.HideSpinner(); + $(this.el).html(clientsLoginTemplate()); + this.delegateEvents(); + return this.place(); + }; + ClientsLoginView.prototype.authenticate = function(e) { + e.preventDefault(); + return $.ajax({ + type: 'POST', + url: API + '/auth/web_login/client', + data: { + login: $("#login").val(), + password: $("#password").val() + }, + dataType: 'json', + success: function(data, textStatus, jqXHR) { + $.cookie('user', JSON.stringify(data)); + $.cookie('token', data.token); + amplify.store('USERjson', data); + $('header').html(app.views.shared.menu.render().el); + return app.routers.clients.navigate('!/dashboard', true); + }, + error: function(jqXHR, textStatus, errorThrown) { + $.cookie('user', null); + $.cookie('token', null); + if (jqXHR.status === 403) { + $.cookie('redirected_user', JSON.stringify(JSON.parse(jqXHR.responseText).error_obj), { + domain: '.uber.com' + }); + window.location = 'http://partners.uber.com/'; + } + return $('.error_message').html(JSON.parse(jqXHR.responseText).error).hide().fadeIn(); + } + }); + }; + return ClientsLoginView; + })(); +}).call(this); +}, "views/clients/modules/credit_card": function(exports, require, module) {(function() { + var creditCardTemplate; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + creditCardTemplate = require('templates/clients/modules/credit_card'); + exports.CreditCardView = (function() { + __extends(CreditCardView, UberView); + function CreditCardView() { + CreditCardView.__super__.constructor.apply(this, arguments); + } + CreditCardView.prototype.id = 'creditcard_view'; + CreditCardView.prototype.className = 'module_container'; + CreditCardView.prototype.events = { + 'submit #credit_card_form': 'processNewCard', + 'click #new_card': 'processNewCard', + 'change #card_number': 'showCardType', + 'click .edit_card_show': 'showEditCard', + 'click .edit_card': 'editCard', + 'click .delete_card': 'deleteCard', + 'click .make_default': 'makeDefault', + 'change .use_case': 'saveUseCase' + }; + CreditCardView.prototype.initialize = function() { + return app.collections.paymentprofiles.bind("refresh", __bind(function() { + return this.RefreshUserInfo(__bind(function() { + this.render("all"); + return this.HideSpinner(); + }, this)); + }, this)); + }; + CreditCardView.prototype.render = function(cards) { + if (cards == null) { + cards = "new"; + } + if (cards === "all") { + app.collections.paymentprofiles.reset(USER.payment_gateway.payment_profiles); + cards = app.collections.paymentprofiles; + } + $(this.el).html(creditCardTemplate({ + cards: cards + })); + return this; + }; + CreditCardView.prototype.processNewCard = function(e) { + var $el, attrs, model, options; + e.preventDefault(); + this.ClearGlobalStatus(); + $el = $("#credit_card_form"); + $el.find('.error_message').html(""); + attrs = { + card_number: $el.find('#card_number').val(), + card_code: $el.find('#card_code').val(), + card_expiration_month: $el.find('#card_expiration_month').val(), + card_expiration_year: $el.find('#card_expiration_year').val(), + use_case: $el.find('#use_case').val(), + "default": $el.find('#default_check').prop("checked") + }; + options = { + statusCode: { + 200: __bind(function(e) { + this.HideSpinner(); + $('#cc_form_wrapper').hide(); + app.collections.paymentprofiles.trigger("refresh"); + $(this.el).remove(); + $("a#add_card").show(); + return $('section').html(app.views.clients.billing.render().el); + }, this), + 406: __bind(function(e) { + var error, errors, _i, _len, _ref, _results; + this.HideSpinner(); + errors = JSON.parse(e.responseText); + _ref = _.keys(errors); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + error = _ref[_i]; + _results.push(error === "top_of_form" ? $("#top_of_form").html(errors[error]) : $("#credit_card_form").find("#" + error).parent().find(".error_message").html(errors[error])); + } + return _results; + }, this), + 420: __bind(function(e) { + this.HideSpinner(); + return $("#top_of_form").html(t("Unable to Verify Card")); + }, this) + } + }; + this.ShowSpinner("submit"); + model = new app.models.paymentprofile; + model.save(attrs, options); + return app.collections.paymentprofiles.add(model); + }; + CreditCardView.prototype.showCardType = function(e) { + var $el, reAmerica, reDiscover, reMaster, reVisa, validCard; + reVisa = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/; + reMaster = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/; + reAmerica = /^6011-?\d{4}-?\d{4}-?\d{4}$/; + reDiscover = /^3[4,7]\d{13}$/; + $el = $("#card_logos"); + validCard = false; + if (e.currentTarget.value.match(reVisa)) { + validCard = true; + } else if (e.currentTarget.value.match(reMaster)) { + $el.css('background-position', "-60px"); + validCard = true; + } else if (e.currentTarget.value.match(reAmerica)) { + $el.css('background-position', "-120px"); + validCard = true; + } else if (e.currentTarget.value.match(reDiscover)) { + $el.css('background-position', "-180px"); + validCard = true; + } + if (validCard) { + $el.css('width', "60px"); + return $el.css('margin-left', "180px"); + } else { + $el.css('width', "250px"); + return $el.css('margin-left', "80px"); + } + }; + CreditCardView.prototype.showEditCard = function(e) { + var $el, id; + e.preventDefault(); + $el = $(e.currentTarget); + if ($el.html() === t("Edit")) { + id = $el.html(t("Cancel")).parents("tr").attr("id").substring(1); + return $("#e" + id).show(); + } else { + id = $el.html(t("Edit")).parents("tr").attr("id").substring(1); + return $("#e" + id).hide(); + } + }; + CreditCardView.prototype.editCard = function(e) { + var $el, attrs, id, options; + e.preventDefault(); + this.ClearGlobalStatus(); + $el = $(e.currentTarget).parents("td"); + id = $el.parents("tr").attr("id").substring(1); + $el.attr('disabled', 'disabled'); + this.ShowSpinner('submit'); + attrs = { + card_expiration_month: $el.find('#card_expiration_month').val(), + card_expiration_year: $el.find('#card_expiration_year').val(), + card_code: $el.find('#card_code').val() + }; + options = { + success: __bind(function(response) { + this.HideSpinner(); + this.ShowSuccess(t("Credit Card Update Succeeded")); + $("#e" + id).hide(); + $("#d" + id).find(".edit_card_show").html(t("Edit")); + return app.collections.paymentprofiles.trigger("refresh"); + }, this), + error: __bind(function(e) { + this.HideSpinner(); + this.ShowError(t("Credit Card Update Failed")); + return $el.removeAttr('disabled'); + }, this) + }; + app.collections.paymentprofiles.models[id].set(attrs); + return app.collections.paymentprofiles.models[id].save({}, options); + }; + CreditCardView.prototype.deleteCard = function(e) { + var $el, id, options; + e.preventDefault(); + $el = $(e.currentTarget).parents("td"); + id = $el.parents("tr").attr("id").substring(1); + this.ClearGlobalStatus(); + this.ShowSpinner('submit'); + options = { + success: __bind(function(response) { + this.ShowSuccess(t("Credit Card Delete Succeeded")); + $("form").hide(); + app.collections.paymentprofiles.trigger("refresh"); + return $('section').html(app.views.clients.billing.render().el); + }, this), + error: __bind(function(xhr, e) { + this.HideSpinner(); + return this.ShowError(t("Credit Card Delete Failed")); + }, this) + }; + return app.collections.paymentprofiles.models[id].destroy(options); + }; + CreditCardView.prototype.saveUseCase = function(e) { + var $el, attrs, id, options, use_case; + this.ClearGlobalStatus(); + $el = $(e.currentTarget); + use_case = $el.val(); + id = $el.parents("tr").attr("id").substring(1); + attrs = { + use_case: use_case + }; + options = { + success: __bind(function(response) { + return this.ShowSuccess(t("Credit Card Update Category Succeeded")); + }, this), + error: __bind(function(e) { + return this.ShowError(t("Credit Card Update Category Failed")); + }, this) + }; + app.collections.paymentprofiles.models[id].set(attrs); + return app.collections.paymentprofiles.models[id].save({}, options); + }; + CreditCardView.prototype.makeDefault = function(e) { + var $el, attrs, id, options; + e.preventDefault(); + this.ClearGlobalStatus(); + $el = $(e.currentTarget).parents("td"); + id = $el.parents("tr").attr("id").substring(1); + attrs = { + "default": true + }; + options = { + success: __bind(function(response) { + this.ShowSuccess(t("Credit Card Update Default Succeeded")); + return app.collections.paymentprofiles.trigger("refresh"); + }, this), + error: __bind(function(e) { + return this.ShowError(t("Credit Card Update Default Failed")); + }, this) + }; + app.collections.paymentprofiles.models[id].set(attrs); + return app.collections.paymentprofiles.models[id].save({}, options); + }; + return CreditCardView; + })(); +}).call(this); +}, "views/clients/promotions": function(exports, require, module) {(function() { + var clientsPromotionsTemplate; + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + clientsPromotionsTemplate = require('templates/clients/promotions'); + exports.ClientsPromotionsView = (function() { + __extends(ClientsPromotionsView, UberView); + function ClientsPromotionsView() { + this.render = __bind(this.render, this); + ClientsPromotionsView.__super__.constructor.apply(this, arguments); + } + ClientsPromotionsView.prototype.id = 'promotions_view'; + ClientsPromotionsView.prototype.className = 'view_container'; + ClientsPromotionsView.prototype.events = { + 'submit form': 'submitPromo', + 'click button': 'submitPromo' + }; + ClientsPromotionsView.prototype.initialize = function() { + if (this.model) { + return this.RefreshUserInfo(this.render); + } + }; + ClientsPromotionsView.prototype.render = function() { + var renderTemplate; + this.ReadUserInfo(); + renderTemplate = __bind(function() { + $(this.el).html(clientsPromotionsTemplate({ + promos: window.USER.unexpired_client_promotions || [] + })); + return this.HideSpinner(); + }, this); + this.DownloadUserPromotions(renderTemplate); + return this; + }; + ClientsPromotionsView.prototype.submitPromo = function(e) { + var attrs, model, options, refreshTable; + e.preventDefault(); + this.ClearGlobalStatus(); + refreshTable = __bind(function() { + $('section').html(this.render().el); + return this.HideSpinner(); + }, this); + attrs = { + code: $('#code').val() + }; + options = { + success: __bind(function(response) { + this.HideSpinner(); + if (response.get('first_name')) { + return this.ShowSuccess("Your promotion has been applied in the form of an account credit. Click here to check your balance."); + } else { + this.ShowSuccess("Your promotion has successfully been applied"); + return this.RefreshUserInfo(this.render, true); + } + }, this), + statusCode: { + 400: __bind(function(e) { + this.ShowError(JSON.parse(e.responseText).error); + return this.HideSpinner(); + }, this) + } + }; + this.ShowSpinner("submit"); + model = new app.models.promotions; + return model.save(attrs, options); + }; + return ClientsPromotionsView; + })(); +}).call(this); +}, "views/clients/request": function(exports, require, module) {(function() { + var clientsRequestTemplate; + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + clientsRequestTemplate = require('templates/clients/request'); + exports.ClientsRequestView = (function() { + __extends(ClientsRequestView, UberView); + function ClientsRequestView() { + this.AjaxCall = __bind(this.AjaxCall, this); + this.AskDispatch = __bind(this.AskDispatch, this); + this.removeMarkers = __bind(this.removeMarkers, this); + this.displaySearchLoc = __bind(this.displaySearchLoc, this); + this.displayFavLoc = __bind(this.displayFavLoc, this); + this.showFavLoc = __bind(this.showFavLoc, this); + this.addToFavLoc = __bind(this.addToFavLoc, this); + this.removeCabs = __bind(this.removeCabs, this); + this.requestRide = __bind(this.requestRide, this); + this.rateTrip = __bind(this.rateTrip, this); + this.locationChange = __bind(this.locationChange, this); + this.panToLocation = __bind(this.panToLocation, this); + this.clickLocation = __bind(this.clickLocation, this); + this.searchLocation = __bind(this.searchLocation, this); + this.mouseoutLocation = __bind(this.mouseoutLocation, this); + this.mouseoverLocation = __bind(this.mouseoverLocation, this); + this.fetchTripDetails = __bind(this.fetchTripDetails, this); + this.submitRating = __bind(this.submitRating, this); + this.setStatus = __bind(this.setStatus, this); + this.initialize = __bind(this.initialize, this); + ClientsRequestView.__super__.constructor.apply(this, arguments); + } + ClientsRequestView.prototype.id = 'request_view'; + ClientsRequestView.prototype.className = 'view_container'; + ClientsRequestView.prototype.pollInterval = 2 * 1000; + ClientsRequestView.prototype.events = { + "submit #search_form": "searchAddress", + "click .locations_link": "locationLinkHandle", + "mouseover .location_row": "mouseoverLocation", + "mouseout .location_row": "mouseoutLocation", + "click .location_row": "clickLocation", + "click #search_location": "searchLocation", + "click #pickupHandle": "pickupHandle", + "click .stars": "rateTrip", + "submit #rating_form": "submitRating", + "click #addToFavButton": "showFavLoc", + "click #favLocNickname": "selectInputText", + "submit #favLoc_form": "addToFavLoc" + }; + ClientsRequestView.prototype.status = ""; + ClientsRequestView.prototype.pickupMarker = "https://uber-static.s3.amazonaws.com/pickup_marker.png"; + ClientsRequestView.prototype.cabMarker = "https://uber-static.s3.amazonaws.com/cab_marker.png"; + ClientsRequestView.prototype.initialize = function() { + var displayCabs; + displayCabs = __bind(function() { + return this.AskDispatch("NearestCab"); + }, this); + this.showCabs = _.throttle(displayCabs, this.pollInterval); + return this.numSearchToDisplay = 1; + }; + ClientsRequestView.prototype.setStatus = function(status) { + var autocomplete; + if (this.status === status) { + return; + } + try { + google.maps.event.trigger(this.map, 'resize'); + } catch (_e) {} + switch (status) { + case "init": + this.AskDispatch("StatusClient"); + this.status = "init"; + return this.ShowSpinner("load"); + case "ready": + this.HideSpinner(); + $(".panel").hide(); + $("#top_bar").fadeIn(); + $("#location_panel").fadeIn(); + $("#location_panel_control").fadeIn(); + $("#pickupHandle").attr("class", "button_green").fadeIn().find("span").html(t("Request Pickup")); + this.pickup_icon.setDraggable(true); + this.map.panTo(this.pickup_icon.getPosition()); + this.showCabs(); + try { + this.pickup_icon.setMap(this.map); + this.displayFavLoc(); + autocomplete = new google.maps.places.Autocomplete(document.getElementById('address'), { + types: ['geocode'] + }); + autocomplete.bindTo('bounds', this.map); + } catch (_e) {} + return this.status = "ready"; + case "searching": + this.HideSpinner(); + this.removeMarkers(); + $(".panel").hide(); + $("#top_bar").fadeOut(); + $("#status_message").html(t("Requesting Closest Driver")); + $("#pickupHandle").attr("class", "button_red").fadeIn().find("span").html(t("Cancel Pickup")); + this.pickup_icon.setDraggable(false); + this.pickup_icon.setMap(this.map); + return this.status = "searching"; + case "waiting": + this.HideSpinner(); + this.removeMarkers(); + $(".panel").hide(); + $("#top_bar").fadeOut(); + $("#pickupHandle").attr("class", "button_red").fadeIn().find("span").html(t("Cancel Pickup")); + $("#waiting_riding").fadeIn(); + this.pickup_icon.setDraggable(false); + this.pickup_icon.setMap(this.map); + return this.status = "waiting"; + case "arriving": + this.HideSpinner(); + this.removeMarkers(); + $(".panel").hide(); + $("#top_bar").fadeOut(); + $("#pickupHandle").attr("class", "button_red").fadeIn().find("span").html(t("Cancel Pickup")); + $("#waiting_riding").fadeIn(); + this.pickup_icon.setDraggable(false); + this.pickup_icon.setMap(this.map); + return this.status = "arriving"; + case "riding": + this.HideSpinner(); + this.removeMarkers(); + $(".panel").hide(); + $("#top_bar").fadeOut(); + $("#pickupHandle").fadeIn().attr("class", "button_red").find("span").html(t("Cancel Pickup")); + $("#waiting_riding").fadeIn(); + this.pickup_icon.setDraggable(false); + this.status = "riding"; + return $("#status_message").html(t("En Route")); + case "rate": + this.HideSpinner(); + $(".panel").hide(); + $("#pickupHandle").fadeOut(); + $("#trip_completed_panel").fadeIn(); + $('#status_message').html(t("Rate Last Trip")); + return this.status = "rate"; + } + }; + ClientsRequestView.prototype.render = function() { + this.ReadUserInfo(); + this.HideSpinner(); + this.ShowSpinner("load"); + $(this.el).html(clientsRequestTemplate()); + this.cabs = []; + this.RequireMaps(__bind(function() { + var center, myOptions, streetViewPano; + center = new google.maps.LatLng(37.7749295, -122.4194155); + this.markers = []; + this.pickup_icon = new google.maps.Marker({ + position: center, + draggable: true, + clickable: true, + icon: this.pickupMarker + }); + this.geocoder = new google.maps.Geocoder(); + myOptions = { + zoom: 12, + center: center, + mapTypeId: google.maps.MapTypeId.ROADMAP, + rotateControl: false, + rotateControl: false, + panControl: false + }; + this.map = new google.maps.Map($(this.el).find("#map_wrapper_right")[0], myOptions); + if (this.status === "ready") { + this.pickup_icon.setMap(this.map); + } + if (geo_position_js.init()) { + geo_position_js.getCurrentPosition(__bind(function(data) { + var location; + location = new google.maps.LatLng(data.coords.latitude, data.coords.longitude); + this.pickup_icon.setPosition(location); + this.map.panTo(location); + return this.map.setZoom(16); + }, this)); + } + this.setStatus("init"); + streetViewPano = this.map.getStreetView(); + google.maps.event.addListener(streetViewPano, 'visible_changed', __bind(function() { + if (streetViewPano.getVisible()) { + this.pickupMarker = "https://uber-static.s3.amazonaws.com/pickup_marker_large.png"; + this.cabMarker = "https://uber-static.s3.amazonaws.com/cab_marker_large.png"; + } else { + this.pickupMarker = "https://uber-static.s3.amazonaws.com/pickup_marker.png"; + this.cabMarker = "https://uber-static.s3.amazonaws.com/cab_marker.png"; + } + this.pickup_icon.setIcon(this.pickupMarker); + return _.each(this.cabs, __bind(function(cab) { + return cab.setIcon(this.cabMarker); + }, this)); + }, this)); + if (this.status === "ready") { + return this.displayFavLoc(); + } + }, this)); + return this; + }; + ClientsRequestView.prototype.submitRating = function(e) { + var $el, message, rating; + e.preventDefault(); + $el = $(e.currentTarget); + rating = 0; + _(5).times(function(num) { + if ($el.find(".stars#" + (num + 1)).attr("src") === "/web/img/star_active.png") { + return rating = num + 1; + } + }); + if (rating === 0) { + $("#status_message").html("").html(t("Rate Before Submitting")); + } else { + this.ShowSpinner("submit"); + this.AskDispatch("RatingDriver", { + rating: rating + }); + } + message = $el.find("#comments").val().toString(); + if (message.length > 5) { + return this.AskDispatch("Feedback", { + message: message + }); + } + }; + ClientsRequestView.prototype.fetchTripDetails = function(id) { + var trip; + trip = new app.models.trip({ + id: id + }); + return trip.fetch({ + data: { + relationships: 'points,driver,city' + }, + dataType: 'json', + success: __bind(function() { + var bounds, endPos, path, polyline, startPos; + bounds = new google.maps.LatLngBounds(); + path = []; + _.each(trip.get('points'), __bind(function(point) { + path.push(new google.maps.LatLng(point.lat, point.lng)); + return bounds.extend(_.last(path)); + }, this)); + startPos = new google.maps.Marker({ + position: _.first(path), + map: this.map, + title: t("Trip started here"), + icon: 'https://uber-static.s3.amazonaws.com/carstart.png' + }); + endPos = new google.maps.Marker({ + position: _.last(path), + map: this.map, + title: t("Trip ended here"), + icon: 'https://uber-static.s3.amazonaws.com/carstop.png' + }); + polyline = new google.maps.Polyline({ + path: path, + strokeColor: '#003F87', + strokeOpacity: 1, + strokeWeight: 5 + }); + polyline.setMap(this.map); + this.map.fitBounds(bounds); + $("#tripTime").html(app.helpers.parseDateTime(trip.get('pickup_local_time'), trip.get('city.timezone'))); + $("#tripDist").html(app.helpers.RoundNumber(trip.get('distance'), 2)); + $("#tripDur").html(app.helpers.FormatSeconds(trip.get('duration'))); + return $("#tripFare").html(app.helpers.FormatCurrency(trip.get('fare'))); + }, this) + }); + }; + ClientsRequestView.prototype.searchAddress = function(e) { + var $locationsDiv, address, alphabet, bounds, showResults; + alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + try { + e.preventDefault(); + } catch (_e) {} + $('.error_message').html(""); + $locationsDiv = $("
"); + address = $('#address').val(); + bounds = new google.maps.LatLngBounds(); + if (address.length < 5) { + $('#status_message').html(t("Address too short")).fadeIn(); + return false; + } + showResults = __bind(function(address, index) { + var first_cell, row, second_cell; + if (index < this.numSearchToDisplay) { + first_cell = ""; + second_cell = "" + address.formatted_address + ""; + row = $("").attr("id", "s" + index).attr("class", "location_row").html(first_cell + second_cell); + $locationsDiv.append(row); + } + if (index === this.numSearchToDisplay) { + $locationsDiv.append("" + (t('or did you mean')) + " "); + return $locationsDiv.append("" + address.formatted_address + ""); + } + }, this); + return this.geocoder.geocode({ + address: address + }, __bind(function(result, status) { + if (status !== "OK") { + $('.error_message').html(t("Search Address Failed")).fadeIn(); + return; + } + _.each(result, showResults); + $("#search_results").html($locationsDiv); + this.locationChange("search"); + this.searchResults = result; + return this.displaySearchLoc(); + }, this)); + }; + ClientsRequestView.prototype.mouseoverLocation = function(e) { + var $el, id, marker; + $el = $(e.currentTarget); + id = $el.attr("id").substring(1); + marker = this.markers[id]; + return marker.setAnimation(google.maps.Animation.BOUNCE); + }; + ClientsRequestView.prototype.mouseoutLocation = function(e) { + var $el, id, marker; + $el = $(e.currentTarget); + id = $el.attr("id").substring(1); + marker = this.markers[id]; + return marker.setAnimation(null); + }; + ClientsRequestView.prototype.searchLocation = function(e) { + e.preventDefault(); + $("#address").val($(e.currentTarget).html()); + return this.searchAddress(); + }; + ClientsRequestView.prototype.favoriteClick = function(e) { + var index, location; + e.preventDefault(); + $(".favorites").attr("href", ""); + index = $(e.currentTarget).removeAttr("href").attr("id"); + location = new google.maps.LatLng(USER.locations[index].latitude, USER.locations[index].longitude); + return this.panToLocation(location); + }; + ClientsRequestView.prototype.clickLocation = function(e) { + var id; + id = $(e.currentTarget).attr("id").substring(1); + return this.panToLocation(this.markers[id].getPosition()); + }; + ClientsRequestView.prototype.panToLocation = function(location) { + this.map.panTo(location); + this.map.setZoom(16); + return this.pickup_icon.setPosition(location); + }; + ClientsRequestView.prototype.locationLinkHandle = function(e) { + var panelName; + e.preventDefault(); + panelName = $(e.currentTarget).attr("id"); + return this.locationChange(panelName); + }; + ClientsRequestView.prototype.locationChange = function(type) { + $(".locations_link").attr("href", "").css("font-weight", "normal"); + switch (type) { + case "favorite": + $(".search_results").attr("href", ""); + $(".locations_link#favorite").removeAttr("href").css("font-weight", "bold"); + $("#search_results").hide(); + $("#favorite_results").fadeIn(); + return this.displayFavLoc(); + case "search": + $(".favorites").attr("href", ""); + $(".locations_link#search").removeAttr("href").css("font-weight", "bold"); + $("#favorite_results").hide(); + $("#search_results").fadeIn(); + return this.displaySearchLoc(); + } + }; + ClientsRequestView.prototype.rateTrip = function(e) { + var rating; + rating = $(e.currentTarget).attr("id"); + $(".stars").attr("src", "/web/img/star_inactive.png"); + return _(rating).times(function(index) { + return $(".stars#" + (index + 1)).attr("src", "/web/img/star_active.png"); + }); + }; + ClientsRequestView.prototype.pickupHandle = function(e) { + var $el, callback, message; + e.preventDefault(); + $el = $(e.currentTarget).find("span"); + switch ($el.html()) { + case t("Request Pickup"): + _.delay(this.requestRide, 3000); + $("#status_message").html(t("Sending pickup request...")); + $el.html(t("Cancel Pickup")).parent().attr("class", "button_red"); + this.pickup_icon.setDraggable(false); + this.map.panTo(this.pickup_icon.getPosition()); + return this.map.setZoom(18); + case t("Cancel Pickup"): + if (this.status === "ready") { + $el.html(t("Request Pickup")).parent().attr("class", "button_green"); + return this.pickup_icon.setDraggable(true); + } else { + callback = __bind(function(v, m, f) { + if (v) { + this.AskDispatch("PickupCanceledClient"); + return this.setStatus("ready"); + } + }, this); + message = t("Cancel Request Prompt"); + if (this.status === "arriving") { + message = 'Cancel Request Arrived Prompt'; + } + return $.prompt(message, { + buttons: { + Ok: true, + Cancel: false + }, + callback: callback + }); + } + } + }; + ClientsRequestView.prototype.requestRide = function() { + if ($("#pickupHandle").find("span").html() === t("Cancel Pickup")) { + this.AskDispatch("Pickup"); + return this.setStatus("searching"); + } + }; + ClientsRequestView.prototype.removeCabs = function() { + _.each(this.cabs, __bind(function(point) { + return point.setMap(null); + }, this)); + return this.cabs = []; + }; + ClientsRequestView.prototype.addToFavLoc = function(e) { + var $el, lat, lng, nickname; + e.preventDefault(); + $el = $(e.currentTarget); + $el.find(".error_message").html(""); + nickname = $el.find("#favLocNickname").val().toString(); + lat = $el.find("#pickupLat").val().toString(); + lng = $el.find("#pickupLng").val().toString(); + if (nickname.length < 3) { + $el.find(".error_message").html(t("Favorite Location Nickname Length Error")); + return; + } + this.ShowSpinner("submit"); + return $.ajax({ + type: 'POST', + url: API + "/locations", + dataType: 'json', + data: { + token: USER.token, + nickname: nickname, + latitude: lat, + longitude: lng + }, + success: __bind(function(data, textStatus, jqXHR) { + return $el.html(t("Favorite Location Save Succeeded")); + }, this), + error: __bind(function(jqXHR, textStatus, errorThrown) { + return $el.find(".error_message").html(t("Favorite Location Save Failed")); + }, this), + complete: __bind(function(data) { + return this.HideSpinner(); + }, this) + }); + }; + ClientsRequestView.prototype.showFavLoc = function(e) { + $(e.currentTarget).fadeOut(); + return $("#favLoc_form").fadeIn(); + }; + ClientsRequestView.prototype.selectInputText = function(e) { + e.currentTarget.focus(); + return e.currentTarget.select(); + }; + ClientsRequestView.prototype.displayFavLoc = function() { + var alphabet, bounds; + alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + this.removeMarkers(); + bounds = new google.maps.LatLngBounds(); + _.each(USER.locations, __bind(function(location, index) { + var marker; + marker = new google.maps.Marker({ + position: new google.maps.LatLng(location.latitude, location.longitude), + map: this.map, + title: t("Favorite Location Title", { + id: alphabet != null ? alphabet[index] : void 0 + }), + icon: "https://www.google.com/mapfiles/marker" + alphabet[index] + ".png" + }); + this.markers.push(marker); + bounds.extend(marker.getPosition()); + return google.maps.event.addListener(marker, 'click', __bind(function() { + return this.pickup_icon.setPosition(marker.getPosition()); + }, this)); + }, this)); + this.pickup_icon.setPosition(_.first(this.markers).getPosition()); + return this.map.fitBounds(bounds); + }; + ClientsRequestView.prototype.displaySearchLoc = function() { + var alphabet; + alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + this.removeMarkers(); + return _.each(this.searchResults, __bind(function(result, index) { + var marker; + if (index < this.numSearchToDisplay) { + marker = new google.maps.Marker({ + position: result.geometry.location, + map: this.map, + title: t("Search Location Title", { + id: alphabet != null ? alphabet[index] : void 0 + }), + icon: "https://www.google.com/mapfiles/marker" + alphabet[index] + ".png" + }); + this.markers.push(marker); + return this.panToLocation(result.geometry.location); + } + }, this)); + }; + ClientsRequestView.prototype.removeMarkers = function() { + _.each(this.markers, __bind(function(marker) { + return marker.setMap(null); + }, this)); + return this.markers = []; + }; + ClientsRequestView.prototype.AskDispatch = function(ask, options) { + var attrs, lowestETA, processData, showCab; + if (ask == null) { + ask = ""; + } + if (options == null) { + options = {}; + } + switch (ask) { + case "NearestCab": + attrs = { + latitude: this.pickup_icon.getPosition().lat(), + longitude: this.pickup_icon.getPosition().lng() + }; + lowestETA = 99999; + showCab = __bind(function(cab) { + var point; + point = new google.maps.Marker({ + position: new google.maps.LatLng(cab.latitude, cab.longitude), + map: this.map, + icon: this.cabMarker, + title: t("ETA Message", { + minutes: app.helpers.FormatSeconds(cab != null ? cab.eta : void 0, true) + }) + }); + if (cab.eta < lowestETA) { + lowestETA = cab.eta; + } + return this.cabs.push(point); + }, this); + processData = __bind(function(data, textStatus, jqXHR) { + if (this.status === "ready") { + this.removeCabs(); + if (data.sorry) { + $("#status_message").html(data.sorry).fadeIn(); + } else { + _.each(data.driverLocations, showCab); + $("#status_message").html(t("Nearest Cab Message", { + minutes: app.helpers.FormatSeconds(lowestETA, true) + })).fadeIn(); + } + if (Backbone.history.fragment === "!/request") { + return _.delay(this.showCabs, this.pollInterval); + } + } + }, this); + return this.AjaxCall(ask, processData, attrs); + case "StatusClient": + processData = __bind(function(data, textStatus, jqXHR) { + var bounds, cabLocation, locationSaved, point, userLocation; + if (data.messageType === "OK") { + switch (data.status) { + case "completed": + this.removeCabs(); + this.setStatus("rate"); + return this.fetchTripDetails(data.tripID); + case "open": + return this.setStatus("ready"); + case "begintrip": + this.setStatus("riding"); + cabLocation = new google.maps.LatLng(data.latitude, data.longitude); + this.removeCabs(); + this.pickup_icon.setMap(null); + point = new google.maps.Marker({ + position: cabLocation, + map: this.map, + icon: this.cabMarker + }); + this.cabs.push(point); + this.map.panTo(point.getPosition()); + $("#rideName").html(data.driverName); + $("#ridePhone").html(data.driverMobile); + $("#ride_address_wrapper").hide(); + if (Backbone.history.fragment === "!/request") { + return _.delay(this.AskDispatch, this.pollInterval, "StatusClient"); + } + break; + case "pending": + this.setStatus("searching"); + if (Backbone.history.fragment === "!/request") { + return _.delay(this.AskDispatch, this.pollInterval, "StatusClient"); + } + break; + case "accepted": + case "arrived": + if (data.status === "accepted") { + this.setStatus("waiting"); + $("#status_message").html(t("Arrival ETA Message", { + minutes: app.helpers.FormatSeconds(data.eta, true) + })); + } else { + this.setStatus("arriving"); + $("#status_message").html(t("Arriving Now Message")); + } + userLocation = new google.maps.LatLng(data.pickupLocation.latitude, data.pickupLocation.longitude); + cabLocation = new google.maps.LatLng(data.latitude, data.longitude); + this.pickup_icon.setPosition(userLocation); + this.removeCabs(); + $("#rideName").html(data.driverName); + $("#ridePhone").html(data.driverMobile); + if ($("#rideAddress").html() === "") { + locationSaved = false; + _.each(USER.locations, __bind(function(location) { + if (parseFloat(location.latitude) === parseFloat(data.pickupLocation.latitude) && parseFloat(location.longitude) === parseFloat(data.pickupLocation.longitude)) { + return locationSaved = true; + } + }, this)); + if (locationSaved) { + $("#addToFavButton").hide(); + } + $("#pickupLat").val(data.pickupLocation.latitude); + $("#pickupLng").val(data.pickupLocation.longitude); + this.geocoder.geocode({ + location: userLocation + }, __bind(function(result, status) { + $("#rideAddress").html(result[0].formatted_address); + return $("#favLocNickname").val("" + result[0].address_components[0].short_name + " " + result[0].address_components[1].short_name); + }, this)); + } + point = new google.maps.Marker({ + position: cabLocation, + map: this.map, + icon: this.cabMarker + }); + this.cabs.push(point); + bounds = bounds = new google.maps.LatLngBounds(); + bounds.extend(cabLocation); + bounds.extend(userLocation); + this.map.fitBounds(bounds); + if (Backbone.history.fragment === "!/request") { + return _.delay(this.AskDispatch, this.pollInterval, "StatusClient"); + } + } + } + }, this); + return this.AjaxCall(ask, processData); + case "Pickup": + attrs = { + latitude: this.pickup_icon.getPosition().lat(), + longitude: this.pickup_icon.getPosition().lng() + }; + processData = __bind(function(data, textStatus, jqXHR) { + if (data.messageType === "Error") { + return $("#status_message").html(data.description); + } else { + return this.AskDispatch("StatusClient"); + } + }, this); + return this.AjaxCall(ask, processData, attrs); + case "PickupCanceledClient": + processData = __bind(function(data, textStatus, jqXHR) { + if (data.messageType === "OK") { + return this.setStatus("ready"); + } else { + return $("#status_message").html(data.description); + } + }, this); + return this.AjaxCall(ask, processData, attrs); + case "RatingDriver": + attrs = { + rating: options.rating + }; + processData = __bind(function(data, textStatus, jqXHR) { + if (data.messageType === "OK") { + this.setStatus("init"); + } else { + $("status_message").html(t("Rating Driver Failed")); + } + return this.HideSpinner(); + }, this); + return this.AjaxCall(ask, processData, attrs); + case "Feedback": + attrs = { + message: options.message + }; + processData = __bind(function(data, textStatus, jqXHR) { + if (data.messageType === "OK") { + return alert("rated"); + } + }, this); + return this.AjaxCall(ask, processData, attrs); + } + }; + ClientsRequestView.prototype.AjaxCall = function(type, successCallback, attrs) { + if (attrs == null) { + attrs = {}; + } + _.extend(attrs, { + token: USER.token, + messageType: type, + app: "client", + version: "1.0.60", + device: "web" + }); + return $.ajax({ + type: 'POST', + url: DISPATCH + "/", + processData: false, + data: JSON.stringify(attrs), + success: successCallback, + dataType: 'json', + error: __bind(function(jqXHR, textStatus, errorThrown) { + $("#status_message").html(errorThrown); + return this.HideSpinner(); + }, this) + }); + }; + return ClientsRequestView; + })(); +}).call(this); +}, "views/clients/settings": function(exports, require, module) {(function() { + var clientsSettingsTemplate; + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + clientsSettingsTemplate = require('templates/clients/settings'); + exports.ClientsSettingsView = (function() { + __extends(ClientsSettingsView, UberView); + function ClientsSettingsView() { + this.render = __bind(this.render, this); + this.initialize = __bind(this.initialize, this); + ClientsSettingsView.__super__.constructor.apply(this, arguments); + } + ClientsSettingsView.prototype.id = 'settings_view'; + ClientsSettingsView.prototype.className = 'view_container'; + ClientsSettingsView.prototype.events = { + 'submit #profile_pic_form': 'processPicUpload', + 'click #submit_pic': 'processPicUpload', + 'click a.setting_change': "changeTab", + 'submit #edit_info_form': "submitInfo", + 'click #change_password': 'changePass' + }; + ClientsSettingsView.prototype.divs = { + 'info_div': "Information", + 'pic_div': "Picture" + }; + ClientsSettingsView.prototype.pageTitle = t("Settings") + " | " + t("Uber"); + ClientsSettingsView.prototype.tabTitle = { + 'info_div': t("Information"), + 'pic_div': t("Picture") + }; + ClientsSettingsView.prototype.initialize = function() { + return this.mixin(require('web-lib/mixins/i18n_phone_form').i18nPhoneForm); + }; + ClientsSettingsView.prototype.render = function(type) { + if (type == null) { + type = "info"; + } + this.RefreshUserInfo(__bind(function() { + var $el, alphabet; + this.delegateEvents(); + this.HideSpinner(); + alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + $el = $(this.el); + $(this.el).html(clientsSettingsTemplate({ + type: type + })); + $el.find("#" + type + "_div").show(); + $el.find("a[href='" + type + "_div']").parent().addClass("active"); + return document.title = "" + this.tabTitle[type + '_div'] + " " + this.pageTitle; + }, this)); + this.delegateEvents(); + return this; + }; + ClientsSettingsView.prototype.changeTab = function(e) { + var $eTarget, $el, div, link, pageDiv, _i, _j, _len, _len2, _ref, _ref2; + e.preventDefault(); + $eTarget = $(e.currentTarget); + this.ClearGlobalStatus(); + $el = $(this.el); + _ref = $el.find(".setting_change"); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + link = _ref[_i]; + $(link).parent().removeClass("active"); + } + $eTarget.parent().addClass("active"); + _ref2 = _.keys(this.divs); + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + div = _ref2[_j]; + $el.find("#" + div).hide(); + } + pageDiv = $eTarget.attr('href'); + $el.find("#" + pageDiv).show(); + Backbone.history.navigate("!/settings/" + (this.divs[pageDiv].toLowerCase().replace(" ", "-")), false); + document.title = "" + this.tabTitle[pageDiv] + " " + this.pageTitle; + if (pageDiv === "loc_div") { + try { + google.maps.event.trigger(this.map, 'resize'); + return this.map.fitBounds(this.bounds); + } catch (_e) {} + } + }; + ClientsSettingsView.prototype.submitInfo = function(e) { + var $e, attrs, client, options; + $('#global_status').find('.success_message').text(''); + $('#global_status').find('.error_message').text(''); + $('.error_message').text(''); + e.preventDefault(); + $e = $(e.currentTarget); + attrs = $e.serializeToJson(); + attrs['mobile_country_id'] = this.$('#mobile_country_id').val(); + if (attrs['password'] === '') { + delete attrs['password']; + } + options = { + success: __bind(function(response) { + this.ShowSuccess(t("Information Update Succeeded")); + return this.RefreshUserInfo(); + }, this), + error: __bind(function(model, data) { + var errors; + if (data.status === 406) { + errors = JSON.parse(data.responseText); + return _.each(_.keys(errors), function(field) { + return $("#" + field).parent().find('span.error_message').text(errors[field]); + }); + } else { + return this.ShowError(t("Information Update Failed")); + } + }, this), + type: "PUT" + }; + client = new app.models.client({ + id: USER.id + }); + return client.save(attrs, options); + }; + ClientsSettingsView.prototype.changePass = function(e) { + e.preventDefault(); + $(e.currentTarget).hide(); + return $("#password").show(); + }; + ClientsSettingsView.prototype.processPicUpload = function(e) { + e.preventDefault(); + this.ShowSpinner("submit"); + return $.ajaxFileUpload({ + url: API + '/user_pictures', + secureuri: false, + fileElementId: 'picture', + data: { + token: USER.token + }, + dataType: 'json', + complete: __bind(function(data, status) { + this.HideSpinner(); + if (status === 'success') { + this.ShowSuccess(t("Picture Update Succeeded")); + return this.RefreshUserInfo(__bind(function() { + return $("#settingsProfPic").attr("src", USER.picture_url + ("?" + (Math.floor(Math.random() * 1000)))); + }, this)); + } else { + if (data.error) { + return this.ShowError(data.error); + } else { + return this.ShowError("Picture Update Failed"); + } + } + }, this) + }); + }; + return ClientsSettingsView; + })(); +}).call(this); +}, "views/clients/sign_up": function(exports, require, module) {(function() { + var clientsSignUpTemplate; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + clientsSignUpTemplate = require('templates/clients/sign_up'); + exports.ClientsSignUpView = (function() { + __extends(ClientsSignUpView, UberView); + function ClientsSignUpView() { + ClientsSignUpView.__super__.constructor.apply(this, arguments); + } + ClientsSignUpView.prototype.id = 'signup_view'; + ClientsSignUpView.prototype.className = 'view_container'; + ClientsSignUpView.prototype.initialize = function() { + this.mixin(require('web-lib/mixins/i18n_phone_form').i18nPhoneForm); + return $('#location_country').live('change', function() { + if (!$('#mobile').val()) { + return $('#mobile_country').find("option[value=" + ($(this).val()) + "]").attr('selected', 'selected').end().trigger('change'); + } + }); + }; + ClientsSignUpView.prototype.events = { + 'submit form': 'signup', + 'click button': 'signup', + 'change #card_number': 'showCardType', + 'change #location_country': 'countryChange' + }; + ClientsSignUpView.prototype.render = function(invite) { + this.HideSpinner(); + $(this.el).html(clientsSignUpTemplate({ + invite: invite + })); + return this; + }; + ClientsSignUpView.prototype.signup = function(e) { + var $el, attrs, client, error_messages, options; + e.preventDefault(); + $el = $("form"); + $el.find('#terms_error').hide(); + if (!$el.find('#signup_terms input[type=checkbox]').attr('checked')) { + $('#spinner.submit').hide(); + $el.find('#terms_error').show(); + return; + } + error_messages = $el.find('.error_message').html(""); + attrs = { + first_name: $el.find('#first_name').val(), + last_name: $el.find('#last_name').val(), + email: $el.find('#email').val(), + password: $el.find('#password').val(), + location_country: $el.find('#location_country option:selected').attr('data-iso2'), + location: $el.find('#location').val(), + language: $el.find('#language').val(), + mobile_country: $el.find('#mobile_country option:selected').attr('data-iso2'), + mobile: $el.find('#mobile').val(), + card_number: $el.find('#card_number').val(), + card_expiration_month: $el.find('#card_expiration_month').val(), + card_expiration_year: $el.find('#card_expiration_year').val(), + card_code: $el.find('#card_code').val(), + use_case: $el.find('#use_case').val(), + promotion_code: $el.find('#promotion_code').val() + }; + options = { + statusCode: { + 200: function(response) { + $.cookie('token', response.token); + amplify.store('USERjson', response); + app.refreshMenu(); + return app.routers.clients.navigate('!/dashboard', true); + }, + 406: function(e) { + var error, errors, _i, _len, _ref, _results; + errors = JSON.parse(e.responseText); + _ref = _.keys(errors); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + error = _ref[_i]; + _results.push($('#' + error).parent().find('span').html($('#' + error).parent().find('span').html() + " " + errors[error])); + } + return _results; + } + }, + complete: __bind(function(response) { + return this.HideSpinner(); + }, this) + }; + client = new app.models.client; + $('.spinner#submit').show(); + return client.save(attrs, options); + }; + ClientsSignUpView.prototype.countryChange = function(e) { + var $e; + $e = $(e.currentTarget); + return $("#mobile_country").val($e.val()).trigger('change'); + }; + ClientsSignUpView.prototype.showCardType = function(e) { + var $el, reAmerica, reDiscover, reMaster, reVisa, validCard; + reVisa = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/; + reMaster = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/; + reAmerica = /^6011-?\d{4}-?\d{4}-?\d{4}$/; + reDiscover = /^3[4,7]\d{13}$/; + $el = $("#card_logos_signup"); + validCard = false; + if (e.currentTarget.value.match(reVisa)) { + $el.find("#overlay_left").css('width', "0px"); + return $el.find("#overlay_right").css('width', "75%"); + } else if (e.currentTarget.value.match(reMaster)) { + $el.find("#overlay_left").css('width', "25%"); + return $el.find("#overlay_right").css('width', "50%"); + } else if (e.currentTarget.value.match(reAmerica)) { + $el.find("#overlay_left").css('width', "75%"); + $el.find("#overlay_right").css('width', "0px"); + return console.log("amex"); + } else if (e.currentTarget.value.match(reDiscover)) { + $el.find("#overlay_left").css('width', "50%"); + return $el.find("#overlay_right").css('width', "25%"); + } else { + $el.find("#overlay_left").css('width', "0px"); + return $el.find("#overlay_right").css('width', "0px"); + } + }; + return ClientsSignUpView; + })(); +}).call(this); +}, "views/clients/trip_detail": function(exports, require, module) {(function() { + var clientsTripDetailTemplate; + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + clientsTripDetailTemplate = require('templates/clients/trip_detail'); + exports.TripDetailView = (function() { + __extends(TripDetailView, UberView); + function TripDetailView() { + this.resendReceipt = __bind(this.resendReceipt, this); + TripDetailView.__super__.constructor.apply(this, arguments); + } + TripDetailView.prototype.id = 'trip_detail_view'; + TripDetailView.prototype.className = 'view_container'; + TripDetailView.prototype.events = { + 'click a#fare_review': 'showFareReview', + 'click #fare_review_hide': 'hideFareReview', + 'submit #form_review_form': 'submitFareReview', + 'click #submit_fare_review': 'submitFareReview', + 'click .resendReceipt': 'resendReceipt' + }; + TripDetailView.prototype.render = function(id) { + if (id == null) { + id = 'invalid'; + } + this.ReadUserInfo(); + this.HideSpinner(); + this.model = new app.models.trip({ + id: id + }); + this.model.fetch({ + data: { + relationships: 'points,driver,city.country' + }, + dataType: 'json', + success: __bind(function() { + var trip; + trip = this.model; + $(this.el).html(clientsTripDetailTemplate({ + trip: trip + })); + this.RequireMaps(__bind(function() { + var bounds, endPos, map, myOptions, path, polyline, startPos; + bounds = new google.maps.LatLngBounds(); + path = []; + _.each(this.model.get('points'), __bind(function(point) { + path.push(new google.maps.LatLng(point.lat, point.lng)); + return bounds.extend(_.last(path)); + }, this)); + myOptions = { + zoom: 12, + center: path[0], + mapTypeId: google.maps.MapTypeId.ROADMAP, + zoomControl: false, + rotateControl: false, + panControl: false, + mapTypeControl: false, + scrollwheel: false + }; + map = new google.maps.Map(document.getElementById("trip_details_map"), myOptions); + map.fitBounds(bounds); + startPos = new google.maps.Marker({ + position: _.first(path), + map: map, + title: t("Trip started here"), + icon: 'https://uber-static.s3.amazonaws.com/marker_start.png' + }); + endPos = new google.maps.Marker({ + position: _.last(path), + map: map, + title: t("Trip ended here"), + icon: 'https://uber-static.s3.amazonaws.com/marker_end.png' + }); + startPos.setMap(map); + endPos.setMap(map); + polyline = new google.maps.Polyline({ + path: path, + strokeColor: '#003F87', + strokeOpacity: 1, + strokeWeight: 5 + }); + return polyline.setMap(map); + }, this)); + return this.HideSpinner(); + }, this) + }); + this.ShowSpinner('load'); + this.delegateEvents(); + return this; + }; + TripDetailView.prototype.showFareReview = function(e) { + e.preventDefault(); + $('#fare_review_box').slideDown(); + return $('#fare_review').hide(); + }; + TripDetailView.prototype.hideFareReview = function(e) { + e.preventDefault(); + $('#fare_review_box').slideUp(); + return $('#fare_review').show(); + }; + TripDetailView.prototype.submitFareReview = function(e) { + var attrs, errorMessage, id, options; + e.preventDefault(); + errorMessage = $(".error_message"); + errorMessage.hide(); + id = $("#tripid").val(); + this.model = new app.models.trip({ + id: id + }); + attrs = { + note: $('#form_review_message').val(), + note_type: 'client_fare_review' + }; + options = { + success: __bind(function(response) { + $(".success_message").fadeIn(); + return $("#fare_review_form_wrapper").slideUp(); + }, this), + error: __bind(function(error) { + return errorMessage.fadeIn(); + }, this) + }; + return this.model.save(attrs, options); + }; + TripDetailView.prototype.resendReceipt = function(e) { + var $e; + e.preventDefault(); + $e = $(e.currentTarget); + this.$(".resendReceiptSuccess").empty().show(); + this.$(".resentReceiptError").empty().show(); + e.preventDefault(); + $('#spinner').show(); + return $.ajax('/api/trips/func/resend_receipt', { + data: { + token: $.cookie('token'), + trip_id: this.model.id + }, + type: 'POST', + complete: __bind(function(xhr) { + var response; + response = JSON.parse(xhr.responseText); + $('#spinner').hide(); + switch (xhr.status) { + case 200: + this.$(".resendReceiptSuccess").html("Receipt has been emailed"); + return this.$(".resendReceiptSuccess").fadeOut(2000); + default: + this.$(".resendReceiptError").html("Receipt has failed to be emailed"); + return this.$(".resendReceiptError").fadeOut(2000); + } + }, this) + }); + }; + return TripDetailView; + })(); +}).call(this); +}, "views/shared/menu": function(exports, require, module) {(function() { + var menuTemplate; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + menuTemplate = require('templates/shared/menu'); + exports.SharedMenuView = (function() { + __extends(SharedMenuView, Backbone.View); + function SharedMenuView() { + SharedMenuView.__super__.constructor.apply(this, arguments); + } + SharedMenuView.prototype.id = 'menu_view'; + SharedMenuView.prototype.render = function() { + var type; + if ($.cookie('token') === null) { + type = 'guest'; + } else { + type = 'client'; + } + $(this.el).html(menuTemplate({ + type: type + })); + return this; + }; + return SharedMenuView; + })(); +}).call(this); +}, "web-lib/collections/countries": function(exports, require, module) {(function() { + var UberCollection; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + UberCollection = require('web-lib/uber_collection').UberCollection; + exports.CountriesCollection = (function() { + __extends(CountriesCollection, UberCollection); + function CountriesCollection() { + CountriesCollection.__super__.constructor.apply(this, arguments); + } + CountriesCollection.prototype.model = app.models.country; + CountriesCollection.prototype.url = '/countries'; + return CountriesCollection; + })(); +}).call(this); +}, "web-lib/collections/vehicle_types": function(exports, require, module) {(function() { + var UberCollection, vehicleType, _ref; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + UberCollection = require('web-lib/uber_collection').UberCollection; + vehicleType = (typeof app !== "undefined" && app !== null ? (_ref = app.models) != null ? _ref.vehicleType : void 0 : void 0) || require('models/vehicle_type').VehicleType; + exports.VehicleTypesCollection = (function() { + __extends(VehicleTypesCollection, UberCollection); + function VehicleTypesCollection() { + VehicleTypesCollection.__super__.constructor.apply(this, arguments); + } + VehicleTypesCollection.prototype.model = vehicleType; + VehicleTypesCollection.prototype.url = '/vehicle_types'; + VehicleTypesCollection.prototype.defaultColumns = ['id', 'created_at', 'updated_at', 'deleted_at', 'created_by_user_id', 'updated_by_user_id', 'city_id', 'type', 'make', 'model', 'capacity', 'minimum_year', 'actions']; + VehicleTypesCollection.prototype.tableColumns = function(cols) { + var actions, c, capacity, city_id, columnValues, created_at, created_by_user_id, deleted_at, headerRow, id, make, minimum_year, model, type, updated_at, updated_by_user_id, _i, _len; + id = { + sTitle: 'Id' + }; + created_at = { + sTitle: 'Created At (UTC)', + 'sType': 'string' + }; + updated_at = { + sTitle: 'Updated At (UTC)', + 'sType': 'string' + }; + deleted_at = { + sTitle: 'Deleted At (UTC)', + 'sType': 'string' + }; + created_by_user_id = { + sTitle: 'Created By' + }; + updated_by_user_id = { + sTitle: 'Updated By' + }; + city_id = { + sTitle: 'City' + }; + type = { + sTitle: 'Type' + }; + make = { + sTitle: 'Make' + }; + model = { + sTitle: 'Model' + }; + capacity = { + sTitle: 'Capacity' + }; + minimum_year = { + sTitle: 'Min. Year' + }; + actions = { + sTitle: 'Actions' + }; + columnValues = { + id: id, + created_at: created_at, + updated_at: updated_at, + deleted_at: deleted_at, + created_by_user_id: created_by_user_id, + updated_by_user_id: updated_by_user_id, + city_id: city_id, + type: type, + make: make, + model: model, + capacity: capacity, + minimum_year: minimum_year, + actions: actions + }; + headerRow = []; + for (_i = 0, _len = cols.length; _i < _len; _i++) { + c = cols[_i]; + if (columnValues[c]) { + headerRow.push(columnValues[c]); + } + } + return headerRow; + }; + return VehicleTypesCollection; + })(); +}).call(this); +}, "web-lib/helpers": function(exports, require, module) {(function() { + var __indexOf = Array.prototype.indexOf || function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (this[i] === item) return i; + } + return -1; + }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + exports.helpers = { + pin: function(num, color) { + if (color == null) { + color = 'FF0000'; + } + return ""; + }, + reverseGeocode: function(latitude, longitude) { + if (latitude && longitude) { + return "" + latitude + ", " + longitude + ""; + } else { + return ''; + } + }, + linkedName: function(model) { + var first_name, id, last_name, role, url; + role = model.role || model.get('role'); + id = model.id || model.get('id'); + first_name = model.first_name || model.get('first_name'); + last_name = model.last_name || model.get('last_name'); + url = "/" + role + "s/" + id; + return "" + first_name + " " + last_name + ""; + }, + linkedVehicle: function(vehicle, vehicleType) { + return " " + (vehicleType != null ? vehicleType.get('make') : void 0) + " " + (vehicleType != null ? vehicleType.get('model') : void 0) + " " + (vehicle.get('year')) + " "; + }, + linkedUserId: function(userType, userId) { + return "" + userType + " " + userId + ""; + }, + timeDelta: function(start, end) { + var delta; + if (typeof start === 'string') { + start = this.parseDate(start); + } + if (typeof end === 'string') { + end = this.parseDate(end); + } + if (end && start) { + delta = end.getTime() - start.getTime(); + return this.formatSeconds(delta / 1000); + } else { + return '00:00'; + } + }, + formatSeconds: function(s) { + var minutes, seconds; + s = Math.floor(s); + minutes = Math.floor(s / 60); + seconds = s - minutes * 60; + return "" + (this.leadingZero(minutes)) + ":" + (this.leadingZero(seconds)); + }, + formatCurrency: function(strValue, reverseSign, currency) { + var currency_locale, lc, mf; + if (reverseSign == null) { + reverseSign = false; + } + if (currency == null) { + currency = null; + } + strValue = String(strValue); + if (reverseSign) { + strValue = ~strValue.indexOf('-') ? strValue.split('-').join('') : ['-', strValue].join(''); + } + currency_locale = i18n.currencyToLocale[currency]; + try { + if (!(currency_locale != null) || currency_locale === i18n.locale) { + return i18n.jsworld.mf.format(strValue); + } else { + lc = new jsworld.Locale(POSIX_LC[currency_locale]); + mf = new jsworld.MonetaryFormatter(lc); + return mf.format(strValue); + } + } catch (error) { + i18n.log(error); + return strValue; + } + }, + formatTripFare: function(trip, type) { + var _ref, _ref2; + if (type == null) { + type = "fare"; + } + if (!trip.get('fare')) { + return 'n/a'; + } + if (((_ref = trip.get('fare_breakdown_local')) != null ? _ref.currency : void 0) != null) { + return app.helpers.formatCurrency(trip.get("" + type + "_local"), false, (_ref2 = trip.get('fare_breakdown_local')) != null ? _ref2.currency : void 0); + } else if (trip.get("" + type + "_string") != null) { + return trip.get("" + type + "_string"); + } else if (trip.get("" + type + "_local") != null) { + return trip.get("" + type + "_local"); + } else { + return 'n/a'; + } + }, + formatPhoneNumber: function(phoneNumber, countryCode) { + if (countryCode == null) { + countryCode = "+1"; + } + if (phoneNumber != null) { + phoneNumber = String(phoneNumber); + switch (countryCode) { + case '+1': + return countryCode + ' ' + phoneNumber.substring(0, 3) + '-' + phoneNumber.substring(3, 6) + '-' + phoneNumber.substring(6, 10); + case '+33': + return countryCode + ' ' + phoneNumber.substring(0, 1) + ' ' + phoneNumber.substring(1, 3) + ' ' + phoneNumber.substring(3, 5) + ' ' + phoneNumber.substring(5, 7) + ' ' + phoneNumber.substring(7, 9); + default: + countryCode + phoneNumber; + } + } + return "" + countryCode + " " + phoneNumber; + }, + parseDate: function(d, cityTime, tz) { + var city_filter, parsed, _ref; + if (cityTime == null) { + cityTime = true; + } + if (tz == null) { + tz = null; + } + if (((_ref = !d.substr(-6, 1)) === '+' || _ref === '-') || d.length === 19) { + d += '+00:00'; + } + if (/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})/.test(d)) { + parsed = d.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/); + d = new Date(); + d.setUTCFullYear(parsed[1]); + d.setUTCMonth(parsed[2] - 1); + d.setUTCDate(parsed[3]); + d.setUTCHours(parsed[4]); + d.setUTCMinutes(parsed[5]); + d.setUTCSeconds(parsed[6]); + } else { + d = Date.parse(d); + } + if (typeof d === 'number') { + d = new Date(d); + } + d = new timezoneJS.Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), 'Etc/UTC'); + if (tz) { + d.convertToTimezone(tz); + } else if (cityTime) { + city_filter = $.cookie('city_filter'); + if (city_filter) { + tz = $("#city_filter option[value=" + city_filter + "]").attr('data-timezone'); + if (tz) { + d.convertToTimezone(tz); + } + } + } + return d; + }, + dateToTimezone: function(d) { + var city_filter, tz; + d = new timezoneJS.Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), 'Etc/UTC'); + city_filter = $.cookie('city_filter'); + if (city_filter) { + tz = $("#city_filter option[value=" + city_filter + "]").attr('data-timezone'); + d.convertToTimezone(tz); + } + return d; + }, + fixAMPM: function(d, formatted) { + if (d.hours >= 12) { + return formatted.replace(/\b[AP]M\b/, 'PM'); + } else { + return formatted.replace(/\b[AP]M\b/, 'AM'); + } + }, + formatDate: function(d, time, timezone) { + var formatted; + if (time == null) { + time = true; + } + if (timezone == null) { + timezone = null; + } + d = this.parseDate(d, true, timezone); + formatted = time ? ("" + (i18n.jsworld.dtf.formatDate(d)) + " ") + this.formatTime(d, d.getTimezoneInfo()) : i18n.jsworld.dtf.formatDate(d); + return this.fixAMPM(d, formatted); + }, + formatDateLong: function(d, time, timezone) { + if (time == null) { + time = true; + } + if (timezone == null) { + timezone = null; + } + d = this.parseDate(d, true, timezone); + timezone = d.getTimezoneInfo().tzAbbr; + if (time) { + return (i18n.jsworld.dtf.formatDateTime(d)) + (" " + timezone); + } else { + return i18n.jsworld.dtf.formatDate(d); + } + }, + formatTimezoneJSDate: function(d) { + var day, hours, jsDate, minutes, month, year; + year = d.getFullYear(); + month = this.leadingZero(d.getMonth()); + day = this.leadingZero(d.getDate()); + hours = this.leadingZero(d.getHours()); + minutes = this.leadingZero(d.getMinutes()); + jsDate = new Date(year, month, day, hours, minutes, 0); + return jsDate.toDateString(); + }, + formatTime: function(d, timezone) { + var formatted; + if (timezone == null) { + timezone = null; + } + formatted = ("" + (i18n.jsworld.dtf.formatTime(d))) + (timezone != null ? " " + (timezone != null ? timezone.tzAbbr : void 0) : ""); + return this.fixAMPM(d, formatted); + }, + formatISODate: function(d) { + var pad; + pad = function(n) { + if (n < 10) { + return '0' + n; + } + return n; + }; + return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + 'Z'; + }, + formatExpDate: function(d) { + var month, year; + d = this.parseDate(d); + year = d.getFullYear(); + month = this.leadingZero(d.getMonth() + 1); + return "" + year + "-" + month; + }, + formatLatLng: function(lat, lng, precision) { + if (precision == null) { + precision = 8; + } + return parseFloat(lat).toFixed(precision) + ',' + parseFloat(lng).toFixed(precision); + }, + leadingZero: function(num) { + if (num < 10) { + return "0" + num; + } else { + return num; + } + }, + roundNumber: function(num, dec) { + return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); + }, + notesToHTML: function(notes) { + var i, note, notesHTML, _i, _len; + notesHTML = ''; + i = 1; + if (notes) { + for (_i = 0, _len = notes.length; _i < _len; _i++) { + note = notes[_i]; + notesHTML += "" + note['userid'] + "     " + (this.formatDate(note['created_at'])) + "

" + note['note'] + "

"; + notesHTML += "
"; + } + } + return notesHTML.replace("'", '"e'); + }, + formatPhone: function(n) { + var parts, phone, regexObj; + n = "" + n; + regexObj = /^(?:\+?1[-. ]?)?(?:\(?([0-9]{3})\)?[-. ]?)?([0-9]{3})[-. ]?([0-9]{4})$/; + if (regexObj.test(n)) { + parts = n.match(regexObj); + phone = ""; + if (parts[1]) { + phone += "(" + parts[1] + ") "; + } + phone += "" + parts[2] + "-" + parts[3]; + } else { + phone = n; + } + return phone; + }, + usStates: ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'District of Columbia', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'], + onboardingPages: ['applied', 'ready_to_interview', 'pending_interview', 'interviewed', 'accepted', 'ready_to_onboard', 'pending_onboarding', 'active', 'waitlisted', 'rejected'], + driverBreadCrumb: function(loc, model) { + var onboardingPage, out, _i, _len, _ref; + out = "Drivers > "; + if (!(model != null)) { + out += ""; + } else { + out += "" + (this.onboardingUrlToName(model.get('driver_status'))) + ""; + out += " > " + (this.linkedName(model)) + " (" + (model.get('role')) + ") #" + (model.get('id')); + } + return out; + }, + onboardingUrlToName: function(url) { + return url != null ? url.replace(/_/g, " ").replace(/(^|\s)([a-z])/g, function(m, p1, p2) { + return p1 + p2.toUpperCase(); + }) : void 0; + }, + formatVehicle: function(vehicle) { + if (vehicle.get('make') && vehicle.get('model') && vehicle.get('license_plate')) { + return "" + (vehicle.get('make')) + " " + (vehicle.get('model')) + " (" + (vehicle.get('license_plate')) + ")"; + } + }, + docArbitraryFields: function(docName, cityDocs) { + var doc, field, out, _i, _j, _len, _len2, _ref; + out = ""; + for (_i = 0, _len = cityDocs.length; _i < _len; _i++) { + doc = cityDocs[_i]; + if (doc.name === docName && __indexOf.call(_.keys(doc), "metaFields") >= 0) { + _ref = doc.metaFields; + for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) { + field = _ref[_j]; + out += "" + field.label + ":
"; + } + } + } + return out; + }, + capitaliseFirstLetter: function(string) { + return string.charAt(0).toUpperCase() + string.slice(1); + }, + createDocUploadForm: function(docName, driverId, vehicleId, cityMeta, vehicleName, expirationRequired) { + var ddocs, expDropdowns, pdocs, vdocs; + if (driverId == null) { + driverId = "None"; + } + if (vehicleId == null) { + vehicleId = "None"; + } + if (cityMeta == null) { + cityMeta = []; + } + if (vehicleName == null) { + vehicleName = false; + } + if (expirationRequired == null) { + expirationRequired = false; + } + ddocs = cityMeta["driverRequiredDocs"] || []; + pdocs = cityMeta["partnerRequiredDocs"] || []; + vdocs = cityMeta["vehicleRequiredDocs"] || []; + expDropdowns = "Expiration Date:\n -\n"; + return "
\n
\n \n \n \n\n
\n " + (vehicleName ? vehicleName : "") + " " + docName + "\n
\n\n
\n \n
\n\n
\n " + (expirationRequired ? expDropdowns : "") + "\n
\n\n
\n " + (app.helpers.docArbitraryFields(docName, _.union(ddocs, pdocs, vdocs))) + "\n
\n\n
\n \n
\n\n
\n
"; + }, + countrySelector: function(name, options) { + var countries, countryCodePrefix, defaultOptions; + if (options == null) { + options = {}; + } + defaultOptions = { + selectedKey: 'telephone_code', + selectedValue: '+1', + silent: false + }; + _.extend(defaultOptions, options); + options = defaultOptions; + countries = new app.collections.countries(); + countries.fetch({ + data: { + limit: 300 + }, + success: function(countries) { + var $option, $select, country, selected, _i, _len, _ref; + selected = false; + _ref = countries.models || []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + country = _ref[_i]; + $select = $("select[name=" + name + "]"); + $option = $('').val(country.id).attr('data-iso2', country.get('iso2')).attr('data-prefix', country.get('telephone_code')).html(country.get('name')); + if (country.get(options.selectedKey) === options.selectedValue && !selected) { + selected = true; + $option.attr('selected', 'selected'); + } + $select.append($option); + } + if (selected && !options.silent) { + return $select.val(options.selected).trigger('change'); + } + } + }); + countryCodePrefix = options.countryCodePrefix ? "data-country-code-prefix='" + options.countryCodePrefix + "'" : ''; + return ""; + }, + missingDocsOnDriver: function(driver) { + var city, docsReq, documents, partnerDocs; + city = driver.get('city'); + documents = driver.get('documents'); + if ((city != null) && (documents != null)) { + docsReq = _.pluck(city != null ? city.get('meta')["driverRequiredDocs"] : void 0, "name"); + if (driver.get('role') === "partner") { + partnerDocs = _.pluck(city != null ? city.get('meta')["partnerRequiredDocs"] : void 0, "name"); + docsReq = _.union(docsReq, partnerDocs); + } + return _.reject(docsReq, __bind(function(doc) { + return __indexOf.call((documents != null ? documents.pluck("name") : void 0) || [], doc) >= 0; + }, this)); + } else { + return []; + } + } + }; +}).call(this); +}, "web-lib/i18n": function(exports, require, module) {(function() { + exports.i18n = { + defaultLocale: 'en_US', + cookieName: '_LOCALE_', + locales: { + 'en_US': "English (US)", + 'fr_FR': "Français" + }, + currencyToLocale: { + 'USD': 'en_US', + 'EUR': 'fr_FR' + }, + logglyKey: 'd2d5a9bc-7ebe-4538-a180-81e62c705b1b', + logglyHost: 'https://logs.loggly.com', + init: function() { + this.castor = new window.loggly({ + url: this.logglyHost + '/inputs/' + this.logglyKey + '?rt=1', + level: 'error' + }); + this.setLocale($.cookie(this.cookieName) || this.defaultLocale); + window.t = _.bind(this.t, this); + this.loadLocaleTranslations(this.locale); + if (!(this[this.defaultLocale] != null)) { + return this.loadLocaleTranslations(this.defaultLocale); + } + }, + loadLocaleTranslations: function(locale) { + var loadPaths, path, _i, _len, _results; + loadPaths = ['web-lib/translations/' + locale, 'web-lib/translations/' + locale.slice(0, 2), 'translations/' + locale, 'translations/' + locale.slice(0, 2)]; + _results = []; + for (_i = 0, _len = loadPaths.length; _i < _len; _i++) { + path = loadPaths[_i]; + locale = path.substring(path.lastIndexOf('/') + 1); + if (this[locale] == null) { + this[locale] = {}; + } + _results.push((function() { + try { + return _.extend(this[locale], require(path).translations); + } catch (error) { + + } + }).call(this)); + } + return _results; + }, + getLocale: function() { + return this.locale; + }, + setLocale: function(locale) { + var message, parts, _ref; + parts = locale.split('_'); + this.locale = parts[0].toLowerCase(); + if (parts.length > 1) { + this.locale += "_" + (parts[1].toUpperCase()); + } + if (this.locale) { + $.cookie(this.cookieName, this.locale, { + path: '/', + domain: '.uber.com' + }); + } + try { + ((_ref = this.jsworld) != null ? _ref : this.jsworld = {}).lc = new jsworld.Locale(POSIX_LC[this.locale]); + this.jsworld.mf = new jsworld.MonetaryFormatter(this.jsworld.lc); + this.jsworld.nf = new jsworld.NumericFormatter(this.jsworld.lc); + this.jsworld.dtf = new jsworld.DateTimeFormatter(this.jsworld.lc); + this.jsworld.np = new jsworld.NumericParser(this.jsworld.lc); + this.jsworld.mp = new jsworld.MonetaryParser(this.jsworld.lc); + return this.jsworld.dtp = new jsworld.DateTimeParser(this.jsworld.lc); + } catch (error) { + message = 'JsWorld error with locale: ' + this.locale; + return this.log({ + message: message, + error: error + }); + } + }, + getTemplate: function(id) { + var _ref, _ref2; + return ((_ref = this[this.locale]) != null ? _ref[id] : void 0) || ((_ref2 = this[this.locale.slice(0, 2)]) != null ? _ref2[id] : void 0); + }, + getTemplateDefault: function(id) { + var _ref, _ref2; + return ((_ref = this[this.defaultLocale]) != null ? _ref[id] : void 0) || ((_ref2 = this[this.defaultLocale.slice(0, 2)]) != null ? _ref2[id] : void 0); + }, + getTemplateOrDefault: function(id) { + return this.getTemplate(id) || this.getTemplateDefault(id); + }, + t: function(id, vars) { + var errStr, locale, template; + if (vars == null) { + vars = {}; + } + locale = this.getLocale(); + template = this.getTemplate(id); + if (template == null) { + if (/dev|test/.test(window.location.host)) { + template = "(?) " + id; + } else { + template = this.getTemplateDefault(id); + } + errStr = "Missing [" + locale + "] translation for [" + id + "] at [" + window.location.hash + "] - Default template is [" + template + "]"; + this.log({ + error: errStr, + locale: locale, + id: id, + defaultTemplate: template + }); + } + if (template) { + return _.template(template, vars); + } else { + return id; + } + }, + log: function(error) { + if (/dev/.test(window.location.host)) { + if ((typeof console !== "undefined" && console !== null ? console.log : void 0) != null) { + return console.log(error); + } + } else { + _.extend(error, { + host: window.location.host, + hash: window.location.hash + }); + return this.castor.error(JSON.stringify(error)); + } + } + }; +}).call(this); +}, "web-lib/mixins/i18n_phone_form": function(exports, require, module) {(function() { + exports.i18nPhoneForm = { + _events: { + 'change select[data-country-code-prefix]': 'setCountryCodePrefix' + }, + setCountryCodePrefix: function(e) { + var $el, prefix; + $el = $(e.currentTarget); + prefix = $el.find('option:selected').attr('data-prefix'); + return $("#" + ($el.attr('data-country-code-prefix'))).text(prefix); + } + }; +}).call(this); +}, "web-lib/models/country": function(exports, require, module) {(function() { + var UberModel; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + UberModel = require('web-lib/uber_model').UberModel; + exports.Country = (function() { + __extends(Country, UberModel); + function Country() { + Country.__super__.constructor.apply(this, arguments); + } + Country.prototype.url = function() { + if (this.id) { + return "/countries/" + this.id; + } else { + return '/countries'; + } + }; + return Country; + })(); +}).call(this); +}, "web-lib/models/vehicle_type": function(exports, require, module) {(function() { + var UberModel; + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + UberModel = require('web-lib/uber_model').UberModel; + exports.VehicleType = (function() { + __extends(VehicleType, UberModel); + function VehicleType() { + this.toString = __bind(this.toString, this); + VehicleType.__super__.constructor.apply(this, arguments); + } + VehicleType.prototype.endpoint = 'vehicle_types'; + VehicleType.prototype.toTableRow = function(cols) { + var actions, c, capacity, city_id, columnValues, created_at, created_by_user_id, deleted_at, id, make, minimum_year, model, rows, type, updated_at, updated_by_user_id, _i, _len, _ref; + id = "" + (this.get('id')) + ""; + if (this.get('created_at')) { + created_at = app.helpers.formatDate(this.get('created_at')); + } + if (this.get('updated_at')) { + updated_at = app.helpers.formatDate(this.get('updated_at')); + } + if (this.get('deleted_at')) { + deleted_at = app.helpers.formatDate(this.get('deleted_at')); + } + created_by_user_id = "" + (this.get('created_by_user_id')) + ""; + updated_by_user_id = "" + (this.get('updated_by_user_id')) + ""; + city_id = (_ref = this.get('city')) != null ? _ref.get('display_name') : void 0; + type = this.get('type'); + make = this.get('make'); + model = this.get('model'); + capacity = this.get('capacity'); + minimum_year = this.get('minimum_year'); + actions = "Show"; + if (!this.get('deleted_at')) { + actions += " Edit"; + actions += " Delete"; + } + columnValues = { + id: id, + created_at: created_at, + updated_at: updated_at, + deleted_at: deleted_at, + created_by_user_id: created_by_user_id, + updated_by_user_id: updated_by_user_id, + city_id: city_id, + type: type, + make: make, + model: model, + capacity: capacity, + minimum_year: minimum_year, + actions: actions + }; + rows = []; + for (_i = 0, _len = cols.length; _i < _len; _i++) { + c = cols[_i]; + rows.push(columnValues[c] ? columnValues[c] : '-'); + } + return rows; + }; + VehicleType.prototype.toString = function() { + return this.get('make') + ' ' + this.get('model') + ' ' + this.get('type') + (" (" + (this.get('capacity')) + ")"); + }; + return VehicleType; + })(); +}).call(this); +}, "web-lib/templates/footer": function(exports, require, module) {module.exports = function(__obj) { + if (!__obj) __obj = {}; + var __out = [], __capture = function(callback) { + var out = __out, result; + __out = []; + callback.call(this); + result = __out.join(''); + __out = out; + return __safe(result); + }, __sanitize = function(value) { + if (value && value.ecoSafe) { + return value; + } else if (typeof value !== 'undefined' && value != null) { + return __escape(value); + } else { + return ''; + } + }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; + __safe = __obj.safe = function(value) { + if (value && value.ecoSafe) { + return value; + } else { + if (!(typeof value !== 'undefined' && value != null)) value = ''; + var result = new String(value); + result.ecoSafe = true; + return result; + } + }; + if (!__escape) { + __escape = __obj.escape = function(value) { + return ('' + value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + }; + } + (function() { + (function() { + var locale, title, _ref; + __out.push('\n\n\n\n\n'); + }).call(this); + + }).call(__obj); + __obj.safe = __objSafe, __obj.escape = __escape; + return __out.join(''); +}}, "web-lib/translations/en": function(exports, require, module) {(function() { + exports.translations = { + "Info": "Info", + "Learn More": "Learn More", + "Pricing": "Pricing", + "FAQ": "FAQ", + "Support": "Support", + "Support & FAQ": "Support & FAQ", + "Contact Us": "Contact Us", + "Jobs": "Jobs", + "Phones": "Phones", + "Text Message": "Text Message", + "iPhone": "iPhone", + "Android": "Android", + "Drivers": "Drivers", + "Apply": "Apply", + "Sign In": "Sign In", + "Social": "Social", + "Twitter": "Twitter", + "Facebook": "Facebook", + "Blog": "Blog", + "Legal": "Legal", + "Company_Footer": "Company", + "Privacy Policy": "Privacy Policy", + "Terms": "Terms", + "Copyright © Uber Technologies, Inc.": "Copyright © Uber Technologies, Inc.", + "Language:": "Language:", + "Apply to Drive": "Apply to Drive", + "Expiration": "Expiration", + "Fare": "Fare", + "Driver": "Driver ", + "Dashboard": "Dashboard", + "Forgot Password": "Forgot Password", + "Trip Details": "Trip Details", + "Save": "Save", + "Cancel": "Cancel", + "Edit": "Edit", + "Password": "Password", + "First Name": "First Name", + "Last Name": "Last Name", + "Email Address": "Email Address", + "Submit": "Submit", + "Mobile Number": "Mobile Number", + "Zip Code": "Zip Code", + "Sign Out": "Sign Out", + "Confirm Email Message": "Attempting to confirm email...", + "Upload": "Upload", + "Rating": "Rating", + "Pickup Time": "Pickup Time", + "2011": "2011", + "2012": "2012", + "2013": "2013", + "2014": "2014", + "2015": "2015", + "2016": "2016", + "2017": "2017", + "2018": "2018", + "2019": "2019", + "2020": "2020", + "2021": "2021", + "2022": "2022", + "01": "01", + "02": "02", + "03": "03", + "04": "04", + "05": "05", + "06": "06", + "07": "07", + "08": "08", + "09": "09", + "10": "10", + "11": "11", + "12": "12" + }; +}).call(this); +}, "web-lib/translations/fr": function(exports, require, module) {(function() { + exports.translations = { + "Info": "Info", + "Learn More": "En Savoir Plus", + "Pricing": "Calcul du Prix", + "Support & FAQ": "Aide & FAQ", + "Contact Us": "Contactez Nous", + "Jobs": "Emplois", + "Phones": "Téléphones", + "Text Message": "SMS", + "iPhone": "iPhone", + "Android": "Android", + "Apply to Drive": "Candidature Chauffeur", + "Sign In": "Connexion", + "Social": "Contact", + "Twitter": "Twitter", + "Facebook": "Facebook", + "Blog": "Blog", + "Privacy Policy": "Protection des Données Personelles", + "Terms": "Conditions Générales", + "Copyright © Uber Technologies, Inc.": "© Uber, Inc.", + "Language:": "Langue:", + "Forgot Password": "Mot de passe oublié", + "Company_Footer": "À Propos d'Uber", + "Expiration": "Expiration", + "Fare": "Tarif", + "Driver": "Chauffeur", + "Drivers": "Chauffeurs", + "Dashboard": "Tableau de bord", + "Forgot Password": "Mot de passe oublié", + "Forgot Password?": "Mot de passe oublié?", + "Trip Details": "Détails de la course", + "Save": "Enregistrer", + "Cancel": "Annuler", + "Edit": "Modifier", + "Password": "Mot de passe", + "First Name": "Prénom", + "Last Name": "Nom", + "Email Address": "E-mail", + "Submit": "Soumettre", + "Mobile Number": "Téléphone Portable", + "Zip Code": "Code Postal", + "Sign Out": "Se déconnecter", + "Confirm Email Message": "E-mail de confirmation", + "Upload": "Télécharger", + "Rating": "Notation", + "Pickup Time": "Heure de prise en charge", + "2011": "2011", + "2012": "2012", + "2013": "2013", + "2014": "2014", + "2015": "2015", + "2016": "2016", + "2017": "2017", + "2018": "2018", + "2019": "2019", + "2020": "2020", + "2021": "2021", + "2022": "2022", + "01": "01", + "02": "02", + "03": "03", + "04": "04", + "05": "05", + "06": "06", + "07": "07", + "08": "08", + "09": "09", + "10": "10", + "11": "11", + "12": "12" + }; +}).call(this); +}, "web-lib/uber_collection": function(exports, require, module) {(function() { + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + exports.UberCollection = (function() { + __extends(UberCollection, Backbone.Collection); + function UberCollection() { + UberCollection.__super__.constructor.apply(this, arguments); + } + UberCollection.prototype.parse = function(data) { + var model, tmp, _i, _in, _len, _out; + _in = data.resources || data; + _out = []; + if (data.meta) { + this.meta = data.meta; + } + for (_i = 0, _len = _in.length; _i < _len; _i++) { + model = _in[_i]; + tmp = new this.model; + tmp.set(tmp.parse(model)); + _out.push(tmp); + } + return _out; + }; + UberCollection.prototype.isRenderable = function() { + if (this.models.length) { + return true; + } + }; + UberCollection.prototype.toTableRows = function(cols) { + var tableRows; + tableRows = []; + _.each(this.models, function(model) { + return tableRows.push(model.toTableRow(cols)); + }); + return tableRows; + }; + return UberCollection; + })(); +}).call(this); +}, "web-lib/uber_model": function(exports, require, module) {(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }, __indexOf = Array.prototype.indexOf || function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (this[i] === item) return i; + } + return -1; + }; + exports.UberModel = (function() { + __extends(UberModel, Backbone.Model); + function UberModel() { + this.refetch = __bind(this.refetch, this); + this.fetch = __bind(this.fetch, this); + this.save = __bind(this.save, this); + this.parse = __bind(this.parse, this); + UberModel.__super__.constructor.apply(this, arguments); + } + UberModel.prototype.endpoint = 'set_api_endpoint_in_subclass'; + UberModel.prototype.refetchOptions = {}; + UberModel.prototype.url = function(type) { + var endpoint_path; + endpoint_path = "/" + this.endpoint; + if (this.get('id')) { + return endpoint_path + ("/" + (this.get('id'))); + } else { + return endpoint_path; + } + }; + UberModel.prototype.isRenderable = function() { + var i, key, value, _ref; + i = 0; + _ref = this.attributes; + for (key in _ref) { + if (!__hasProp.call(_ref, key)) continue; + value = _ref[key]; + if (this.attributes.hasOwnProperty(key)) { + i += 1; + } + if (i > 1) { + return true; + } + } + return !(i === 1); + }; + UberModel.prototype.parse = function(response) { + var attrs, key, model, models, _i, _j, _k, _len, _len2, _len3, _ref, _ref2; + if (typeof response === 'object') { + _ref = _.intersection(_.keys(app.models), _.keys(response)); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + key = _ref[_i]; + if (response[key]) { + attrs = this.parse(response[key]); + if (typeof attrs === 'object') { + response[key] = new app.models[key](attrs); + } + } + } + _ref2 = _.intersection(_.keys(app.collections), _.keys(response)); + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + key = _ref2[_j]; + models = response[key]; + if (_.isArray(models)) { + response[key] = new app.collections[key]; + for (_k = 0, _len3 = models.length; _k < _len3; _k++) { + model = models[_k]; + attrs = app.collections[key].prototype.model.prototype.parse(model); + response[key].add(new response[key].model(attrs)); + } + } + } + } + return response; + }; + UberModel.prototype.save = function(attributes, options) { + var attr, _i, _j, _len, _len2, _ref, _ref2; + if (options == null) { + options = {}; + } + _ref = _.intersection(_.keys(app.models), _.keys(this.attributes)); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + attr = _ref[_i]; + if (typeof this.get(attr) === "object") { + this.unset(attr, { + silent: true + }); + } + } + _ref2 = _.intersection(_.keys(app.collections), _.keys(this.attributes)); + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + attr = _ref2[_j]; + if (typeof this.get(attr) === "object") { + this.unset(attr, { + silent: true + }); + } + } + if ((options != null) && options.diff && (attributes != null) && attributes !== {}) { + attributes['id'] = this.get('id'); + attributes['token'] = this.get('token'); + this.clear({ + 'silent': true + }); + this.set(attributes, { + silent: true + }); + } + if (__indexOf.call(_.keys(options), "data") < 0 && __indexOf.call(_.keys(this.refetchOptions || {}), "data") >= 0) { + options.data = this.refetchOptions.data; + } + return Backbone.Model.prototype.save.call(this, attributes, options); + }; + UberModel.prototype.fetch = function(options) { + this.refetchOptions = options; + return Backbone.Model.prototype.fetch.call(this, options); + }; + UberModel.prototype.refetch = function() { + return this.fetch(this.refetchOptions); + }; + return UberModel; + })(); +}).call(this); +}, "web-lib/uber_router": function(exports, require, module) {(function() { + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + exports.UberRouter = (function() { + __extends(UberRouter, Backbone.Router); + function UberRouter() { + UberRouter.__super__.constructor.apply(this, arguments); + } + UberRouter.prototype.datePickers = function(format) { + if (format == null) { + format = "%Z-%m-%dT%H:%i:%s%:"; + } + $('.datepicker').AnyTime_noPicker(); + return $('.datepicker').AnyTime_picker({ + 'format': format, + 'formatUtcOffset': '%@' + }); + }; + UberRouter.prototype.autoGrowInput = function() { + return $('.editable input').autoGrowInput(); + }; + UberRouter.prototype.windowTitle = function(title) { + return $(document).attr('title', title); + }; + return UberRouter; + })(); +}).call(this); +}, "web-lib/uber_show_view": function(exports, require, module) {(function() { + var UberView; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + UberView = require('web-lib/uber_view').UberView; + exports.UberShowView = (function() { + __extends(UberShowView, UberView); + function UberShowView() { + UberShowView.__super__.constructor.apply(this, arguments); + } + UberShowView.prototype.view = 'show'; + UberShowView.prototype.events = { + 'click #edit': 'edit', + 'submit form': 'save', + 'click .cancel': 'cancel' + }; + UberShowView.prototype.errors = null; + UberShowView.prototype.showTemplate = null; + UberShowView.prototype.editTemplate = null; + UberShowView.prototype.initialize = function() { + if (this.init_hook) { + this.init_hook(); + } + _.bindAll(this, 'render'); + return this.model.bind('change', this.render); + }; + UberShowView.prototype.render = function() { + var $el; + $el = $(this.el); + this.selectView(); + if (this.view === 'show') { + $el.html(this.showTemplate({ + model: this.model + })); + } else if (this.view === 'edit') { + $el.html(this.editTemplate({ + model: this.model, + errors: this.errors || {}, + collections: this.collections || {} + })); + } else { + $el.html(this.newTemplate({ + model: this.model, + errors: this.errors || {}, + collections: this.collections || {} + })); + } + if (this.render_hook) { + this.render_hook(); + } + this.errors = null; + this.userIdsToLinkedNames(); + this.datePickers(); + return this.place(); + }; + UberShowView.prototype.selectView = function() { + var url; + if (this.options.urlRendering) { + url = window.location.hash; + if (url.match(/\/new/)) { + return this.view = 'new'; + } else if (url.match(/\/edit/)) { + return this.view = 'edit'; + } else { + return this.view = 'show'; + } + } + }; + UberShowView.prototype.edit = function(e) { + e.preventDefault(); + if (this.options.urlRendering) { + window.location.hash = '#/' + this.model.endpoint + '/' + this.model.get('id') + '/edit'; + } else { + this.view = 'edit'; + } + return this.model.change(); + }; + UberShowView.prototype.save = function(e) { + var attributes, ele, form_attrs, _i, _len, _ref; + e.preventDefault(); + attributes = $(e.currentTarget).serializeToJson(); + form_attrs = {}; + _ref = $('input[type="radio"]'); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + ele = _ref[_i]; + if ($(ele).is(':checked')) { + form_attrs[$(ele).attr('name')] = $(ele).attr('value'); + } + } + attributes = _.extend(attributes, form_attrs); + if (this.relationships) { + attributes = _.extend(attributes, { + relationships: this.relationships + }); + } + if (this.filter_attributes != null) { + this.filter_attributes(attributes); + } + return this.model.save(attributes, { + silent: true, + success: __bind(function(model) { + if (this.options.urlRendering) { + window.location.hash = '#/' + this.model.endpoint + '/' + this.model.get('id'); + } else { + this.view = 'show'; + } + return this.flash('success', "Uber save!"); + }, this), + statusCode: { + 406: __bind(function(xhr) { + this.errors = JSON.parse(xhr.responseText); + return this.flash('error', 'That was not Uber.'); + }, this) + }, + error: __bind(function(model, xhr) { + var code, message, responseJSON, responseText; + code = xhr.status; + responseText = xhr.responseText; + if (responseText) { + responseJSON = JSON.parse(responseText); + } + if (responseJSON && (typeof responseJSON === 'object') && (responseJSON.hasOwnProperty('error'))) { + message = responseJSON.error; + } + return this.flash('error', (code || 'Unknown') + ' error' + (': ' + message || '')); + }, this), + complete: __bind(function() { + return this.model.change(); + }, this) + }); + }; + UberShowView.prototype.cancel = function(e) { + e.preventDefault(); + if (this.options.urlRendering) { + window.location.hash = '#/' + this.model.endpoint + '/' + this.model.get('id'); + } else { + this.view = 'show'; + } + return this.model.fetch({ + silent: true, + complete: __bind(function() { + return this.model.change(); + }, this) + }); + }; + return UberShowView; + })(); +}).call(this); +}, "web-lib/uber_sync": function(exports, require, module) {(function() { + var methodType; + var __indexOf = Array.prototype.indexOf || function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (this[i] === item) return i; + } + return -1; + }; + methodType = { + create: 'POST', + update: 'PUT', + "delete": 'DELETE', + read: 'GET' + }; + exports.UberSync = function(method, model, options) { + var token; + options.type = methodType[method]; + options.url = _.isString(this.url) ? '/api' + this.url : '/api' + this.url(options.type); + options.data = _.extend({}, options.data); + if (__indexOf.call(_.keys(options.data), "city_id") < 0) { + if ($.cookie('city_filter')) { + _.extend(options.data, { + city_id: $.cookie('city_filter') + }); + } + } else { + delete options.data['city_id']; + } + if (options.type === 'POST' || options.type === 'PUT') { + _.extend(options.data, model.toJSON()); + } + token = $.cookie('token') ? $.cookie('token') : typeof USER !== "undefined" && USER !== null ? USER.get('token') : ""; + _.extend(options.data, { + token: token + }); + if (method === "delete") { + options.contentType = 'application/json'; + options.data = JSON.stringify(options.data); + } + return $.ajax(options); + }; +}).call(this); +}, "web-lib/uber_view": function(exports, require, module) {(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + exports.UberView = (function() { + __extends(UberView, Backbone.View); + function UberView() { + this.processDocumentUpload = __bind(this.processDocumentUpload, this); + UberView.__super__.constructor.apply(this, arguments); + } + UberView.prototype.className = 'view_container'; + UberView.prototype.hashId = function() { + return parseInt(location.hash.split('/')[2]); + }; + UberView.prototype.place = function(content) { + var $target; + $target = this.options.scope ? this.options.scope.find(this.options.selector) : $(this.options.selector); + $target[this.options.method || 'html'](content || this.el); + this.delegateEvents(); + $('#spinner').hide(); + return this; + }; + UberView.prototype.mixin = function(m, args) { + var events, self; + if (args == null) { + args = {}; + } + self = this; + events = m._events; + _.extend(this, m); + if (m.initialize) { + m.initialize(self, args); + } + return _.each(_.keys(events), function(key) { + var event, func, selector, split; + split = key.split(' '); + event = split[0]; + selector = split[1]; + func = events[key]; + return $(self.el).find(selector).live(event, function(e) { + return self[func](e); + }); + }); + }; + UberView.prototype.datePickers = function(format) { + if (format == null) { + format = "%Z-%m-%dT%H:%i:%s%:"; + } + $('.datepicker').AnyTime_noPicker(); + return $('.datepicker').AnyTime_picker({ + 'format': format, + 'formatUtcOffset': '%@' + }); + }; + UberView.prototype.dataTable = function(collection, selector, options, params, cols) { + var defaults; + if (selector == null) { + selector = 'table'; + } + if (options == null) { + options = {}; + } + if (params == null) { + params = {}; + } + if (cols == null) { + cols = []; + } + $(selector).empty(); + if (!cols.length) { + cols = collection.defaultColumns; + } + defaults = { + aoColumns: collection.tableColumns(cols), + bDestroy: true, + bSort: false, + bProcessing: true, + bFilter: false, + bServerSide: true, + bPaginate: true, + bScrollInfinite: true, + bScrollCollapse: true, + sScrollY: '600px', + iDisplayLength: 50, + fnServerData: function(source, data, callback) { + var defaultParams; + defaultParams = { + limit: data[4].value, + offset: data[3].value + }; + return collection.fetch({ + data: _.extend(defaultParams, params), + success: function() { + return callback({ + aaData: collection.toTableRows(cols), + iTotalRecords: collection.meta.count, + iTotalDisplayRecords: collection.meta.count + }); + }, + error: function() { + return new Error({ + message: 'Loading error.' + }); + } + }); + }, + fnRowCallback: function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { + $('[data-tooltip]', nRow).qtip({ + content: { + attr: 'data-tooltip' + }, + style: { + classes: "ui-tooltip-light ui-tooltip-rounded ui-tooltip-shadow" + } + }); + return nRow; + } + }; + return $(this.el).find(selector).dataTable(_.extend(defaults, options)); + }; + UberView.prototype.dataTableLocal = function(collection, selector, options, params, cols) { + var $dataTable, defaults; + if (selector == null) { + selector = 'table'; + } + if (options == null) { + options = {}; + } + if (params == null) { + params = {}; + } + if (cols == null) { + cols = []; + } + $(selector).empty(); + if (!cols.length || cols.length === 0) { + cols = collection.defaultColumns; + } + defaults = { + aaData: collection.toTableRows(cols), + aoColumns: collection.tableColumns(cols), + bDestroy: true, + bSort: false, + bProcessing: true, + bFilter: false, + bScrollInfinite: true, + bScrollCollapse: true, + sScrollY: '600px', + iDisplayLength: -1 + }; + $dataTable = $(this.el).find(selector).dataTable(_.extend(defaults, options)); + _.delay(__bind(function() { + if ($dataTable && $dataTable.length > 0) { + return $dataTable.fnAdjustColumnSizing(); + } + }, this), 1); + return $dataTable; + }; + UberView.prototype.reverseGeocode = function() { + var $el; + return ''; + $el = $(this.el); + return this.requireMaps(function() { + var geocoder; + geocoder = new google.maps.Geocoder(); + return $el.find('[data-point]').each(function() { + var $this, latLng, point; + $this = $(this); + point = JSON.parse($this.attr('data-point')); + latLng = new google.maps.LatLng(point.latitude, point.longitude); + return geocoder.geocode({ + latLng: latLng + }, function(data, status) { + if (status === google.maps.GeocoderStatus.OK) { + return $this.text(data[0].formatted_address); + } + }); + }); + }); + }; + UberView.prototype.userIdsToLinkedNames = function() { + var $el; + $el = $(this.el); + return $el.find('a[data-user-id][data-user-type]').each(function() { + var $this, user, userType; + $this = $(this); + userType = $this.attr('data-user-type') === 'user' ? 'client' : $this.attr('data-user-type'); + user = new app.models[userType]({ + id: $this.attr('data-user-id') + }); + return user.fetch({ + success: function(user) { + return $this.html(app.helpers.linkedName(user)).attr('href', "!/" + user.role + "s/" + user.id); + }, + error: function() { + if ($this.attr('data-user-type') === 'user') { + user = new app.models['driver']({ + id: $this.attr('data-user-id') + }); + return user.fetch({ + success: function(user) { + return $this.html(app.helpers.linkedName(user)).attr('href', "!/driver/" + user.id); + } + }); + } + } + }); + }); + }; + UberView.prototype.selectedCity = function() { + var $selected, city, cityFilter; + cityFilter = $.cookie('city_filter'); + $selected = $("#city_filter option[value=" + cityFilter + "]"); + if (city_filter && $selected.length) { + return city = { + lat: parseFloat($selected.attr('data-lat')), + lng: parseFloat($selected.attr('data-lng')), + timezone: $selected.attr('data-timezone') + }; + } else { + return city = { + lat: 37.775, + lng: -122.45, + timezone: 'Etc/UTC' + }; + } + }; + UberView.prototype.updateModel = function(e, success) { + var $el, attrs, model, self; + e.preventDefault(); + $el = $(e.currentTarget); + self = this; + model = new this.model.__proto__.constructor({ + id: this.model.id + }); + attrs = {}; + $el.find('[name]').each(function() { + var $this; + $this = $(this); + return attrs["" + ($this.attr('name'))] = $this.val(); + }); + self.model.set(attrs); + $el.find('span.error').text(''); + return model.save(attrs, { + complete: function(xhr) { + var response; + response = JSON.parse(xhr.responseText); + switch (xhr.status) { + case 200: + self.model = model; + $el.find('[name]').val(''); + if (success) { + return success(); + } + break; + case 406: + return _.each(response, function(error, field) { + return $el.find("[name=" + field + "]").parent().find('span.error').text(error); + }); + default: + return this.unanticipatedError(response); + } + } + }); + }; + UberView.prototype.autoUpdateModel = function(e) { + var $el, arg, model, self, val; + $el = $(e.currentTarget); + val = $el.val(); + self = this; + if (val !== this.model.get($el.attr('id'))) { + arg = {}; + arg[$el.attr('id')] = $el.is(':checkbox') ? $el.is(':checked') ? 1 : 0 : val; + $('.editable span').empty(); + this.model.set(arg); + model = new this.model.__proto__.constructor({ + id: this.model.id + }); + return model.save(arg, { + complete: function(xhr) { + var key, response, _i, _len, _ref, _results; + response = JSON.parse(xhr.responseText); + switch (xhr.status) { + case 200: + self.flash('success', 'Saved!'); + return $el.blur(); + case 406: + self.flash('error', 'That was not Uber.'); + _ref = _.keys(response); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + key = _ref[_i]; + _results.push($el.parent().find('span').html(response[key])); + } + return _results; + break; + default: + return self.unanticipatedError; + } + } + }); + } + }; + UberView.prototype.unanticipatedError = function(response) { + return self.flash('error', response); + }; + UberView.prototype.flash = function(type, text) { + var $banner; + $banner = $("." + type); + $banner.find('p').text(text).end().css('border', '1px solid #999').animate({ + top: 0 + }, 500); + return setTimeout(function() { + return $banner.animate({ + top: -$banner.outerHeight() + }, 500); + }, 3000); + }; + UberView.prototype.requireMaps = function(callback) { + if (typeof google !== 'undefined' && google.maps) { + return callback(); + } else { + return $.getScript("https://www.google.com/jsapi?key=" + CONFIG.googleJsApiKey, function() { + return google.load('maps', 3, { + callback: callback, + other_params: 'sensor=false&language=en' + }); + }); + } + }; + UberView.prototype.select_drop_down = function(model, key) { + var value; + value = model.get(key); + if (value) { + return $("select[id='" + key + "'] option[value='" + value + "']").attr('selected', 'selected'); + } + }; + UberView.prototype.processDocumentUpload = function(e) { + var $fi, $form, arbData, curDate, data, expDate, expM, expY, expiration, fileElementId, invalid; + e.preventDefault(); + $form = $(e.currentTarget); + $fi = $("input[type=file]", $form); + $(".validationError").removeClass("validationError"); + if (!$fi.val()) { + return $fi.addClass("validationError"); + } else { + fileElementId = $fi.attr('id'); + expY = $("select[name=expiration-year]", $form).val(); + expM = $("select[name=expiration-month]", $form).val(); + invalid = false; + if (expY && expM) { + expDate = new Date(expY, expM, 28); + curDate = new Date(); + if (expDate < curDate) { + invalid = true; + $(".expiration", $form).addClass("validationError"); + } + expiration = "" + expY + "-" + expM + "-28T23:59:59Z"; + } + arbData = {}; + $(".arbitraryField", $form).each(__bind(function(i, e) { + arbData[$(e).attr('name')] = $(e).val(); + if ($(e).val() === "") { + invalid = true; + return $(e).addClass("validationError"); + } + }, this)); + if (!invalid) { + data = { + token: $.cookie('token') || USER.get('token'), + name: $("input[name=fileName]", $form).val(), + meta: escape(JSON.stringify(arbData)), + user_id: $("input[name=driver_id]", $form).val(), + vehicle_id: $("input[name=vehicle_id]", $form).val() + }; + if (expiration) { + data['expiration'] = expiration; + } + $("#spinner").show(); + return $.ajaxFileUpload({ + url: '/api/documents', + secureuri: false, + fileElementId: fileElementId, + data: data, + complete: __bind(function(resp, status) { + var key, _i, _len, _ref, _results; + $("#spinner").hide(); + if (status === "success") { + if (this.model) { + this.model.refetch(); + } else { + USER.refetch(); + } + } + if (status === "error") { + _ref = _.keys(resp); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + key = _ref[_i]; + _results.push($("*[name=" + key + "]", $form).addClass("validationError")); + } + return _results; + } + }, this) + }); + } + } + }; + return UberView; + })(); +}).call(this); +}, "web-lib/views/footer": function(exports, require, module) {(function() { + var footerTemplate; + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; + }; + footerTemplate = require('web-lib/templates/footer'); + exports.SharedFooterView = (function() { + __extends(SharedFooterView, Backbone.View); + function SharedFooterView() { + SharedFooterView.__super__.constructor.apply(this, arguments); + } + SharedFooterView.prototype.id = 'footer_view'; + SharedFooterView.prototype.events = { + 'click .language': 'intl_set_cookie_locale' + }; + SharedFooterView.prototype.render = function() { + $(this.el).html(footerTemplate()); + this.delegateEvents(); + return this; + }; + SharedFooterView.prototype.intl_set_cookie_locale = function(e) { + var _ref; + i18n.setLocale(e != null ? (_ref = e.srcElement) != null ? _ref.id : void 0 : void 0); + return location.reload(); + }; + return SharedFooterView; + })(); +}).call(this); +}}); diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/embed-tokens.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/embed-tokens.js new file mode 100755 index 0000000..61307ee --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/embed-tokens.js @@ -0,0 +1,15 @@ +#! /usr/bin/env node + +global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util"); +var fs = require("fs"); +var uglify = require("uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js + jsp = uglify.parser, + pro = uglify.uglify; + +var code = fs.readFileSync("embed-tokens.js", "utf8").replace(/^#.*$/mg, ""); +var ast = jsp.parse(code, null, true); + +// trololo +function fooBar() {} + +console.log(sys.inspect(ast, null, null)); diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto.js new file mode 100644 index 0000000..945960c --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto.js @@ -0,0 +1,26 @@ +function unique(arqw) { + var a = [], i, j + outer: for (i = 0; i < arqw.length; i++) { + for (j = 0; j < a.length; j++) { + if (a[j] == arqw[i]) { + continue outer + } + } + a[a.length] = arqw[i] + } + return a +} + + +function unique(arqw) { + var crap = [], i, j + outer: for (i = 0; i < arqw.length; i++) { + for (j = 0; j < crap.length; j++) { + if (crap[j] == arqw[i]) { + continue outer + } + } + crap[crap.length] = arqw[i] + } + return crap +} diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto2.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto2.js new file mode 100644 index 0000000..d13b2bc --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto2.js @@ -0,0 +1,8 @@ +function q(qooo) { + var a; + foo: for(;;) { + a++; + if (something) break foo; + return qooo; + } +} diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/hoist.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/hoist.js new file mode 100644 index 0000000..4bf2b94 --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/hoist.js @@ -0,0 +1,33 @@ +function foo(arg1, arg2, arg3, arg4, arg5, arg6) { + var a = 5; + { + var d = 10, mak = 20, buz = 30; + var q = buz * 2; + } + if (moo) { + var a, b, c; + } + for (var arg1 = 0, d = 20; arg1 < 10; ++arg1) + console.log(arg3); + for (var i in mak) {} + for (j in d) {} + var d; + + function test() { + + }; + + //test(); + + (function moo(first, second){ + console.log(first); + })(1); + + (function moo(first, second){ + console.log(moo()); + })(1); +} + + +var foo; +var bar; diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument.js new file mode 100644 index 0000000..c6a9d79 --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument.js @@ -0,0 +1,97 @@ +// sample on how to use the parser and walker API to instrument some code + +var jsp = require("uglify-js").parser; +var pro = require("uglify-js").uglify; + +function instrument(code) { + var ast = jsp.parse(code, false, true); // true for the third arg specifies that we want + // to have start/end tokens embedded in the + // statements + var w = pro.ast_walker(); + + // we're gonna need this to push elements that we're currently looking at, to avoid + // endless recursion. + var analyzing = []; + function do_stat() { + var ret; + if (this[0].start && analyzing.indexOf(this) < 0) { + // without the `analyzing' hack, w.walk(this) would re-enter here leading + // to infinite recursion + analyzing.push(this); + ret = [ "splice", // XXX: "block" is safer + [ [ "stat", + [ "call", [ "name", "trace" ], + [ [ "string", this[0].toString() ], + [ "num", this[0].start.line ], + [ "num", this[0].start.col ], + [ "num", this[0].end.line ], + [ "num", this[0].end.col ]]]], + w.walk(this) ]]; + analyzing.pop(this); + } + return ret; + }; + var new_ast = w.with_walkers({ + "stat" : do_stat, + "label" : do_stat, + "break" : do_stat, + "continue" : do_stat, + "debugger" : do_stat, + "var" : do_stat, + "const" : do_stat, + "return" : do_stat, + "throw" : do_stat, + "try" : do_stat, + "defun" : do_stat, + "if" : do_stat, + "while" : do_stat, + "do" : do_stat, + "for" : do_stat, + "for-in" : do_stat, + "switch" : do_stat, + "with" : do_stat + }, function(){ + return w.walk(ast); + }); + return pro.gen_code(new_ast, { beautify: true }); +} + + + + +////// test code follows. + +var code = instrument(test.toString()); +console.log(code); + +function test() { + // simple stats + a = 5; + c += a + b; + "foo"; + + // var + var foo = 5; + const bar = 6, baz = 7; + + // switch block. note we can't track case lines the same way. + switch ("foo") { + case "foo": + return 1; + case "bar": + return 2; + } + + // for/for in + for (var i = 0; i < 5; ++i) { + console.log("Hello " + i); + } + for (var i in [ 1, 2, 3]) { + console.log(i); + } + + // note however that the following is broken. I guess we + // should add the block brackets in this case... + for (var i = 0; i < 5; ++i) + console.log("foo"); +} diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument2.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument2.js new file mode 100644 index 0000000..6aee5f3 --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument2.js @@ -0,0 +1,138 @@ +// sample on how to use the parser and walker API to instrument some code + +var jsp = require("uglify-js").parser; +var pro = require("uglify-js").uglify; + +function instrument(code) { + var ast = jsp.parse(code, false, true); // true for the third arg specifies that we want + // to have start/end tokens embedded in the + // statements + var w = pro.ast_walker(); + + function trace (line, comment) { + var code = pro.gen_code(line, { beautify: true }); + var data = line[0] + + var args = [] + if (!comment) comment = "" + if (typeof data === "object") { + code = code.split(/\n/).shift() + args = [ [ "string", data.toString() ], + [ "string", code ], + [ "num", data.start.line ], + [ "num", data.start.col ], + [ "num", data.end.line ], + [ "num", data.end.col ]] + } else { + args = [ [ "string", data ], + [ "string", code ]] + + } + return [ "call", [ "name", "trace" ], args ]; + } + + // we're gonna need this to push elements that we're currently looking at, to avoid + // endless recursion. + var analyzing = []; + function do_stat() { + var ret; + if (this[0].start && analyzing.indexOf(this) < 0) { + // without the `analyzing' hack, w.walk(this) would re-enter here leading + // to infinite recursion + analyzing.push(this); + ret = [ "splice", + [ [ "stat", trace(this) ], + w.walk(this) ]]; + analyzing.pop(this); + } + return ret; + } + + function do_cond(c, t, f) { + return [ this[0], w.walk(c), + ["seq", trace(t), w.walk(t) ], + ["seq", trace(f), w.walk(f) ]]; + } + + function do_binary(c, l, r) { + if (c !== "&&" && c !== "||") { + return [this[0], c, w.walk(l), w.walk(r)]; + } + return [ this[0], c, + ["seq", trace(l), w.walk(l) ], + ["seq", trace(r), w.walk(r) ]]; + } + + var new_ast = w.with_walkers({ + "stat" : do_stat, + "label" : do_stat, + "break" : do_stat, + "continue" : do_stat, + "debugger" : do_stat, + "var" : do_stat, + "const" : do_stat, + "return" : do_stat, + "throw" : do_stat, + "try" : do_stat, + "defun" : do_stat, + "if" : do_stat, + "while" : do_stat, + "do" : do_stat, + "for" : do_stat, + "for-in" : do_stat, + "switch" : do_stat, + "with" : do_stat, + "conditional" : do_cond, + "binary" : do_binary + }, function(){ + return w.walk(ast); + }); + return pro.gen_code(new_ast, { beautify: true }); +} + + +////// test code follows. + +var code = instrument(test.toString()); +console.log(code); + +function test() { + // simple stats + a = 5; + c += a + b; + "foo"; + + // var + var foo = 5; + const bar = 6, baz = 7; + + // switch block. note we can't track case lines the same way. + switch ("foo") { + case "foo": + return 1; + case "bar": + return 2; + } + + // for/for in + for (var i = 0; i < 5; ++i) { + console.log("Hello " + i); + } + for (var i in [ 1, 2, 3]) { + console.log(i); + } + + for (var i = 0; i < 5; ++i) + console.log("foo"); + + for (var i = 0; i < 5; ++i) { + console.log("foo"); + } + + var k = plurp() ? 1 : 0; + var x = a ? doX(y) && goZoo("zoo") + : b ? blerg({ x: y }) + : null; + + var x = X || Y; +} diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/liftvars.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/liftvars.js new file mode 100644 index 0000000..2f4b7fe --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/liftvars.js @@ -0,0 +1,8 @@ +var UNUSED_VAR1 = 19; + +function main() { + var unused_var2 = 20; + alert(100); +} + +main(); diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/test.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/test.js new file mode 100755 index 0000000..f295fba --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/test.js @@ -0,0 +1,30 @@ +#! /usr/bin/env node + +global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util"); +var fs = require("fs"); +var uglify = require("uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js + jsp = uglify.parser, + pro = uglify.uglify; + +var code = fs.readFileSync("hoist.js", "utf8"); +var ast = jsp.parse(code); + +ast = pro.ast_lift_variables(ast); + +var w = pro.ast_walker(); +ast = w.with_walkers({ + "function": function() { + var node = w.dive(this); // walk depth first + console.log(pro.gen_code(node, { beautify: true })); + return node; + }, + "name": function(name) { + return [ this[0], "X" ]; + } +}, function(){ + return w.walk(ast); +}); + +console.log(pro.gen_code(ast, { + beautify: true +})); diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs.js new file mode 100644 index 0000000..0d5b7e0 --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs.js @@ -0,0 +1,3930 @@ +/** + * @fileoverview + * + * JsWorld + * + *

Javascript library for localised formatting and parsing of: + *

    + *
  • Numbers + *
  • Dates and times + *
  • Currency + *
+ * + *

The library classes are configured with standard POSIX locale definitions + * derived from Unicode's Common Locale Data Repository (CLDR). + * + *

Website: JsWorld + * + * @author Vladimir Dzhuvinov + * @version 2.5 (2011-12-23) + */ + + + +/** + * @namespace Namespace container for the JsWorld library objects. + */ +jsworld = {}; + + +/** + * @function + * + * @description Formats a JavaScript Date object as an ISO-8601 date/time + * string. + * + * @param {Date} [d] A valid JavaScript Date object. If undefined the + * current date/time will be used. + * @param {Boolean} [withTZ] Include timezone offset, default false. + * + * @returns {String} The date/time formatted as YYYY-MM-DD HH:MM:SS. + */ +jsworld.formatIsoDateTime = function(d, withTZ) { + + if (typeof d === "undefined") + d = new Date(); // now + + if (typeof withTZ === "undefined") + withTZ = false; + + var s = jsworld.formatIsoDate(d) + " " + jsworld.formatIsoTime(d); + + if (withTZ) { + + var diff = d.getHours() - d.getUTCHours(); + var hourDiff = Math.abs(diff); + + var minuteUTC = d.getUTCMinutes(); + var minute = d.getMinutes(); + + if (minute != minuteUTC && minuteUTC < 30 && diff < 0) + hourDiff--; + + if (minute != minuteUTC && minuteUTC > 30 && diff > 0) + hourDiff--; + + var minuteDiff; + if (minute != minuteUTC) + minuteDiff = ":30"; + else + minuteDiff = ":00"; + + var timezone; + if (hourDiff < 10) + timezone = "0" + hourDiff + minuteDiff; + + else + timezone = "" + hourDiff + minuteDiff; + + if (diff < 0) + timezone = "-" + timezone; + + else + timezone = "+" + timezone; + + s = s + timezone; + } + + return s; +}; + + +/** + * @function + * + * @description Formats a JavaScript Date object as an ISO-8601 date string. + * + * @param {Date} [d] A valid JavaScript Date object. If undefined the current + * date will be used. + * + * @returns {String} The date formatted as YYYY-MM-DD. + */ +jsworld.formatIsoDate = function(d) { + + if (typeof d === "undefined") + d = new Date(); // now + + var year = d.getFullYear(); + var month = d.getMonth() + 1; + var day = d.getDate(); + + return year + "-" + jsworld._zeroPad(month, 2) + "-" + jsworld._zeroPad(day, 2); +}; + + +/** + * @function + * + * @description Formats a JavaScript Date object as an ISO-8601 time string. + * + * @param {Date} [d] A valid JavaScript Date object. If undefined the current + * time will be used. + * + * @returns {String} The time formatted as HH:MM:SS. + */ +jsworld.formatIsoTime = function(d) { + + if (typeof d === "undefined") + d = new Date(); // now + + var hour = d.getHours(); + var minute = d.getMinutes(); + var second = d.getSeconds(); + + return jsworld._zeroPad(hour, 2) + ":" + jsworld._zeroPad(minute, 2) + ":" + jsworld._zeroPad(second, 2); +}; + + +/** + * @function + * + * @description Parses an ISO-8601 formatted date/time string to a JavaScript + * Date object. + * + * @param {String} isoDateTimeVal An ISO-8601 formatted date/time string. + * + *

Accepted formats: + * + *

    + *
  • YYYY-MM-DD HH:MM:SS + *
  • YYYYMMDD HHMMSS + *
  • YYYY-MM-DD HHMMSS + *
  • YYYYMMDD HH:MM:SS + *
+ * + * @returns {Date} The corresponding Date object. + * + * @throws Error on a badly formatted date/time string or on a invalid date. + */ +jsworld.parseIsoDateTime = function(isoDateTimeVal) { + + if (typeof isoDateTimeVal != "string") + throw "Error: The parameter must be a string"; + + // First, try to match "YYYY-MM-DD HH:MM:SS" format + var matches = isoDateTimeVal.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/); + + // If unsuccessful, try to match "YYYYMMDD HHMMSS" format + if (matches === null) + matches = isoDateTimeVal.match(/^(\d\d\d\d)(\d\d)(\d\d)[T ](\d\d)(\d\d)(\d\d)/); + + // ... try to match "YYYY-MM-DD HHMMSS" format + if (matches === null) + matches = isoDateTimeVal.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d)(\d\d)(\d\d)/); + + // ... try to match "YYYYMMDD HH:MM:SS" format + if (matches === null) + matches = isoDateTimeVal.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/); + + // Report bad date/time string + if (matches === null) + throw "Error: Invalid ISO-8601 date/time string"; + + // Force base 10 parse int as some values may have leading zeros! + // (to avoid implicit octal base conversion) + var year = parseInt(matches[1], 10); + var month = parseInt(matches[2], 10); + var day = parseInt(matches[3], 10); + + var hour = parseInt(matches[4], 10); + var mins = parseInt(matches[5], 10); + var secs = parseInt(matches[6], 10); + + // Simple value range check, leap years not checked + // Note: the originial ISO time spec for leap hours (24:00:00) and seconds (00:00:60) is not supported + if (month < 1 || month > 12 || + day < 1 || day > 31 || + hour < 0 || hour > 23 || + mins < 0 || mins > 59 || + secs < 0 || secs > 59 ) + + throw "Error: Invalid ISO-8601 date/time value"; + + var d = new Date(year, month - 1, day, hour, mins, secs); + + // Check if the input date was valid + // (JS Date does automatic forward correction) + if (d.getDate() != day || d.getMonth() +1 != month) + throw "Error: Invalid date"; + + return d; +}; + + +/** + * @function + * + * @description Parses an ISO-8601 formatted date string to a JavaScript + * Date object. + * + * @param {String} isoDateVal An ISO-8601 formatted date string. + * + *

Accepted formats: + * + *

    + *
  • YYYY-MM-DD + *
  • YYYYMMDD + *
+ * + * @returns {Date} The corresponding Date object. + * + * @throws Error on a badly formatted date string or on a invalid date. + */ +jsworld.parseIsoDate = function(isoDateVal) { + + if (typeof isoDateVal != "string") + throw "Error: The parameter must be a string"; + + // First, try to match "YYYY-MM-DD" format + var matches = isoDateVal.match(/^(\d\d\d\d)-(\d\d)-(\d\d)/); + + // If unsuccessful, try to match "YYYYMMDD" format + if (matches === null) + matches = isoDateVal.match(/^(\d\d\d\d)(\d\d)(\d\d)/); + + // Report bad date/time string + if (matches === null) + throw "Error: Invalid ISO-8601 date string"; + + // Force base 10 parse int as some values may have leading zeros! + // (to avoid implicit octal base conversion) + var year = parseInt(matches[1], 10); + var month = parseInt(matches[2], 10); + var day = parseInt(matches[3], 10); + + // Simple value range check, leap years not checked + if (month < 1 || month > 12 || + day < 1 || day > 31 ) + + throw "Error: Invalid ISO-8601 date value"; + + var d = new Date(year, month - 1, day); + + // Check if the input date was valid + // (JS Date does automatic forward correction) + if (d.getDate() != day || d.getMonth() +1 != month) + throw "Error: Invalid date"; + + return d; +}; + + +/** + * @function + * + * @description Parses an ISO-8601 formatted time string to a JavaScript + * Date object. + * + * @param {String} isoTimeVal An ISO-8601 formatted time string. + * + *

Accepted formats: + * + *

    + *
  • HH:MM:SS + *
  • HHMMSS + *
+ * + * @returns {Date} The corresponding Date object, with year, month and day set + * to zero. + * + * @throws Error on a badly formatted time string. + */ +jsworld.parseIsoTime = function(isoTimeVal) { + + if (typeof isoTimeVal != "string") + throw "Error: The parameter must be a string"; + + // First, try to match "HH:MM:SS" format + var matches = isoTimeVal.match(/^(\d\d):(\d\d):(\d\d)/); + + // If unsuccessful, try to match "HHMMSS" format + if (matches === null) + matches = isoTimeVal.match(/^(\d\d)(\d\d)(\d\d)/); + + // Report bad date/time string + if (matches === null) + throw "Error: Invalid ISO-8601 date/time string"; + + // Force base 10 parse int as some values may have leading zeros! + // (to avoid implicit octal base conversion) + var hour = parseInt(matches[1], 10); + var mins = parseInt(matches[2], 10); + var secs = parseInt(matches[3], 10); + + // Simple value range check, leap years not checked + if (hour < 0 || hour > 23 || + mins < 0 || mins > 59 || + secs < 0 || secs > 59 ) + + throw "Error: Invalid ISO-8601 time value"; + + return new Date(0, 0, 0, hour, mins, secs); +}; + + +/** + * @private + * + * @description Trims leading and trailing whitespace from a string. + * + *

Used non-regexp the method from http://blog.stevenlevithan.com/archives/faster-trim-javascript + * + * @param {String} str The string to trim. + * + * @returns {String} The trimmed string. + */ +jsworld._trim = function(str) { + + var whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000'; + + for (var i = 0; i < str.length; i++) { + + if (whitespace.indexOf(str.charAt(i)) === -1) { + str = str.substring(i); + break; + } + } + + for (i = str.length - 1; i >= 0; i--) { + if (whitespace.indexOf(str.charAt(i)) === -1) { + str = str.substring(0, i + 1); + break; + } + } + + return whitespace.indexOf(str.charAt(0)) === -1 ? str : ''; +}; + + + +/** + * @private + * + * @description Returns true if the argument represents a decimal number. + * + * @param {Number|String} arg The argument to test. + * + * @returns {Boolean} true if the argument represents a decimal number, + * otherwise false. + */ +jsworld._isNumber = function(arg) { + + if (typeof arg == "number") + return true; + + if (typeof arg != "string") + return false; + + // ensure string + var s = arg + ""; + + return (/^-?(\d+|\d*\.\d+)$/).test(s); +}; + + +/** + * @private + * + * @description Returns true if the argument represents a decimal integer. + * + * @param {Number|String} arg The argument to test. + * + * @returns {Boolean} true if the argument represents an integer, otherwise + * false. + */ +jsworld._isInteger = function(arg) { + + if (typeof arg != "number" && typeof arg != "string") + return false; + + // convert to string + var s = arg + ""; + + return (/^-?\d+$/).test(s); +}; + + +/** + * @private + * + * @description Returns true if the argument represents a decimal float. + * + * @param {Number|String} arg The argument to test. + * + * @returns {Boolean} true if the argument represents a float, otherwise false. + */ +jsworld._isFloat = function(arg) { + + if (typeof arg != "number" && typeof arg != "string") + return false; + + // convert to string + var s = arg + ""; + + return (/^-?\.\d+?$/).test(s); +}; + + +/** + * @private + * + * @description Checks if the specified formatting option is contained + * within the options string. + * + * @param {String} option The option to search for. + * @param {String} optionsString The options string. + * + * @returns {Boolean} true if the flag is found, else false + */ +jsworld._hasOption = function(option, optionsString) { + + if (typeof option != "string" || typeof optionsString != "string") + return false; + + if (optionsString.indexOf(option) != -1) + return true; + else + return false; +}; + + +/** + * @private + * + * @description String replacement function. + * + * @param {String} s The string to work on. + * @param {String} target The string to search for. + * @param {String} replacement The replacement. + * + * @returns {String} The new string. + */ +jsworld._stringReplaceAll = function(s, target, replacement) { + + var out; + + if (target.length == 1 && replacement.length == 1) { + // simple char/char case somewhat faster + out = ""; + + for (var i = 0; i < s.length; i++) { + + if (s.charAt(i) == target.charAt(0)) + out = out + replacement.charAt(0); + else + out = out + s.charAt(i); + } + + return out; + } + else { + // longer target and replacement strings + out = s; + + var index = out.indexOf(target); + + while (index != -1) { + + out = out.replace(target, replacement); + + index = out.indexOf(target); + } + + return out; + } +}; + + +/** + * @private + * + * @description Tests if a string starts with the specified substring. + * + * @param {String} testedString The string to test. + * @param {String} sub The string to match. + * + * @returns {Boolean} true if the test succeeds. + */ +jsworld._stringStartsWith = function (testedString, sub) { + + if (testedString.length < sub.length) + return false; + + for (var i = 0; i < sub.length; i++) { + if (testedString.charAt(i) != sub.charAt(i)) + return false; + } + + return true; +}; + + +/** + * @private + * + * @description Gets the requested precision from an options string. + * + *

Example: ".3" returns 3 decimal places precision. + * + * @param {String} optionsString The options string. + * + * @returns {integer Number} The requested precision, -1 if not specified. + */ +jsworld._getPrecision = function (optionsString) { + + if (typeof optionsString != "string") + return -1; + + var m = optionsString.match(/\.(\d)/); + if (m) + return parseInt(m[1], 10); + else + return -1; +}; + + +/** + * @private + * + * @description Takes a decimal numeric amount (optionally as string) and + * returns its integer and fractional parts packed into an object. + * + * @param {Number|String} amount The amount, e.g. "123.45" or "-56.78" + * + * @returns {object} Parsed amount object with properties: + * {String} integer : the integer part + * {String} fraction : the fraction part + */ +jsworld._splitNumber = function (amount) { + + if (typeof amount == "number") + amount = amount + ""; + + var obj = {}; + + // remove negative sign + if (amount.charAt(0) == "-") + amount = amount.substring(1); + + // split amount into integer and decimal parts + var amountParts = amount.split("."); + if (!amountParts[1]) + amountParts[1] = ""; // we need "" instead of null + + obj.integer = amountParts[0]; + obj.fraction = amountParts[1]; + + return obj; +}; + + +/** + * @private + * + * @description Formats the integer part using the specified grouping + * and thousands separator. + * + * @param {String} intPart The integer part of the amount, as string. + * @param {String} grouping The grouping definition. + * @param {String} thousandsSep The thousands separator. + * + * @returns {String} The formatted integer part. + */ +jsworld._formatIntegerPart = function (intPart, grouping, thousandsSep) { + + // empty separator string? no grouping? + // -> return immediately with no formatting! + if (thousandsSep == "" || grouping == "-1") + return intPart; + + // turn the semicolon-separated string of integers into an array + var groupSizes = grouping.split(";"); + + // the formatted output string + var out = ""; + + // the intPart string position to process next, + // start at string end, e.g. "10000000 0) { + + // get next group size (if any, otherwise keep last) + if (groupSizes.length > 0) + size = parseInt(groupSizes.shift(), 10); + + // int parse error? + if (isNaN(size)) + throw "Error: Invalid grouping"; + + // size is -1? -> no more grouping, so just copy string remainder + if (size == -1) { + out = intPart.substring(0, pos) + out; + break; + } + + pos -= size; // move to next sep. char. position + + // position underrun? -> just copy string remainder + if (pos < 1) { + out = intPart.substring(0, pos + size) + out; + break; + } + + // extract group and apply sep. char. + out = thousandsSep + intPart.substring(pos, pos + size) + out; + } + + return out; +}; + + +/** + * @private + * + * @description Formats the fractional part to the specified decimal + * precision. + * + * @param {String} fracPart The fractional part of the amount + * @param {integer Number} precision The desired decimal precision + * + * @returns {String} The formatted fractional part. + */ +jsworld._formatFractionPart = function (fracPart, precision) { + + // append zeroes up to precision if necessary + for (var i=0; fracPart.length < precision; i++) + fracPart = fracPart + "0"; + + return fracPart; +}; + + +/** + * @private + * + * @desription Converts a number to string and pad it with leading zeroes if the + * string is shorter than length. + * + * @param {integer Number} number The number value subjected to selective padding. + * @param {integer Number} length If the number has fewer digits than this length + * apply padding. + * + * @returns {String} The formatted string. + */ +jsworld._zeroPad = function(number, length) { + + // ensure string + var s = number + ""; + + while (s.length < length) + s = "0" + s; + + return s; +}; + + +/** + * @private + * @description Converts a number to string and pads it with leading spaces if + * the string is shorter than length. + * + * @param {integer Number} number The number value subjected to selective padding. + * @param {integer Number} length If the number has fewer digits than this length + * apply padding. + * + * @returns {String} The formatted string. + */ +jsworld._spacePad = function(number, length) { + + // ensure string + var s = number + ""; + + while (s.length < length) + s = " " + s; + + return s; +}; + + + +/** + * @class + * Represents a POSIX-style locale with its numeric, monetary and date/time + * properties. Also provides a set of locale helper methods. + * + *

The locale properties follow the POSIX standards: + * + *

+ * + * @public + * @constructor + * @description Creates a new locale object (POSIX-style) with the specified + * properties. + * + * @param {object} properties An object containing the raw locale properties: + * + * @param {String} properties.decimal_point + * + * A string containing the symbol that shall be used as the decimal + * delimiter (radix character) in numeric, non-monetary formatted + * quantities. This property cannot be omitted and cannot be set to the + * empty string. + * + * + * @param {String} properties.thousands_sep + * + * A string containing the symbol that shall be used as a separator for + * groups of digits to the left of the decimal delimiter in numeric, + * non-monetary formatted monetary quantities. + * + * + * @param {String} properties.grouping + * + * Defines the size of each group of digits in formatted non-monetary + * quantities. The operand is a sequence of integers separated by + * semicolons. Each integer specifies the number of digits in each group, + * with the initial integer defining the size of the group immediately + * preceding the decimal delimiter, and the following integers defining + * the preceding groups. If the last integer is not -1, then the size of + * the previous group (if any) shall be repeatedly used for the + * remainder of the digits. If the last integer is -1, then no further + * grouping shall be performed. + * + * + * @param {String} properties.int_curr_symbol + * + * The first three letters signify the ISO-4217 currency code, + * the fourth letter is the international symbol separation character + * (normally a space). + * + * + * @param {String} properties.currency_symbol + * + * The local shorthand currency symbol, e.g. "$" for the en_US locale + * + * + * @param {String} properties.mon_decimal_point + * + * The symbol to be used as the decimal delimiter (radix character) + * + * + * @param {String} properties.mon_thousands_sep + * + * The symbol to be used as a separator for groups of digits to the + * left of the decimal delimiter. + * + * + * @param {String} properties.mon_grouping + * + * A string that defines the size of each group of digits. The + * operand is a sequence of integers separated by semicolons (";"). + * Each integer specifies the number of digits in each group, with the + * initial integer defining the size of the group preceding the + * decimal delimiter, and the following integers defining the + * preceding groups. If the last integer is not -1, then the size of + * the previous group (if any) must be repeatedly used for the + * remainder of the digits. If the last integer is -1, then no + * further grouping is to be performed. + * + * + * @param {String} properties.positive_sign + * + * The string to indicate a non-negative monetary amount. + * + * + * @param {String} properties.negative_sign + * + * The string to indicate a negative monetary amount. + * + * + * @param {integer Number} properties.frac_digits + * + * An integer representing the number of fractional digits (those to + * the right of the decimal delimiter) to be written in a formatted + * monetary quantity using currency_symbol. + * + * + * @param {integer Number} properties.int_frac_digits + * + * An integer representing the number of fractional digits (those to + * the right of the decimal delimiter) to be written in a formatted + * monetary quantity using int_curr_symbol. + * + * + * @param {integer Number} properties.p_cs_precedes + * + * An integer set to 1 if the currency_symbol precedes the value for a + * monetary quantity with a non-negative value, and set to 0 if the + * symbol succeeds the value. + * + * + * @param {integer Number} properties.n_cs_precedes + * + * An integer set to 1 if the currency_symbol precedes the value for a + * monetary quantity with a negative value, and set to 0 if the symbol + * succeeds the value. + * + * + * @param {integer Number} properties.p_sep_by_space + * + * Set to a value indicating the separation of the currency_symbol, + * the sign string, and the value for a non-negative formatted monetary + * quantity: + * + *

0 No space separates the currency symbol and value.

+ * + *

1 If the currency symbol and sign string are adjacent, a space + * separates them from the value; otherwise, a space separates + * the currency symbol from the value.

+ * + *

2 If the currency symbol and sign string are adjacent, a space + * separates them; otherwise, a space separates the sign string + * from the value.

+ * + * + * @param {integer Number} properties.n_sep_by_space + * + * Set to a value indicating the separation of the currency_symbol, + * the sign string, and the value for a negative formatted monetary + * quantity. Rules same as for p_sep_by_space. + * + * + * @param {integer Number} properties.p_sign_posn + * + * An integer set to a value indicating the positioning of the + * positive_sign for a monetary quantity with a non-negative value: + * + *

0 Parentheses enclose the quantity and the currency_symbol.

+ * + *

1 The sign string precedes the quantity and the currency_symbol.

+ * + *

2 The sign string succeeds the quantity and the currency_symbol.

+ * + *

3 The sign string precedes the currency_symbol.

+ * + *

4 The sign string succeeds the currency_symbol.

+ * + * + * @param {integer Number} properties.n_sign_posn + * + * An integer set to a value indicating the positioning of the + * negative_sign for a negative formatted monetary quantity. Rules same + * as for p_sign_posn. + * + * + * @param {integer Number} properties.int_p_cs_precedes + * + * An integer set to 1 if the int_curr_symbol precedes the value for a + * monetary quantity with a non-negative value, and set to 0 if the + * symbol succeeds the value. + * + * + * @param {integer Number} properties.int_n_cs_precedes + * + * An integer set to 1 if the int_curr_symbol precedes the value for a + * monetary quantity with a negative value, and set to 0 if the symbol + * succeeds the value. + * + * + * @param {integer Number} properties.int_p_sep_by_space + * + * Set to a value indicating the separation of the int_curr_symbol, + * the sign string, and the value for a non-negative internationally + * formatted monetary quantity. Rules same as for p_sep_by_space. + * + * + * @param {integer Number} properties.int_n_sep_by_space + * + * Set to a value indicating the separation of the int_curr_symbol, + * the sign string, and the value for a negative internationally + * formatted monetary quantity. Rules same as for p_sep_by_space. + * + * + * @param {integer Number} properties.int_p_sign_posn + * + * An integer set to a value indicating the positioning of the + * positive_sign for a positive monetary quantity formatted with the + * international format. Rules same as for p_sign_posn. + * + * + * @param {integer Number} properties.int_n_sign_posn + * + * An integer set to a value indicating the positioning of the + * negative_sign for a negative monetary quantity formatted with the + * international format. Rules same as for p_sign_posn. + * + * + * @param {String[] | String} properties.abday + * + * The abbreviated weekday names, corresponding to the %a conversion + * specification. The property must be either an array of 7 strings or + * a string consisting of 7 semicolon-separated substrings, each + * surrounded by double-quotes. The first must be the abbreviated name + * of the day corresponding to Sunday, the second the abbreviated name + * of the day corresponding to Monday, and so on. + * + * + * @param {String[] | String} properties.day + * + * The full weekday names, corresponding to the %A conversion + * specification. The property must be either an array of 7 strings or + * a string consisting of 7 semicolon-separated substrings, each + * surrounded by double-quotes. The first must be the full name of the + * day corresponding to Sunday, the second the full name of the day + * corresponding to Monday, and so on. + * + * + * @param {String[] | String} properties.abmon + * + * The abbreviated month names, corresponding to the %b conversion + * specification. The property must be either an array of 12 strings or + * a string consisting of 12 semicolon-separated substrings, each + * surrounded by double-quotes. The first must be the abbreviated name + * of the first month of the year (January), the second the abbreviated + * name of the second month, and so on. + * + * + * @param {String[] | String} properties.mon + * + * The full month names, corresponding to the %B conversion + * specification. The property must be either an array of 12 strings or + * a string consisting of 12 semicolon-separated substrings, each + * surrounded by double-quotes. The first must be the full name of the + * first month of the year (January), the second the full name of the second + * month, and so on. + * + * + * @param {String} properties.d_fmt + * + * The appropriate date representation. The string may contain any + * combination of characters and conversion specifications (%). + * + * + * @param {String} properties.t_fmt + * + * The appropriate time representation. The string may contain any + * combination of characters and conversion specifications (%). + * + * + * @param {String} properties.d_t_fmt + * + * The appropriate date and time representation. The string may contain + * any combination of characters and conversion specifications (%). + * + * + * @param {String[] | String} properties.am_pm + * + * The appropriate representation of the ante-meridiem and post-meridiem + * strings, corresponding to the %p conversion specification. The property + * must be either an array of 2 strings or a string consisting of 2 + * semicolon-separated substrings, each surrounded by double-quotes. + * The first string must represent the ante-meridiem designation, the + * last string the post-meridiem designation. + * + * + * @throws @throws Error on a undefined or invalid locale property. + */ +jsworld.Locale = function(properties) { + + + /** + * @private + * + * @description Identifies the class for internal library purposes. + */ + this._className = "jsworld.Locale"; + + + /** + * @private + * + * @description Parses a day or month name definition list, which + * could be a ready JS array, e.g. ["Mon", "Tue", "Wed"...] or + * it could be a string formatted according to the classic POSIX + * definition e.g. "Mon";"Tue";"Wed";... + * + * @param {String[] | String} namesAn array or string defining + * the week/month names. + * @param {integer Number} expectedItems The number of expected list + * items, e.g. 7 for weekdays, 12 for months. + * + * @returns {String[]} The parsed (and checked) items. + * + * @throws Error on missing definition, unexpected item count or + * missing double-quotes. + */ + this._parseList = function(names, expectedItems) { + + var array = []; + + if (names == null) { + throw "Names not defined"; + } + else if (typeof names == "object") { + // we got a ready array + array = names; + } + else if (typeof names == "string") { + // we got the names in the classic POSIX form, do parse + array = names.split(";", expectedItems); + + for (var i = 0; i < array.length; i++) { + // check for and strip double quotes + if (array[i][0] == "\"" && array[i][array[i].length - 1] == "\"") + array[i] = array[i].slice(1, -1); + else + throw "Missing double quotes"; + } + } + else { + throw "Names must be an array or a string"; + } + + if (array.length != expectedItems) + throw "Expected " + expectedItems + " items, got " + array.length; + + return array; + }; + + + /** + * @private + * + * @description Validates a date/time format string, such as "H:%M:%S". + * Checks that the argument is of type "string" and is not empty. + * + * @param {String} formatString The format string. + * + * @returns {String} The validated string. + * + * @throws Error on null or empty string. + */ + this._validateFormatString = function(formatString) { + + if (typeof formatString == "string" && formatString.length > 0) + return formatString; + else + throw "Empty or no string"; + }; + + + // LC_NUMERIC + + if (properties == null || typeof properties != "object") + throw "Error: Invalid/missing locale properties"; + + + if (typeof properties.decimal_point != "string") + throw "Error: Invalid/missing decimal_point property"; + + this.decimal_point = properties.decimal_point; + + + if (typeof properties.thousands_sep != "string") + throw "Error: Invalid/missing thousands_sep property"; + + this.thousands_sep = properties.thousands_sep; + + + if (typeof properties.grouping != "string") + throw "Error: Invalid/missing grouping property"; + + this.grouping = properties.grouping; + + + // LC_MONETARY + + if (typeof properties.int_curr_symbol != "string") + throw "Error: Invalid/missing int_curr_symbol property"; + + if (! /[A-Za-z]{3}.?/.test(properties.int_curr_symbol)) + throw "Error: Invalid int_curr_symbol property"; + + this.int_curr_symbol = properties.int_curr_symbol; + + + if (typeof properties.currency_symbol != "string") + throw "Error: Invalid/missing currency_symbol property"; + + this.currency_symbol = properties.currency_symbol; + + + if (typeof properties.frac_digits != "number" && properties.frac_digits < 0) + throw "Error: Invalid/missing frac_digits property"; + + this.frac_digits = properties.frac_digits; + + + // may be empty string/null for currencies with no fractional part + if (properties.mon_decimal_point === null || properties.mon_decimal_point == "") { + + if (this.frac_digits > 0) + throw "Error: Undefined mon_decimal_point property"; + else + properties.mon_decimal_point = ""; + } + + if (typeof properties.mon_decimal_point != "string") + throw "Error: Invalid/missing mon_decimal_point property"; + + this.mon_decimal_point = properties.mon_decimal_point; + + + if (typeof properties.mon_thousands_sep != "string") + throw "Error: Invalid/missing mon_thousands_sep property"; + + this.mon_thousands_sep = properties.mon_thousands_sep; + + + if (typeof properties.mon_grouping != "string") + throw "Error: Invalid/missing mon_grouping property"; + + this.mon_grouping = properties.mon_grouping; + + + if (typeof properties.positive_sign != "string") + throw "Error: Invalid/missing positive_sign property"; + + this.positive_sign = properties.positive_sign; + + + if (typeof properties.negative_sign != "string") + throw "Error: Invalid/missing negative_sign property"; + + this.negative_sign = properties.negative_sign; + + + + if (properties.p_cs_precedes !== 0 && properties.p_cs_precedes !== 1) + throw "Error: Invalid/missing p_cs_precedes property, must be 0 or 1"; + + this.p_cs_precedes = properties.p_cs_precedes; + + + if (properties.n_cs_precedes !== 0 && properties.n_cs_precedes !== 1) + throw "Error: Invalid/missing n_cs_precedes, must be 0 or 1"; + + this.n_cs_precedes = properties.n_cs_precedes; + + + if (properties.p_sep_by_space !== 0 && + properties.p_sep_by_space !== 1 && + properties.p_sep_by_space !== 2) + throw "Error: Invalid/missing p_sep_by_space property, must be 0, 1 or 2"; + + this.p_sep_by_space = properties.p_sep_by_space; + + + if (properties.n_sep_by_space !== 0 && + properties.n_sep_by_space !== 1 && + properties.n_sep_by_space !== 2) + throw "Error: Invalid/missing n_sep_by_space property, must be 0, 1, or 2"; + + this.n_sep_by_space = properties.n_sep_by_space; + + + if (properties.p_sign_posn !== 0 && + properties.p_sign_posn !== 1 && + properties.p_sign_posn !== 2 && + properties.p_sign_posn !== 3 && + properties.p_sign_posn !== 4) + throw "Error: Invalid/missing p_sign_posn property, must be 0, 1, 2, 3 or 4"; + + this.p_sign_posn = properties.p_sign_posn; + + + if (properties.n_sign_posn !== 0 && + properties.n_sign_posn !== 1 && + properties.n_sign_posn !== 2 && + properties.n_sign_posn !== 3 && + properties.n_sign_posn !== 4) + throw "Error: Invalid/missing n_sign_posn property, must be 0, 1, 2, 3 or 4"; + + this.n_sign_posn = properties.n_sign_posn; + + + if (typeof properties.int_frac_digits != "number" && properties.int_frac_digits < 0) + throw "Error: Invalid/missing int_frac_digits property"; + + this.int_frac_digits = properties.int_frac_digits; + + + if (properties.int_p_cs_precedes !== 0 && properties.int_p_cs_precedes !== 1) + throw "Error: Invalid/missing int_p_cs_precedes property, must be 0 or 1"; + + this.int_p_cs_precedes = properties.int_p_cs_precedes; + + + if (properties.int_n_cs_precedes !== 0 && properties.int_n_cs_precedes !== 1) + throw "Error: Invalid/missing int_n_cs_precedes property, must be 0 or 1"; + + this.int_n_cs_precedes = properties.int_n_cs_precedes; + + + if (properties.int_p_sep_by_space !== 0 && + properties.int_p_sep_by_space !== 1 && + properties.int_p_sep_by_space !== 2) + throw "Error: Invalid/missing int_p_sep_by_spacev, must be 0, 1 or 2"; + + this.int_p_sep_by_space = properties.int_p_sep_by_space; + + + if (properties.int_n_sep_by_space !== 0 && + properties.int_n_sep_by_space !== 1 && + properties.int_n_sep_by_space !== 2) + throw "Error: Invalid/missing int_n_sep_by_space property, must be 0, 1, or 2"; + + this.int_n_sep_by_space = properties.int_n_sep_by_space; + + + if (properties.int_p_sign_posn !== 0 && + properties.int_p_sign_posn !== 1 && + properties.int_p_sign_posn !== 2 && + properties.int_p_sign_posn !== 3 && + properties.int_p_sign_posn !== 4) + throw "Error: Invalid/missing int_p_sign_posn property, must be 0, 1, 2, 3 or 4"; + + this.int_p_sign_posn = properties.int_p_sign_posn; + + + if (properties.int_n_sign_posn !== 0 && + properties.int_n_sign_posn !== 1 && + properties.int_n_sign_posn !== 2 && + properties.int_n_sign_posn !== 3 && + properties.int_n_sign_posn !== 4) + throw "Error: Invalid/missing int_n_sign_posn property, must be 0, 1, 2, 3 or 4"; + + this.int_n_sign_posn = properties.int_n_sign_posn; + + + // LC_TIME + + if (properties == null || typeof properties != "object") + throw "Error: Invalid/missing time locale properties"; + + + // parse the supported POSIX LC_TIME properties + + // abday + try { + this.abday = this._parseList(properties.abday, 7); + } + catch (error) { + throw "Error: Invalid abday property: " + error; + } + + // day + try { + this.day = this._parseList(properties.day, 7); + } + catch (error) { + throw "Error: Invalid day property: " + error; + } + + // abmon + try { + this.abmon = this._parseList(properties.abmon, 12); + } catch (error) { + throw "Error: Invalid abmon property: " + error; + } + + // mon + try { + this.mon = this._parseList(properties.mon, 12); + } catch (error) { + throw "Error: Invalid mon property: " + error; + } + + // d_fmt + try { + this.d_fmt = this._validateFormatString(properties.d_fmt); + } catch (error) { + throw "Error: Invalid d_fmt property: " + error; + } + + // t_fmt + try { + this.t_fmt = this._validateFormatString(properties.t_fmt); + } catch (error) { + throw "Error: Invalid t_fmt property: " + error; + } + + // d_t_fmt + try { + this.d_t_fmt = this._validateFormatString(properties.d_t_fmt); + } catch (error) { + throw "Error: Invalid d_t_fmt property: " + error; + } + + // am_pm + try { + var am_pm_strings = this._parseList(properties.am_pm, 2); + this.am = am_pm_strings[0]; + this.pm = am_pm_strings[1]; + } catch (error) { + // ignore empty/null string errors + this.am = ""; + this.pm = ""; + } + + + /** + * @public + * + * @description Returns the abbreviated name of the specified weekday. + * + * @param {integer Number} [weekdayNum] An integer between 0 and 6. Zero + * corresponds to Sunday, one to Monday, etc. If omitted the + * method will return an array of all abbreviated weekday + * names. + * + * @returns {String | String[]} The abbreviated name of the specified weekday + * or an array of all abbreviated weekday names. + * + * @throws Error on invalid argument. + */ + this.getAbbreviatedWeekdayName = function(weekdayNum) { + + if (typeof weekdayNum == "undefined" || weekdayNum === null) + return this.abday; + + if (! jsworld._isInteger(weekdayNum) || weekdayNum < 0 || weekdayNum > 6) + throw "Error: Invalid weekday argument, must be an integer [0..6]"; + + return this.abday[weekdayNum]; + }; + + + /** + * @public + * + * @description Returns the name of the specified weekday. + * + * @param {integer Number} [weekdayNum] An integer between 0 and 6. Zero + * corresponds to Sunday, one to Monday, etc. If omitted the + * method will return an array of all weekday names. + * + * @returns {String | String[]} The name of the specified weekday or an + * array of all weekday names. + * + * @throws Error on invalid argument. + */ + this.getWeekdayName = function(weekdayNum) { + + if (typeof weekdayNum == "undefined" || weekdayNum === null) + return this.day; + + if (! jsworld._isInteger(weekdayNum) || weekdayNum < 0 || weekdayNum > 6) + throw "Error: Invalid weekday argument, must be an integer [0..6]"; + + return this.day[weekdayNum]; + }; + + + /** + * @public + * + * @description Returns the abbreviated name of the specified month. + * + * @param {integer Number} [monthNum] An integer between 0 and 11. Zero + * corresponds to January, one to February, etc. If omitted the + * method will return an array of all abbreviated month names. + * + * @returns {String | String[]} The abbreviated name of the specified month + * or an array of all abbreviated month names. + * + * @throws Error on invalid argument. + */ + this.getAbbreviatedMonthName = function(monthNum) { + + if (typeof monthNum == "undefined" || monthNum === null) + return this.abmon; + + if (! jsworld._isInteger(monthNum) || monthNum < 0 || monthNum > 11) + throw "Error: Invalid month argument, must be an integer [0..11]"; + + return this.abmon[monthNum]; + }; + + + /** + * @public + * + * @description Returns the name of the specified month. + * + * @param {integer Number} [monthNum] An integer between 0 and 11. Zero + * corresponds to January, one to February, etc. If omitted the + * method will return an array of all month names. + * + * @returns {String | String[]} The name of the specified month or an array + * of all month names. + * + * @throws Error on invalid argument. + */ + this.getMonthName = function(monthNum) { + + if (typeof monthNum == "undefined" || monthNum === null) + return this.mon; + + if (! jsworld._isInteger(monthNum) || monthNum < 0 || monthNum > 11) + throw "Error: Invalid month argument, must be an integer [0..11]"; + + return this.mon[monthNum]; + }; + + + + /** + * @public + * + * @description Gets the decimal delimiter (radix) character for + * numeric quantities. + * + * @returns {String} The radix character. + */ + this.getDecimalPoint = function() { + + return this.decimal_point; + }; + + + /** + * @public + * + * @description Gets the local shorthand currency symbol. + * + * @returns {String} The currency symbol. + */ + this.getCurrencySymbol = function() { + + return this.currency_symbol; + }; + + + /** + * @public + * + * @description Gets the internaltion currency symbol (ISO-4217 code). + * + * @returns {String} The international currency symbol. + */ + this.getIntCurrencySymbol = function() { + + return this.int_curr_symbol.substring(0,3); + }; + + + /** + * @public + * + * @description Gets the position of the local (shorthand) currency + * symbol relative to the amount. Assumes a non-negative amount. + * + * @returns {Boolean} True if the symbol precedes the amount, false if + * the symbol succeeds the amount. + */ + this.currencySymbolPrecedes = function() { + + if (this.p_cs_precedes == 1) + return true; + else + return false; + }; + + + /** + * @public + * + * @description Gets the position of the international (ISO-4217 code) + * currency symbol relative to the amount. Assumes a non-negative + * amount. + * + * @returns {Boolean} True if the symbol precedes the amount, false if + * the symbol succeeds the amount. + */ + this.intCurrencySymbolPrecedes = function() { + + if (this.int_p_cs_precedes == 1) + return true; + else + return false; + + }; + + + /** + * @public + * + * @description Gets the decimal delimiter (radix) for monetary + * quantities. + * + * @returns {String} The radix character. + */ + this.getMonetaryDecimalPoint = function() { + + return this.mon_decimal_point; + }; + + + /** + * @public + * + * @description Gets the number of fractional digits for local + * (shorthand) symbol formatting. + * + * @returns {integer Number} The number of fractional digits. + */ + this.getFractionalDigits = function() { + + return this.frac_digits; + }; + + + /** + * @public + * + * @description Gets the number of fractional digits for + * international (ISO-4217 code) formatting. + * + * @returns {integer Number} The number of fractional digits. + */ + this.getIntFractionalDigits = function() { + + return this.int_frac_digits; + }; +}; + + + +/** + * @class + * Class for localised formatting of numbers. + * + *

See: + * POSIX LC_NUMERIC. + * + * + * @public + * @constructor + * @description Creates a new numeric formatter for the specified locale. + * + * @param {jsworld.Locale} locale A locale object specifying the required + * POSIX LC_NUMERIC formatting properties. + * + * @throws Error on constructor failure. + */ +jsworld.NumericFormatter = function(locale) { + + if (typeof locale != "object" || locale._className != "jsworld.Locale") + throw "Constructor error: You must provide a valid jsworld.Locale instance"; + + this.lc = locale; + + + /** + * @public + * + * @description Formats a decimal numeric value according to the preset + * locale. + * + * @param {Number|String} number The number to format. + * @param {String} [options] Options to modify the formatted output: + *

    + *
  • "^" suppress grouping + *
  • "+" force positive sign for positive amounts + *
  • "~" suppress positive/negative sign + *
  • ".n" specify decimal precision 'n' + *
+ * + * @returns {String} The formatted number. + * + * @throws "Error: Invalid input" on bad input. + */ + this.format = function(number, options) { + + if (typeof number == "string") + number = jsworld._trim(number); + + if (! jsworld._isNumber(number)) + throw "Error: The input is not a number"; + + var floatAmount = parseFloat(number, 10); + + // get the required precision + var reqPrecision = jsworld._getPrecision(options); + + // round to required precision + if (reqPrecision != -1) + floatAmount = Math.round(floatAmount * Math.pow(10, reqPrecision)) / Math.pow(10, reqPrecision); + + + // convert the float number to string and parse into + // object with properties integer and fraction + var parsedAmount = jsworld._splitNumber(String(floatAmount)); + + // format integer part with grouping chars + var formattedIntegerPart; + + if (floatAmount === 0) + formattedIntegerPart = "0"; + else + formattedIntegerPart = jsworld._hasOption("^", options) ? + parsedAmount.integer : + jsworld._formatIntegerPart(parsedAmount.integer, + this.lc.grouping, + this.lc.thousands_sep); + + // format the fractional part + var formattedFractionPart = + reqPrecision != -1 ? + jsworld._formatFractionPart(parsedAmount.fraction, reqPrecision) : + parsedAmount.fraction; + + + // join the integer and fraction parts using the decimal_point property + var formattedAmount = + formattedFractionPart.length ? + formattedIntegerPart + this.lc.decimal_point + formattedFractionPart : + formattedIntegerPart; + + // prepend sign? + if (jsworld._hasOption("~", options) || floatAmount === 0) { + // suppress both '+' and '-' signs, i.e. return abs value + return formattedAmount; + } + else { + if (jsworld._hasOption("+", options) || floatAmount < 0) { + if (floatAmount > 0) + // force '+' sign for positive amounts + return "+" + formattedAmount; + else if (floatAmount < 0) + // prepend '-' sign + return "-" + formattedAmount; + else + // zero case + return formattedAmount; + } + else { + // positive amount with no '+' sign + return formattedAmount; + } + } + }; +}; + + +/** + * @class + * Class for localised formatting of dates and times. + * + *

See: + * POSIX LC_TIME. + * + * @public + * @constructor + * @description Creates a new date/time formatter for the specified locale. + * + * @param {jsworld.Locale} locale A locale object specifying the required + * POSIX LC_TIME formatting properties. + * + * @throws Error on constructor failure. + */ +jsworld.DateTimeFormatter = function(locale) { + + + if (typeof locale != "object" || locale._className != "jsworld.Locale") + throw "Constructor error: You must provide a valid jsworld.Locale instance."; + + this.lc = locale; + + + /** + * @public + * + * @description Formats a date according to the preset locale. + * + * @param {Date|String} date A valid Date object instance or a string + * containing a valid ISO-8601 formatted date, e.g. "2010-31-03" + * or "2010-03-31 23:59:59". + * + * @returns {String} The formatted date + * + * @throws Error on invalid date argument + */ + this.formatDate = function(date) { + + var d = null; + + if (typeof date == "string") { + // assume ISO-8601 date string + try { + d = jsworld.parseIsoDate(date); + } catch (error) { + // try full ISO-8601 date/time string + d = jsworld.parseIsoDateTime(date); + } + } + else if (date !== null && typeof date == "object") { + // assume ready Date object + d = date; + } + else { + throw "Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"; + } + + return this._applyFormatting(d, this.lc.d_fmt); + }; + + + /** + * @public + * + * @description Formats a time according to the preset locale. + * + * @param {Date|String} date A valid Date object instance or a string + * containing a valid ISO-8601 formatted time, e.g. "23:59:59" + * or "2010-03-31 23:59:59". + * + * @returns {String} The formatted time. + * + * @throws Error on invalid date argument. + */ + this.formatTime = function(date) { + + var d = null; + + if (typeof date == "string") { + // assume ISO-8601 time string + try { + d = jsworld.parseIsoTime(date); + } catch (error) { + // try full ISO-8601 date/time string + d = jsworld.parseIsoDateTime(date); + } + } + else if (date !== null && typeof date == "object") { + // assume ready Date object + d = date; + } + else { + throw "Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"; + } + + return this._applyFormatting(d, this.lc.t_fmt); + }; + + + /** + * @public + * + * @description Formats a date/time value according to the preset + * locale. + * + * @param {Date|String} date A valid Date object instance or a string + * containing a valid ISO-8601 formatted date/time, e.g. + * "2010-03-31 23:59:59". + * + * @returns {String} The formatted time. + * + * @throws Error on invalid argument. + */ + this.formatDateTime = function(date) { + + var d = null; + + if (typeof date == "string") { + // assume ISO-8601 format + d = jsworld.parseIsoDateTime(date); + } + else if (date !== null && typeof date == "object") { + // assume ready Date object + d = date; + } + else { + throw "Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"; + } + + return this._applyFormatting(d, this.lc.d_t_fmt); + }; + + + /** + * @private + * + * @description Apples formatting to the Date object according to the + * format string. + * + * @param {Date} d A valid Date instance. + * @param {String} s The formatting string with '%' placeholders. + * + * @returns {String} The formatted string. + */ + this._applyFormatting = function(d, s) { + + s = s.replace(/%%/g, '%'); + s = s.replace(/%a/g, this.lc.abday[d.getDay()]); + s = s.replace(/%A/g, this.lc.day[d.getDay()]); + s = s.replace(/%b/g, this.lc.abmon[d.getMonth()]); + s = s.replace(/%B/g, this.lc.mon[d.getMonth()]); + s = s.replace(/%d/g, jsworld._zeroPad(d.getDate(), 2)); + s = s.replace(/%e/g, jsworld._spacePad(d.getDate(), 2)); + s = s.replace(/%F/g, d.getFullYear() + + "-" + + jsworld._zeroPad(d.getMonth()+1, 2) + + "-" + + jsworld._zeroPad(d.getDate(), 2)); + s = s.replace(/%h/g, this.lc.abmon[d.getMonth()]); // same as %b + s = s.replace(/%H/g, jsworld._zeroPad(d.getHours(), 2)); + s = s.replace(/%I/g, jsworld._zeroPad(this._hours12(d.getHours()), 2)); + s = s.replace(/%k/g, d.getHours()); + s = s.replace(/%l/g, this._hours12(d.getHours())); + s = s.replace(/%m/g, jsworld._zeroPad(d.getMonth()+1, 2)); + s = s.replace(/%n/g, "\n"); + s = s.replace(/%M/g, jsworld._zeroPad(d.getMinutes(), 2)); + s = s.replace(/%p/g, this._getAmPm(d.getHours())); + s = s.replace(/%P/g, this._getAmPm(d.getHours()).toLocaleLowerCase()); // safe? + s = s.replace(/%R/g, jsworld._zeroPad(d.getHours(), 2) + + ":" + + jsworld._zeroPad(d.getMinutes(), 2)); + s = s.replace(/%S/g, jsworld._zeroPad(d.getSeconds(), 2)); + s = s.replace(/%T/g, jsworld._zeroPad(d.getHours(), 2) + + ":" + + jsworld._zeroPad(d.getMinutes(), 2) + + ":" + + jsworld._zeroPad(d.getSeconds(), 2)); + s = s.replace(/%w/g, this.lc.day[d.getDay()]); + s = s.replace(/%y/g, new String(d.getFullYear()).substring(2)); + s = s.replace(/%Y/g, d.getFullYear()); + + s = s.replace(/%Z/g, ""); // to do: ignored until a reliable TMZ method found + + s = s.replace(/%[a-zA-Z]/g, ""); // ignore all other % sequences + + return s; + }; + + + /** + * @private + * + * @description Does 24 to 12 hour conversion. + * + * @param {integer Number} hour24 Hour [0..23]. + * + * @returns {integer Number} Corresponding hour [1..12]. + */ + this._hours12 = function(hour24) { + + if (hour24 === 0) + return 12; // 00h is 12AM + + else if (hour24 > 12) + return hour24 - 12; // 1PM to 11PM + + else + return hour24; // 1AM to 12PM + }; + + + /** + * @private + * + * @description Gets the appropriate localised AM or PM string depending + * on the day hour. Special cases: midnight is 12AM, noon is 12PM. + * + * @param {integer Number} hour24 Hour [0..23]. + * + * @returns {String} The corresponding localised AM or PM string. + */ + this._getAmPm = function(hour24) { + + if (hour24 < 12) + return this.lc.am; + else + return this.lc.pm; + }; +}; + + + +/** + * @class Class for localised formatting of currency amounts. + * + *

See: + * POSIX LC_MONETARY. + * + * @public + * @constructor + * @description Creates a new monetary formatter for the specified locale. + * + * @param {jsworld.Locale} locale A locale object specifying the required + * POSIX LC_MONETARY formatting properties. + * @param {String} [currencyCode] Set the currency explicitly by + * passing its international ISO-4217 code, e.g. "USD", "EUR", "GBP". + * Use this optional parameter to override the default local currency + * @param {String} [altIntSymbol] Non-local currencies are formatted + * with their international ISO-4217 code to prevent ambiguity. + * Use this optional argument to force a different symbol, such as the + * currency's shorthand sign. This is mostly useful when the shorthand + * sign is both internationally recognised and identifies the currency + * uniquely (e.g. the Euro sign). + * + * @throws Error on constructor failure. + */ +jsworld.MonetaryFormatter = function(locale, currencyCode, altIntSymbol) { + + if (typeof locale != "object" || locale._className != "jsworld.Locale") + throw "Constructor error: You must provide a valid jsworld.Locale instance"; + + this.lc = locale; + + /** + * @private + * @description Lookup table to determine the fraction digits for a + * specific currency; most currencies subdivide at 1/100 (2 fractional + * digits), so we store only those that deviate from the default. + * + *

The data is from Unicode's CLDR version 1.7.0. The two currencies + * with non-decimal subunits (MGA and MRO) are marked as having no + * fractional digits as well as all currencies that have no subunits + * in circulation. + * + *

It is "hard-wired" for referential convenience and is only looked + * up when an overriding currencyCode parameter is supplied. + */ + this.currencyFractionDigits = { + "AFN" : 0, "ALL" : 0, "AMD" : 0, "BHD" : 3, "BIF" : 0, + "BYR" : 0, "CLF" : 0, "CLP" : 0, "COP" : 0, "CRC" : 0, + "DJF" : 0, "GNF" : 0, "GYD" : 0, "HUF" : 0, "IDR" : 0, + "IQD" : 0, "IRR" : 0, "ISK" : 0, "JOD" : 3, "JPY" : 0, + "KMF" : 0, "KRW" : 0, "KWD" : 3, "LAK" : 0, "LBP" : 0, + "LYD" : 3, "MGA" : 0, "MMK" : 0, "MNT" : 0, "MRO" : 0, + "MUR" : 0, "OMR" : 3, "PKR" : 0, "PYG" : 0, "RSD" : 0, + "RWF" : 0, "SLL" : 0, "SOS" : 0, "STD" : 0, "SYP" : 0, + "TND" : 3, "TWD" : 0, "TZS" : 0, "UGX" : 0, "UZS" : 0, + "VND" : 0, "VUV" : 0, "XAF" : 0, "XOF" : 0, "XPF" : 0, + "YER" : 0, "ZMK" : 0 + }; + + + // optional currencyCode argument? + if (typeof currencyCode == "string") { + // user wanted to override the local currency + this.currencyCode = currencyCode.toUpperCase(); + + // must override the frac digits too, for some + // currencies have 0, 2 or 3! + var numDigits = this.currencyFractionDigits[this.currencyCode]; + if (typeof numDigits != "number") + numDigits = 2; // default for most currencies + this.lc.frac_digits = numDigits; + this.lc.int_frac_digits = numDigits; + } + else { + // use local currency + this.currencyCode = this.lc.int_curr_symbol.substring(0,3).toUpperCase(); + } + + // extract intl. currency separator + this.intSep = this.lc.int_curr_symbol.charAt(3); + + // flag local or intl. sign formatting? + if (this.currencyCode == this.lc.int_curr_symbol.substring(0,3)) { + // currency matches the local one? -> + // formatting with local symbol and parameters + this.internationalFormatting = false; + this.curSym = this.lc.currency_symbol; + } + else { + // currency doesn't match the local -> + + // do we have an overriding currency symbol? + if (typeof altIntSymbol == "string") { + // -> force formatting with local parameters, using alt symbol + this.curSym = altIntSymbol; + this.internationalFormatting = false; + } + else { + // -> force formatting with intl. sign and parameters + this.internationalFormatting = true; + } + } + + + /** + * @public + * + * @description Gets the currency symbol used in formatting. + * + * @returns {String} The currency symbol. + */ + this.getCurrencySymbol = function() { + + return this.curSym; + }; + + + /** + * @public + * + * @description Gets the position of the currency symbol relative to + * the amount. Assumes a non-negative amount and local formatting. + * + * @param {String} intFlag Optional flag to force international + * formatting by passing the string "i". + * + * @returns {Boolean} True if the symbol precedes the amount, false if + * the symbol succeeds the amount. + */ + this.currencySymbolPrecedes = function(intFlag) { + + if (typeof intFlag == "string" && intFlag == "i") { + // international formatting was forced + if (this.lc.int_p_cs_precedes == 1) + return true; + else + return false; + + } + else { + // check whether local formatting is on or off + if (this.internationalFormatting) { + if (this.lc.int_p_cs_precedes == 1) + return true; + else + return false; + } + else { + if (this.lc.p_cs_precedes == 1) + return true; + else + return false; + } + } + }; + + + /** + * @public + * + * @description Gets the decimal delimiter (radix) used in formatting. + * + * @returns {String} The radix character. + */ + this.getDecimalPoint = function() { + + return this.lc.mon_decimal_point; + }; + + + /** + * @public + * + * @description Gets the number of fractional digits. Assumes local + * formatting. + * + * @param {String} intFlag Optional flag to force international + * formatting by passing the string "i". + * + * @returns {integer Number} The number of fractional digits. + */ + this.getFractionalDigits = function(intFlag) { + + if (typeof intFlag == "string" && intFlag == "i") { + // international formatting was forced + return this.lc.int_frac_digits; + } + else { + // check whether local formatting is on or off + if (this.internationalFormatting) + return this.lc.int_frac_digits; + else + return this.lc.frac_digits; + } + }; + + + /** + * @public + * + * @description Formats a monetary amount according to the preset + * locale. + * + *

+	 * For local currencies the native shorthand symbol will be used for
+	 * formatting.
+	 * Example:
+	 *        locale is en_US
+	 *        currency is USD
+	 *        -> the "$" symbol will be used, e.g. $123.45
+	 *        
+	 * For non-local currencies the international ISO-4217 code will be
+	 * used for formatting.
+	 * Example:
+	 *       locale is en_US (which has USD as currency)
+	 *       currency is EUR
+	 *       -> the ISO three-letter code will be used, e.g. EUR 123.45
+	 *
+	 * If the currency is non-local, but an alternative currency symbol was
+	 * provided, this will be used instead.
+	 * Example
+	 *       locale is en_US (which has USD as currency)
+	 *       currency is EUR
+	 *       an alternative symbol is provided - "€"
+	 *       -> the alternative symbol will be used, e.g. €123.45
+	 * 
+ * + * @param {Number|String} amount The amount to format as currency. + * @param {String} [options] Options to modify the formatted output: + *
    + *
  • "^" suppress grouping + *
  • "!" suppress the currency symbol + *
  • "~" suppress the currency symbol and the sign (positive or negative) + *
  • "i" force international sign (ISO-4217 code) formatting + *
  • ".n" specify decimal precision + * + * @returns The formatted currency amount as string. + * + * @throws "Error: Invalid amount" on bad amount. + */ + this.format = function(amount, options) { + + // if the amount is passed as string, check that it parses to a float + var floatAmount; + + if (typeof amount == "string") { + amount = jsworld._trim(amount); + floatAmount = parseFloat(amount); + + if (typeof floatAmount != "number" || isNaN(floatAmount)) + throw "Error: Amount string not a number"; + } + else if (typeof amount == "number") { + floatAmount = amount; + } + else { + throw "Error: Amount not a number"; + } + + // get the required precision, ".n" option arg overrides default locale config + var reqPrecision = jsworld._getPrecision(options); + + if (reqPrecision == -1) { + if (this.internationalFormatting || jsworld._hasOption("i", options)) + reqPrecision = this.lc.int_frac_digits; + else + reqPrecision = this.lc.frac_digits; + } + + // round + floatAmount = Math.round(floatAmount * Math.pow(10, reqPrecision)) / Math.pow(10, reqPrecision); + + + // convert the float amount to string and parse into + // object with properties integer and fraction + var parsedAmount = jsworld._splitNumber(String(floatAmount)); + + // format integer part with grouping chars + var formattedIntegerPart; + + if (floatAmount === 0) + formattedIntegerPart = "0"; + else + formattedIntegerPart = jsworld._hasOption("^", options) ? + parsedAmount.integer : + jsworld._formatIntegerPart(parsedAmount.integer, + this.lc.mon_grouping, + this.lc.mon_thousands_sep); + + + // format the fractional part + var formattedFractionPart; + + if (reqPrecision == -1) { + // pad fraction with trailing zeros accoring to default locale [int_]frac_digits + if (this.internationalFormatting || jsworld._hasOption("i", options)) + formattedFractionPart = + jsworld._formatFractionPart(parsedAmount.fraction, this.lc.int_frac_digits); + else + formattedFractionPart = + jsworld._formatFractionPart(parsedAmount.fraction, this.lc.frac_digits); + } + else { + // pad fraction with trailing zeros according to optional format parameter + formattedFractionPart = + jsworld._formatFractionPart(parsedAmount.fraction, reqPrecision); + } + + + // join integer and decimal parts using the mon_decimal_point property + var quantity; + + if (this.lc.frac_digits > 0 || formattedFractionPart.length) + quantity = formattedIntegerPart + this.lc.mon_decimal_point + formattedFractionPart; + else + quantity = formattedIntegerPart; + + + // do final formatting with sign and symbol + if (jsworld._hasOption("~", options)) { + return quantity; + } + else { + var suppressSymbol = jsworld._hasOption("!", options) ? true : false; + + var sign = floatAmount < 0 ? "-" : "+"; + + if (this.internationalFormatting || jsworld._hasOption("i", options)) { + + // format with ISO-4217 code (suppressed or not) + if (suppressSymbol) + return this._formatAsInternationalCurrencyWithNoSym(sign, quantity); + else + return this._formatAsInternationalCurrency(sign, quantity); + } + else { + // format with local currency code (suppressed or not) + if (suppressSymbol) + return this._formatAsLocalCurrencyWithNoSym(sign, quantity); + else + return this._formatAsLocalCurrency(sign, quantity); + } + } + }; + + + /** + * @private + * + * @description Assembles the final string with sign, separator and symbol as local + * currency. + * + * @param {String} sign The amount sign: "+" or "-". + * @param {String} q The formatted quantity (unsigned). + * + * @returns {String} The final formatted string. + */ + this._formatAsLocalCurrency = function (sign, q) { + + // assemble final formatted amount by going over all possible value combinations of: + // sign {+,-} , sign position {0,1,2,3,4} , separator {0,1,2} , symbol position {0,1} + if (sign == "+") { + + // parentheses + if (this.lc.p_sign_posn === 0 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { + return "(" + q + this.curSym + ")"; + } + else if (this.lc.p_sign_posn === 0 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { + return "(" + this.curSym + q + ")"; + } + else if (this.lc.p_sign_posn === 0 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { + return "(" + q + " " + this.curSym + ")"; + } + else if (this.lc.p_sign_posn === 0 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { + return "(" + this.curSym + " " + q + ")"; + } + + // sign before q + sym + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { + return this.lc.positive_sign + q + this.curSym; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + this.curSym + q; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { + return this.lc.positive_sign + q + " " + this.curSym; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + this.curSym + " " + q; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { + return this.lc.positive_sign + " " + q + this.curSym; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + " " + this.curSym + q; + } + + // sign after q + sym + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { + return q + this.curSym + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { + return this.curSym + q + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { + return q + " " + this.curSym + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { + return this.curSym + " " + q + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { + return q + this.curSym + " " + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { + return this.curSym + q + " " + this.lc.positive_sign; + } + + // sign before sym + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { + return q + this.lc.positive_sign + this.curSym; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + this.curSym + q; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { + return q + " " + this.lc.positive_sign + this.curSym; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + this.curSym + " " + q; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { + return q + this.lc.positive_sign + " " + this.curSym; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + " " + this.curSym + q; + } + + // sign after symbol + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { + return q + this.curSym + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { + return this.curSym + this.lc.positive_sign + q; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { + return q + " " + this.curSym + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { + return this.curSym + this.lc.positive_sign + " " + q; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { + return q + this.curSym + " " + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { + return this.curSym + " " + this.lc.positive_sign + q; + } + + } + else if (sign == "-") { + + // parentheses enclose q + sym + if (this.lc.n_sign_posn === 0 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { + return "(" + q + this.curSym + ")"; + } + else if (this.lc.n_sign_posn === 0 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { + return "(" + this.curSym + q + ")"; + } + else if (this.lc.n_sign_posn === 0 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { + return "(" + q + " " + this.curSym + ")"; + } + else if (this.lc.n_sign_posn === 0 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { + return "(" + this.curSym + " " + q + ")"; + } + + // sign before q + sym + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { + return this.lc.negative_sign + q + this.curSym; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + this.curSym + q; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { + return this.lc.negative_sign + q + " " + this.curSym; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + this.curSym + " " + q; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { + return this.lc.negative_sign + " " + q + this.curSym; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + " " + this.curSym + q; + } + + // sign after q + sym + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { + return q + this.curSym + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { + return this.curSym + q + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { + return q + " " + this.curSym + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { + return this.curSym + " " + q + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { + return q + this.curSym + " " + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { + return this.curSym + q + " " + this.lc.negative_sign; + } + + // sign before sym + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { + return q + this.lc.negative_sign + this.curSym; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + this.curSym + q; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { + return q + " " + this.lc.negative_sign + this.curSym; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + this.curSym + " " + q; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { + return q + this.lc.negative_sign + " " + this.curSym; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + " " + this.curSym + q; + } + + // sign after symbol + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { + return q + this.curSym + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { + return this.curSym + this.lc.negative_sign + q; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { + return q + " " + this.curSym + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { + return this.curSym + this.lc.negative_sign + " " + q; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { + return q + this.curSym + " " + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { + return this.curSym + " " + this.lc.negative_sign + q; + } + } + + // throw error if we fall through + throw "Error: Invalid POSIX LC MONETARY definition"; + }; + + + /** + * @private + * + * @description Assembles the final string with sign, separator and ISO-4217 + * currency code. + * + * @param {String} sign The amount sign: "+" or "-". + * @param {String} q The formatted quantity (unsigned). + * + * @returns {String} The final formatted string. + */ + this._formatAsInternationalCurrency = function (sign, q) { + + // assemble the final formatted amount by going over all possible value combinations of: + // sign {+,-} , sign position {0,1,2,3,4} , separator {0,1,2} , symbol position {0,1} + + if (sign == "+") { + + // parentheses + if (this.lc.int_p_sign_posn === 0 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { + return "(" + q + this.currencyCode + ")"; + } + else if (this.lc.int_p_sign_posn === 0 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { + return "(" + this.currencyCode + q + ")"; + } + else if (this.lc.int_p_sign_posn === 0 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { + return "(" + q + this.intSep + this.currencyCode + ")"; + } + else if (this.lc.int_p_sign_posn === 0 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { + return "(" + this.currencyCode + this.intSep + q + ")"; + } + + // sign before q + sym + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { + return this.lc.positive_sign + q + this.currencyCode; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.currencyCode + q; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { + return this.lc.positive_sign + q + this.intSep + this.currencyCode; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.currencyCode + this.intSep + q; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { + return this.lc.positive_sign + this.intSep + q + this.currencyCode; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.intSep + this.currencyCode + q; + } + + // sign after q + sym + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { + return q + this.currencyCode + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { + return this.currencyCode + q + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { + return q + this.intSep + this.currencyCode + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { + return this.currencyCode + this.intSep + q + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { + return q + this.currencyCode + this.intSep + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { + return this.currencyCode + q + this.intSep + this.lc.positive_sign; + } + + // sign before sym + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { + return q + this.lc.positive_sign + this.currencyCode; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.currencyCode + q; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { + return q + this.intSep + this.lc.positive_sign + this.currencyCode; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.currencyCode + this.intSep + q; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { + return q + this.lc.positive_sign + this.intSep + this.currencyCode; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.intSep + this.currencyCode + q; + } + + // sign after symbol + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { + return q + this.currencyCode + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { + return this.currencyCode + this.lc.positive_sign + q; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { + return q + this.intSep + this.currencyCode + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { + return this.currencyCode + this.lc.positive_sign + this.intSep + q; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { + return q + this.currencyCode + this.intSep + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { + return this.currencyCode + this.intSep + this.lc.positive_sign + q; + } + + } + else if (sign == "-") { + + // parentheses enclose q + sym + if (this.lc.int_n_sign_posn === 0 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { + return "(" + q + this.currencyCode + ")"; + } + else if (this.lc.int_n_sign_posn === 0 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { + return "(" + this.currencyCode + q + ")"; + } + else if (this.lc.int_n_sign_posn === 0 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { + return "(" + q + this.intSep + this.currencyCode + ")"; + } + else if (this.lc.int_n_sign_posn === 0 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { + return "(" + this.currencyCode + this.intSep + q + ")"; + } + + // sign before q + sym + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { + return this.lc.negative_sign + q + this.currencyCode; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.currencyCode + q; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { + return this.lc.negative_sign + q + this.intSep + this.currencyCode; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.currencyCode + this.intSep + q; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { + return this.lc.negative_sign + this.intSep + q + this.currencyCode; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.intSep + this.currencyCode + q; + } + + // sign after q + sym + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { + return q + this.currencyCode + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { + return this.currencyCode + q + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { + return q + this.intSep + this.currencyCode + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { + return this.currencyCode + this.intSep + q + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { + return q + this.currencyCode + this.intSep + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { + return this.currencyCode + q + this.intSep + this.lc.negative_sign; + } + + // sign before sym + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { + return q + this.lc.negative_sign + this.currencyCode; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.currencyCode + q; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { + return q + this.intSep + this.lc.negative_sign + this.currencyCode; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.currencyCode + this.intSep + q; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { + return q + this.lc.negative_sign + this.intSep + this.currencyCode; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.intSep + this.currencyCode + q; + } + + // sign after symbol + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { + return q + this.currencyCode + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { + return this.currencyCode + this.lc.negative_sign + q; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { + return q + this.intSep + this.currencyCode + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { + return this.currencyCode + this.lc.negative_sign + this.intSep + q; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { + return q + this.currencyCode + this.intSep + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { + return this.currencyCode + this.intSep + this.lc.negative_sign + q; + } + } + + // throw error if we fall through + throw "Error: Invalid POSIX LC MONETARY definition"; + }; + + + /** + * @private + * + * @description Assembles the final string with sign and separator, but suppress the + * local currency symbol. + * + * @param {String} sign The amount sign: "+" or "-". + * @param {String} q The formatted quantity (unsigned). + * + * @returns {String} The final formatted string + */ + this._formatAsLocalCurrencyWithNoSym = function (sign, q) { + + // assemble the final formatted amount by going over all possible value combinations of: + // sign {+,-} , sign position {0,1,2,3,4} , separator {0,1,2} , symbol position {0,1} + + if (sign == "+") { + + // parentheses + if (this.lc.p_sign_posn === 0) { + return "(" + q + ")"; + } + + // sign before q + sym + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { + return this.lc.positive_sign + q; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + q; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { + return this.lc.positive_sign + q; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + q; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { + return this.lc.positive_sign + " " + q; + } + else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + " " + q; + } + + // sign after q + sym + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { + return q + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { + return q + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { + return q + " " + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { + return q + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { + return q + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { + return q + " " + this.lc.positive_sign; + } + + // sign before sym + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { + return q + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + q; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { + return q + " " + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + " " + q; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { + return q + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + " " + q; + } + + // sign after symbol + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { + return q + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + q; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { + return q + " " + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + " " + q; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { + return q + " " + this.lc.positive_sign; + } + else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { + return this.lc.positive_sign + q; + } + + } + else if (sign == "-") { + + // parentheses enclose q + sym + if (this.lc.n_sign_posn === 0) { + return "(" + q + ")"; + } + + // sign before q + sym + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { + return this.lc.negative_sign + q; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + q; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { + return this.lc.negative_sign + q; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + " " + q; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { + return this.lc.negative_sign + " " + q; + } + else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + " " + q; + } + + // sign after q + sym + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { + return q + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { + return q + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { + return q + " " + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { + return q + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { + return q + " " + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { + return q + " " + this.lc.negative_sign; + } + + // sign before sym + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { + return q + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + q; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { + return q + " " + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + " " + q; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { + return q + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + " " + q; + } + + // sign after symbol + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { + return q + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + q; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { + return q + " " + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + " " + q; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { + return q + " " + this.lc.negative_sign; + } + else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { + return this.lc.negative_sign + q; + } + } + + // throw error if we fall through + throw "Error: Invalid POSIX LC MONETARY definition"; + }; + + + /** + * @private + * + * @description Assembles the final string with sign and separator, but suppress + * the ISO-4217 currency code. + * + * @param {String} sign The amount sign: "+" or "-". + * @param {String} q The formatted quantity (unsigned). + * + * @returns {String} The final formatted string. + */ + this._formatAsInternationalCurrencyWithNoSym = function (sign, q) { + + // assemble the final formatted amount by going over all possible value combinations of: + // sign {+,-} , sign position {0,1,2,3,4} , separator {0,1,2} , symbol position {0,1} + + if (sign == "+") { + + // parentheses + if (this.lc.int_p_sign_posn === 0) { + return "(" + q + ")"; + } + + // sign before q + sym + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { + return this.lc.positive_sign + q; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + q; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { + return this.lc.positive_sign + q; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.intSep + q; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { + return this.lc.positive_sign + this.intSep + q; + } + else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.intSep + q; + } + + // sign after q + sym + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { + return q + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { + return q + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { + return q + this.intSep + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { + return q + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { + return q + this.intSep + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { + return q + this.intSep + this.lc.positive_sign; + } + + // sign before sym + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { + return q + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + q; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { + return q + this.intSep + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.intSep + q; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { + return q + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.intSep + q; + } + + // sign after symbol + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { + return q + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + q; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { + return q + this.intSep + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + this.intSep + q; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { + return q + this.intSep + this.lc.positive_sign; + } + else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { + return this.lc.positive_sign + q; + } + + } + else if (sign == "-") { + + // parentheses enclose q + sym + if (this.lc.int_n_sign_posn === 0) { + return "(" + q + ")"; + } + + // sign before q + sym + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { + return this.lc.negative_sign + q; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + q; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { + return this.lc.negative_sign + q; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.intSep + q; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { + return this.lc.negative_sign + this.intSep + q; + } + else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.intSep + q; + } + + // sign after q + sym + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { + return q + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { + return q + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { + return q + this.intSep + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { + return q + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { + return q + this.intSep + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { + return q + this.intSep + this.lc.negative_sign; + } + + // sign before sym + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { + return q + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + q; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { + return q + this.intSep + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.intSep + q; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { + return q + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.intSep + q; + } + + // sign after symbol + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { + return q + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + q; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { + return q + this.intSep + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + this.intSep + q; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { + return q + this.intSep + this.lc.negative_sign; + } + else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { + return this.lc.negative_sign + q; + } + } + + // throw error if we fall through + throw "Error: Invalid POSIX LC_MONETARY definition"; + }; +}; + + +/** + * @class + * Class for parsing localised number strings. + * + * @public + * @constructor + * @description Creates a new numeric parser for the specified locale. + * + * @param {jsworld.Locale} locale A locale object specifying the required + * POSIX LC_NUMERIC formatting properties. + * + * @throws Error on constructor failure. + */ +jsworld.NumericParser = function(locale) { + + if (typeof locale != "object" || locale._className != "jsworld.Locale") + throw "Constructor error: You must provide a valid jsworld.Locale instance"; + + this.lc = locale; + + + /** + * @public + * + * @description Parses a numeric string formatted according to the + * preset locale. Leading and trailing whitespace is ignored; the number + * may also be formatted without thousands separators. + * + * @param {String} formattedNumber The formatted number. + * + * @returns {Number} The parsed number. + * + * @throws Error on a parse exception. + */ + this.parse = function(formattedNumber) { + + if (typeof formattedNumber != "string") + throw "Parse error: Argument must be a string"; + + // trim whitespace + var s = jsworld._trim(formattedNumber); + + // remove any thousand separator symbols + s = jsworld._stringReplaceAll(formattedNumber, this.lc.thousands_sep, ""); + + // replace any local decimal point symbols with the symbol used + // in JavaScript "." + s = jsworld._stringReplaceAll(s, this.lc.decimal_point, "."); + + // test if the string represents a number + if (jsworld._isNumber(s)) + return parseFloat(s, 10); + else + throw "Parse error: Invalid number string"; + }; +}; + + +/** + * @class + * Class for parsing localised date and time strings. + * + * @public + * @constructor + * @description Creates a new date/time parser for the specified locale. + * + * @param {jsworld.Locale} locale A locale object specifying the required + * POSIX LC_TIME formatting properties. + * + * @throws Error on constructor failure. + */ +jsworld.DateTimeParser = function(locale) { + + if (typeof locale != "object" || locale._className != "jsworld.Locale") + throw "Constructor error: You must provide a valid jsworld.Locale instance."; + + this.lc = locale; + + + /** + * @public + * + * @description Parses a time string formatted according to the + * POSIX LC_TIME t_fmt property of the preset locale. + * + * @param {String} formattedTime The formatted time. + * + * @returns {String} The parsed time in ISO-8601 format (HH:MM:SS), e.g. + * "23:59:59". + * + * @throws Error on a parse exception. + */ + this.parseTime = function(formattedTime) { + + if (typeof formattedTime != "string") + throw "Parse error: Argument must be a string"; + + var dt = this._extractTokens(this.lc.t_fmt, formattedTime); + + var timeDefined = false; + + if (dt.hour !== null && dt.minute !== null && dt.second !== null) { + timeDefined = true; + } + else if (dt.hourAmPm !== null && dt.am !== null && dt.minute !== null && dt.second !== null) { + if (dt.am) { + // AM [12(midnight), 1 .. 11] + if (dt.hourAmPm == 12) + dt.hour = 0; + else + dt.hour = parseInt(dt.hourAmPm, 10); + } + else { + // PM [12(noon), 1 .. 11] + if (dt.hourAmPm == 12) + dt.hour = 12; + else + dt.hour = parseInt(dt.hourAmPm, 10) + 12; + } + timeDefined = true; + } + + if (timeDefined) + return jsworld._zeroPad(dt.hour, 2) + + ":" + + jsworld._zeroPad(dt.minute, 2) + + ":" + + jsworld._zeroPad(dt.second, 2); + else + throw "Parse error: Invalid/ambiguous time string"; + }; + + + /** + * @public + * + * @description Parses a date string formatted according to the + * POSIX LC_TIME d_fmt property of the preset locale. + * + * @param {String} formattedDate The formatted date, must be valid. + * + * @returns {String} The parsed date in ISO-8601 format (YYYY-MM-DD), + * e.g. "2010-03-31". + * + * @throws Error on a parse exception. + */ + this.parseDate = function(formattedDate) { + + if (typeof formattedDate != "string") + throw "Parse error: Argument must be a string"; + + var dt = this._extractTokens(this.lc.d_fmt, formattedDate); + + var dateDefined = false; + + if (dt.year !== null && dt.month !== null && dt.day !== null) { + dateDefined = true; + } + + if (dateDefined) + return jsworld._zeroPad(dt.year, 4) + + "-" + + jsworld._zeroPad(dt.month, 2) + + "-" + + jsworld._zeroPad(dt.day, 2); + else + throw "Parse error: Invalid date string"; + }; + + + /** + * @public + * + * @description Parses a date/time string formatted according to the + * POSIX LC_TIME d_t_fmt property of the preset locale. + * + * @param {String} formattedDateTime The formatted date/time, must be + * valid. + * + * @returns {String} The parsed date/time in ISO-8601 format + * (YYYY-MM-DD HH:MM:SS), e.g. "2010-03-31 23:59:59". + * + * @throws Error on a parse exception. + */ + this.parseDateTime = function(formattedDateTime) { + + if (typeof formattedDateTime != "string") + throw "Parse error: Argument must be a string"; + + var dt = this._extractTokens(this.lc.d_t_fmt, formattedDateTime); + + var timeDefined = false; + var dateDefined = false; + + if (dt.hour !== null && dt.minute !== null && dt.second !== null) { + timeDefined = true; + } + else if (dt.hourAmPm !== null && dt.am !== null && dt.minute !== null && dt.second !== null) { + if (dt.am) { + // AM [12(midnight), 1 .. 11] + if (dt.hourAmPm == 12) + dt.hour = 0; + else + dt.hour = parseInt(dt.hourAmPm, 10); + } + else { + // PM [12(noon), 1 .. 11] + if (dt.hourAmPm == 12) + dt.hour = 12; + else + dt.hour = parseInt(dt.hourAmPm, 10) + 12; + } + timeDefined = true; + } + + if (dt.year !== null && dt.month !== null && dt.day !== null) { + dateDefined = true; + } + + if (dateDefined && timeDefined) + return jsworld._zeroPad(dt.year, 4) + + "-" + + jsworld._zeroPad(dt.month, 2) + + "-" + + jsworld._zeroPad(dt.day, 2) + + " " + + jsworld._zeroPad(dt.hour, 2) + + ":" + + jsworld._zeroPad(dt.minute, 2) + + ":" + + jsworld._zeroPad(dt.second, 2); + else + throw "Parse error: Invalid/ambiguous date/time string"; + }; + + + /** + * @private + * + * @description Parses a string according to the specified format + * specification. + * + * @param {String} fmtSpec The format specification, e.g. "%I:%M:%S %p". + * @param {String} s The string to parse. + * + * @returns {object} An object with set properties year, month, day, + * hour, minute and second if the corresponding values are + * found in the parsed string. + * + * @throws Error on a parse exception. + */ + this._extractTokens = function(fmtSpec, s) { + + // the return object containing the parsed date/time properties + var dt = { + // for date and date/time strings + "year" : null, + "month" : null, + "day" : null, + + // for time and date/time strings + "hour" : null, + "hourAmPm" : null, + "am" : null, + "minute" : null, + "second" : null, + + // used internally only + "weekday" : null + }; + + + // extract and process each token in the date/time spec + while (fmtSpec.length > 0) { + + // Do we have a valid "%\w" placeholder in stream? + if (fmtSpec.charAt(0) == "%" && fmtSpec.charAt(1) != "") { + + // get placeholder + var placeholder = fmtSpec.substring(0,2); + + if (placeholder == "%%") { + // escaped '%'' + s = s.substring(1); + } + else if (placeholder == "%a") { + // abbreviated weekday name + for (var i = 0; i < this.lc.abday.length; i++) { + + if (jsworld._stringStartsWith(s, this.lc.abday[i])) { + dt.weekday = i; + s = s.substring(this.lc.abday[i].length); + break; + } + } + + if (dt.weekday === null) + throw "Parse error: Unrecognised abbreviated weekday name (%a)"; + } + else if (placeholder == "%A") { + // weekday name + for (var i = 0; i < this.lc.day.length; i++) { + + if (jsworld._stringStartsWith(s, this.lc.day[i])) { + dt.weekday = i; + s = s.substring(this.lc.day[i].length); + break; + } + } + + if (dt.weekday === null) + throw "Parse error: Unrecognised weekday name (%A)"; + } + else if (placeholder == "%b" || placeholder == "%h") { + // abbreviated month name + for (var i = 0; i < this.lc.abmon.length; i++) { + + if (jsworld._stringStartsWith(s, this.lc.abmon[i])) { + dt.month = i + 1; + s = s.substring(this.lc.abmon[i].length); + break; + } + } + + if (dt.month === null) + throw "Parse error: Unrecognised abbreviated month name (%b)"; + } + else if (placeholder == "%B") { + // month name + for (var i = 0; i < this.lc.mon.length; i++) { + + if (jsworld._stringStartsWith(s, this.lc.mon[i])) { + dt.month = i + 1; + s = s.substring(this.lc.mon[i].length); + break; + } + } + + if (dt.month === null) + throw "Parse error: Unrecognised month name (%B)"; + } + else if (placeholder == "%d") { + // day of the month [01..31] + if (/^0[1-9]|[1-2][0-9]|3[0-1]/.test(s)) { + dt.day = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised day of the month (%d)"; + } + else if (placeholder == "%e") { + // day of the month [1..31] + + // Note: if %e is leading in fmt string -> space padded! + + var day = s.match(/^\s?(\d{1,2})/); + dt.day = parseInt(day, 10); + + if (isNaN(dt.day) || dt.day < 1 || dt.day > 31) + throw "Parse error: Unrecognised day of the month (%e)"; + + s = s.substring(day.length); + } + else if (placeholder == "%F") { + // equivalent to %Y-%m-%d (ISO-8601 date format) + + // year [nnnn] + if (/^\d\d\d\d/.test(s)) { + dt.year = parseInt(s.substring(0,4), 10); + s = s.substring(4); + } + else { + throw "Parse error: Unrecognised date (%F)"; + } + + // - + if (jsworld._stringStartsWith(s, "-")) + s = s.substring(1); + else + throw "Parse error: Unrecognised date (%F)"; + + // month [01..12] + if (/^0[1-9]|1[0-2]/.test(s)) { + dt.month = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised date (%F)"; + + // - + if (jsworld._stringStartsWith(s, "-")) + s = s.substring(1); + else + throw "Parse error: Unrecognised date (%F)"; + + // day of the month [01..31] + if (/^0[1-9]|[1-2][0-9]|3[0-1]/.test(s)) { + dt.day = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised date (%F)"; + } + else if (placeholder == "%H") { + // hour [00..23] + if (/^[0-1][0-9]|2[0-3]/.test(s)) { + dt.hour = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised hour (%H)"; + } + else if (placeholder == "%I") { + // hour [01..12] + if (/^0[1-9]|1[0-2]/.test(s)) { + dt.hourAmPm = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised hour (%I)"; + } + else if (placeholder == "%k") { + // hour [0..23] + var h = s.match(/^(\d{1,2})/); + dt.hour = parseInt(h, 10); + + if (isNaN(dt.hour) || dt.hour < 0 || dt.hour > 23) + throw "Parse error: Unrecognised hour (%k)"; + + s = s.substring(h.length); + } + else if (placeholder == "%l") { + // hour AM/PM [1..12] + var h = s.match(/^(\d{1,2})/); + dt.hourAmPm = parseInt(h, 10); + + if (isNaN(dt.hourAmPm) || dt.hourAmPm < 1 || dt.hourAmPm > 12) + throw "Parse error: Unrecognised hour (%l)"; + + s = s.substring(h.length); + } + else if (placeholder == "%m") { + // month [01..12] + if (/^0[1-9]|1[0-2]/.test(s)) { + dt.month = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised month (%m)"; + } + else if (placeholder == "%M") { + // minute [00..59] + if (/^[0-5][0-9]/.test(s)) { + dt.minute = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised minute (%M)"; + } + else if (placeholder == "%n") { + // new line + + if (s.charAt(0) == "\n") + s = s.substring(1); + else + throw "Parse error: Unrecognised new line (%n)"; + } + else if (placeholder == "%p") { + // locale's equivalent of AM/PM + if (jsworld._stringStartsWith(s, this.lc.am)) { + dt.am = true; + s = s.substring(this.lc.am.length); + } + else if (jsworld._stringStartsWith(s, this.lc.pm)) { + dt.am = false; + s = s.substring(this.lc.pm.length); + } + else + throw "Parse error: Unrecognised AM/PM value (%p)"; + } + else if (placeholder == "%P") { + // same as %p but forced lower case + if (jsworld._stringStartsWith(s, this.lc.am.toLowerCase())) { + dt.am = true; + s = s.substring(this.lc.am.length); + } + else if (jsworld._stringStartsWith(s, this.lc.pm.toLowerCase())) { + dt.am = false; + s = s.substring(this.lc.pm.length); + } + else + throw "Parse error: Unrecognised AM/PM value (%P)"; + } + else if (placeholder == "%R") { + // same as %H:%M + + // hour [00..23] + if (/^[0-1][0-9]|2[0-3]/.test(s)) { + dt.hour = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised time (%R)"; + + // : + if (jsworld._stringStartsWith(s, ":")) + s = s.substring(1); + else + throw "Parse error: Unrecognised time (%R)"; + + // minute [00..59] + if (/^[0-5][0-9]/.test(s)) { + dt.minute = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised time (%R)"; + + } + else if (placeholder == "%S") { + // second [00..59] + if (/^[0-5][0-9]/.test(s)) { + dt.second = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised second (%S)"; + } + else if (placeholder == "%T") { + // same as %H:%M:%S + + // hour [00..23] + if (/^[0-1][0-9]|2[0-3]/.test(s)) { + dt.hour = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised time (%T)"; + + // : + if (jsworld._stringStartsWith(s, ":")) + s = s.substring(1); + else + throw "Parse error: Unrecognised time (%T)"; + + // minute [00..59] + if (/^[0-5][0-9]/.test(s)) { + dt.minute = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised time (%T)"; + + // : + if (jsworld._stringStartsWith(s, ":")) + s = s.substring(1); + else + throw "Parse error: Unrecognised time (%T)"; + + // second [00..59] + if (/^[0-5][0-9]/.test(s)) { + dt.second = parseInt(s.substring(0,2), 10); + s = s.substring(2); + } + else + throw "Parse error: Unrecognised time (%T)"; + } + else if (placeholder == "%w") { + // weekday [0..6] + if (/^\d/.test(s)) { + dt.weekday = parseInt(s.substring(0,1), 10); + s = s.substring(1); + } + else + throw "Parse error: Unrecognised weekday number (%w)"; + } + else if (placeholder == "%y") { + // year [00..99] + if (/^\d\d/.test(s)) { + var year2digits = parseInt(s.substring(0,2), 10); + + // this conversion to year[nnnn] is arbitrary!!! + if (year2digits > 50) + dt.year = 1900 + year2digits; + else + dt.year = 2000 + year2digits; + + s = s.substring(2); + } + else + throw "Parse error: Unrecognised year (%y)"; + } + else if (placeholder == "%Y") { + // year [nnnn] + if (/^\d\d\d\d/.test(s)) { + dt.year = parseInt(s.substring(0,4), 10); + s = s.substring(4); + } + else + throw "Parse error: Unrecognised year (%Y)"; + } + + else if (placeholder == "%Z") { + // time-zone place holder is not supported + + if (fmtSpec.length === 0) + break; // ignore rest of fmt spec + } + + // remove the spec placeholder that was just parsed + fmtSpec = fmtSpec.substring(2); + } + else { + // If we don't have a placeholder, the chars + // at pos. 0 of format spec and parsed string must match + + // Note: Space chars treated 1:1 ! + + if (fmtSpec.charAt(0) != s.charAt(0)) + throw "Parse error: Unexpected symbol \"" + s.charAt(0) + "\" in date/time string"; + + fmtSpec = fmtSpec.substring(1); + s = s.substring(1); + } + } + + // parsing finished, return composite date/time object + return dt; + }; +}; + + +/** + * @class + * Class for parsing localised currency amount strings. + * + * @public + * @constructor + * @description Creates a new monetary parser for the specified locale. + * + * @param {jsworld.Locale} locale A locale object specifying the required + * POSIX LC_MONETARY formatting properties. + * + * @throws Error on constructor failure. + */ +jsworld.MonetaryParser = function(locale) { + + if (typeof locale != "object" || locale._className != "jsworld.Locale") + throw "Constructor error: You must provide a valid jsworld.Locale instance"; + + + this.lc = locale; + + + /** + * @public + * + * @description Parses a currency amount string formatted according to + * the preset locale. Leading and trailing whitespace is ignored; the + * amount may also be formatted without thousands separators. Both + * the local (shorthand) symbol and the ISO 4217 code are accepted to + * designate the currency in the formatted amount. + * + * @param {String} formattedCurrency The formatted currency amount. + * + * @returns {Number} The parsed amount. + * + * @throws Error on a parse exception. + */ + this.parse = function(formattedCurrency) { + + if (typeof formattedCurrency != "string") + throw "Parse error: Argument must be a string"; + + // Detect the format type and remove the currency symbol + var symbolType = this._detectCurrencySymbolType(formattedCurrency); + + var formatType, s; + + if (symbolType == "local") { + formatType = "local"; + s = formattedCurrency.replace(this.lc.getCurrencySymbol(), ""); + } + else if (symbolType == "int") { + formatType = "int"; + s = formattedCurrency.replace(this.lc.getIntCurrencySymbol(), ""); + } + else if (symbolType == "none") { + formatType = "local"; // assume local + s = formattedCurrency; + } + else + throw "Parse error: Internal assert failure"; + + // Remove any thousands separators + s = jsworld._stringReplaceAll(s, this.lc.mon_thousands_sep, ""); + + // Replace any local radix char with JavaScript's "." + s = s.replace(this.lc.mon_decimal_point, "."); + + // Remove all whitespaces + s = s.replace(/\s*/g, ""); + + // Remove any local non-negative sign + s = this._removeLocalNonNegativeSign(s, formatType); + + // Replace any local minus sign with JavaScript's "-" and put + // it in front of the amount if necessary + // (special parentheses rule checked too) + s = this._normaliseNegativeSign(s, formatType); + + // Finally, we should be left with a bare parsable decimal number + if (jsworld._isNumber(s)) + return parseFloat(s, 10); + else + throw "Parse error: Invalid currency amount string"; + }; + + + /** + * @private + * + * @description Tries to detect the symbol type used in the specified + * formatted currency string: local(shorthand), + * international (ISO-4217 code) or none. + * + * @param {String} formattedCurrency The the formatted currency string. + * + * @return {String} With possible values "local", "int" or "none". + */ + this._detectCurrencySymbolType = function(formattedCurrency) { + + // Check for whichever sign (int/local) is longer first + // to cover cases such as MOP/MOP$ and ZAR/R + + if (this.lc.getCurrencySymbol().length > this.lc.getIntCurrencySymbol().length) { + + if (formattedCurrency.indexOf(this.lc.getCurrencySymbol()) != -1) + return "local"; + else if (formattedCurrency.indexOf(this.lc.getIntCurrencySymbol()) != -1) + return "int"; + else + return "none"; + } + else { + if (formattedCurrency.indexOf(this.lc.getIntCurrencySymbol()) != -1) + return "int"; + else if (formattedCurrency.indexOf(this.lc.getCurrencySymbol()) != -1) + return "local"; + else + return "none"; + } + }; + + + /** + * @private + * + * @description Removes a local non-negative sign in a formatted + * currency string if it is found. This is done according to the + * locale properties p_sign_posn and int_p_sign_posn. + * + * @param {String} s The input string. + * @param {String} formatType With possible values "local" or "int". + * + * @returns {String} The processed string. + */ + this._removeLocalNonNegativeSign = function(s, formatType) { + + s = s.replace(this.lc.positive_sign, ""); + + // check for enclosing parentheses rule + if (((formatType == "local" && this.lc.p_sign_posn === 0) || + (formatType == "int" && this.lc.int_p_sign_posn === 0) ) && + /\(\d+\.?\d*\)/.test(s)) { + s = s.replace("(", ""); + s = s.replace(")", ""); + } + + return s; + }; + + + /** + * @private + * + * @description Replaces a local negative sign with the standard + * JavaScript minus ("-") sign placed in the correct position + * (preceding the amount). This is done according to the locale + * properties for negative sign symbol and relative position. + * + * @param {String} s The input string. + * @param {String} formatType With possible values "local" or "int". + * + * @returns {String} The processed string. + */ + this._normaliseNegativeSign = function(s, formatType) { + + // replace local negative symbol with JavaScript's "-" + s = s.replace(this.lc.negative_sign, "-"); + + // check for enclosing parentheses rule and replace them + // with negative sign before the amount + if ((formatType == "local" && this.lc.n_sign_posn === 0) || + (formatType == "int" && this.lc.int_n_sign_posn === 0) ) { + + if (/^\(\d+\.?\d*\)$/.test(s)) { + + s = s.replace("(", ""); + s = s.replace(")", ""); + return "-" + s; + } + } + + // check for rule negative sign succeeding the amount + if (formatType == "local" && this.lc.n_sign_posn == 2 || + formatType == "int" && this.lc.int_n_sign_posn == 2 ) { + + if (/^\d+\.?\d*-$/.test(s)) { + s = s.replace("-", ""); + return "-" + s; + } + } + + // check for rule cur. sym. succeeds and sign adjacent + if (formatType == "local" && this.lc.n_cs_precedes === 0 && this.lc.n_sign_posn == 3 || + formatType == "local" && this.lc.n_cs_precedes === 0 && this.lc.n_sign_posn == 4 || + formatType == "int" && this.lc.int_n_cs_precedes === 0 && this.lc.int_n_sign_posn == 3 || + formatType == "int" && this.lc.int_n_cs_precedes === 0 && this.lc.int_n_sign_posn == 4 ) { + + if (/^\d+\.?\d*-$/.test(s)) { + s = s.replace("-", ""); + return "-" + s; + } + } + + return s; + }; +}; + +// end-of-file diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs2.js b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs2.js new file mode 100644 index 0000000..4e9f967 --- /dev/null +++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs2.js @@ -0,0 +1,166 @@ +jsworld.Locale = function(properties) { + + // LC_NUMERIC + + + this.frac_digits = properties.frac_digits; + + + // may be empty string/null for currencies with no fractional part + if (properties.mon_decimal_point === null || properties.mon_decimal_point == "") { + + if (this.frac_digits > 0) + throw "Error: Undefined mon_decimal_point property"; + else + properties.mon_decimal_point = ""; + } + + if (typeof properties.mon_decimal_point != "string") + throw "Error: Invalid/missing mon_decimal_point property"; + + this.mon_decimal_point = properties.mon_decimal_point; + + + if (typeof properties.mon_thousands_sep != "string") + throw "Error: Invalid/missing mon_thousands_sep property"; + + this.mon_thousands_sep = properties.mon_thousands_sep; + + + if (typeof properties.mon_grouping != "string") + throw "Error: Invalid/missing mon_grouping property"; + + this.mon_grouping = properties.mon_grouping; + + + if (typeof properties.positive_sign != "string") + throw "Error: Invalid/missing positive_sign property"; + + this.positive_sign = properties.positive_sign; + + + if (typeof properties.negative_sign != "string") + throw "Error: Invalid/missing negative_sign property"; + + this.negative_sign = properties.negative_sign; + + + if (properties.p_cs_precedes !== 0 && properties.p_cs_precedes !== 1) + throw "Error: Invalid/missing p_cs_precedes property, must be 0 or 1"; + + this.p_cs_precedes = properties.p_cs_precedes; + + + if (properties.n_cs_precedes !== 0 && properties.n_cs_precedes !== 1) + throw "Error: Invalid/missing n_cs_precedes, must be 0 or 1"; + + this.n_cs_precedes = properties.n_cs_precedes; + + + if (properties.p_sep_by_space !== 0 && + properties.p_sep_by_space !== 1 && + properties.p_sep_by_space !== 2) + throw "Error: Invalid/missing p_sep_by_space property, must be 0, 1 or 2"; + + this.p_sep_by_space = properties.p_sep_by_space; + + + if (properties.n_sep_by_space !== 0 && + properties.n_sep_by_space !== 1 && + properties.n_sep_by_space !== 2) + throw "Error: Invalid/missing n_sep_by_space property, must be 0, 1, or 2"; + + this.n_sep_by_space = properties.n_sep_by_space; + + + if (properties.p_sign_posn !== 0 && + properties.p_sign_posn !== 1 && + properties.p_sign_posn !== 2 && + properties.p_sign_posn !== 3 && + properties.p_sign_posn !== 4) + throw "Error: Invalid/missing p_sign_posn property, must be 0, 1, 2, 3 or 4"; + + this.p_sign_posn = properties.p_sign_posn; + + + if (properties.n_sign_posn !== 0 && + properties.n_sign_posn !== 1 && + properties.n_sign_posn !== 2 && + properties.n_sign_posn !== 3 && + properties.n_sign_posn !== 4) + throw "Error: Invalid/missing n_sign_posn property, must be 0, 1, 2, 3 or 4"; + + this.n_sign_posn = properties.n_sign_posn; + + + if (typeof properties.int_frac_digits != "number" && properties.int_frac_digits < 0) + throw "Error: Invalid/missing int_frac_digits property"; + + this.int_frac_digits = properties.int_frac_digits; + + + if (properties.int_p_cs_precedes !== 0 && properties.int_p_cs_precedes !== 1) + throw "Error: Invalid/missing int_p_cs_precedes property, must be 0 or 1"; + + this.int_p_cs_precedes = properties.int_p_cs_precedes; + + + if (properties.int_n_cs_precedes !== 0 && properties.int_n_cs_precedes !== 1) + throw "Error: Invalid/missing int_n_cs_precedes property, must be 0 or 1"; + + this.int_n_cs_precedes = properties.int_n_cs_precedes; + + + if (properties.int_p_sep_by_space !== 0 && + properties.int_p_sep_by_space !== 1 && + properties.int_p_sep_by_space !== 2) + throw "Error: Invalid/missing int_p_sep_by_spacev, must be 0, 1 or 2"; + + this.int_p_sep_by_space = properties.int_p_sep_by_space; + + + if (properties.int_n_sep_by_space !== 0 && + properties.int_n_sep_by_space !== 1 && + properties.int_n_sep_by_space !== 2) + throw "Error: Invalid/missing int_n_sep_by_space property, must be 0, 1, or 2"; + + this.int_n_sep_by_space = properties.int_n_sep_by_space; + + + if (properties.int_p_sign_posn !== 0 && + properties.int_p_sign_posn !== 1 && + properties.int_p_sign_posn !== 2 && + properties.int_p_sign_posn !== 3 && + properties.int_p_sign_posn !== 4) + throw "Error: Invalid/missing int_p_sign_posn property, must be 0, 1, 2, 3 or 4"; + + this.int_p_sign_posn = properties.int_p_sign_posn; + + + if (properties.int_n_sign_posn !== 0 && + properties.int_n_sign_posn !== 1 && + properties.int_n_sign_posn !== 2 && + properties.int_n_sign_posn !== 3 && + properties.int_n_sign_posn !== 4) + throw "Error: Invalid/missing int_n_sign_posn property, must be 0, 1, 2, 3 or 4"; + + this.int_n_sign_posn = properties.int_n_sign_posn; + + + // LC_TIME + + if (properties == null || typeof properties != "object") + throw "Error: Invalid/missing time locale properties"; + + + // parse the supported POSIX LC_TIME properties + + // abday + try { + this.abday = this._parseList(properties.abday, 7); + } + catch (error) { + throw "Error: Invalid abday property: " + error; + } + +} -- cgit v1.2.3