diff --git a/dist/lib/swagger-client.js b/dist/lib/swagger-client.js index d5ca3135..599d19be 100644 --- a/dist/lib/swagger-client.js +++ b/dist/lib/swagger-client.js @@ -1,103 +1,59 @@ /** * swagger-client - swagger.js is a javascript client for use with swaggering APIs. - * @version v2.1.9-M1 + * @version v2.1.10-M1 * @link http://swagger.io * @license apache 2.0 */ -(function(){ -var ArrayModel = function(definition) { - this.name = "arrayModel"; - this.definition = definition || {}; - this.properties = []; +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SwaggerClient = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o' + propertiesStr.join(',
') + '
' + classClose; +SwaggerClient.ApiKeyAuthorization = auth.ApiKeyAuthorization; +SwaggerClient.PasswordAuthorization = auth.PasswordAuthorization; +SwaggerClient.CookieAuthorization = auth.CookieAuthorization; +SwaggerClient.SwaggerApi = deprecationWrapper; +SwaggerClient.SwaggerClient = deprecationWrapper; - if (!modelsToIgnore) - modelsToIgnore = {}; - modelsToIgnore[this.name] = this; - for (i = 0; i < this.properties.length; i++) { - prop = this.properties[i]; - var ref = prop.$ref; - var model = models[ref]; - if (model && typeof modelsToIgnore[ref] === 'undefined') { - returnVal = returnVal + ('
' + model.getMockSignature(modelsToIgnore)); - } - } - return returnVal; -}; +},{"./lib/auth":2,"./lib/client-compat":3,"./lib/helpers":5}],2:[function(require,module,exports){ +'use strict'; +var btoa = require('btoa'); // jshint ignore:line +var CookieJar = require('cookiejar'); /** * SwaggerAuthorizations applys the correct authorization to an operation being executed */ -var SwaggerAuthorizations = function() { +var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function () { this.authz = {}; }; -SwaggerAuthorizations.prototype.add = function(name, auth) { +SwaggerAuthorizations.prototype.add = function (name, auth) { this.authz[name] = auth; + return auth; }; -SwaggerAuthorizations.prototype.remove = function(name) { +SwaggerAuthorizations.prototype.remove = function (name) { return delete this.authz[name]; }; @@ -105,42 +61,46 @@ SwaggerAuthorizations.prototype.apply = function (obj, authorizations) { var status = null; var key, name, value, result; - // if the "authorizations" key is undefined, or has an empty array, add all keys + // if the 'authorizations' key is undefined, or has an empty array, add all keys if (typeof authorizations === 'undefined' || Object.keys(authorizations).length === 0) { for (key in this.authz) { value = this.authz[key]; result = value.apply(obj, authorizations); - if (result === true) + + if (result === true) { status = true; + } } - } - else { + } else { // 2.0 support if (Array.isArray(authorizations)) { - for (var i = 0; i < authorizations.length; i++) { var auth = authorizations[i]; + for (name in auth) { for (key in this.authz) { - if (key == name) { + if (key === name) { value = this.authz[key]; result = value.apply(obj, authorizations); - if (result === true) + + if (result === true) { status = true; + } } } } } - } - else { + } else { // 1.2 support for (name in authorizations) { for (key in this.authz) { - if (key == name) { + if (key === name) { value = this.authz[key]; result = value.apply(obj, authorizations); - if (result === true) + + if (result === true) { status = true; + } } } } @@ -153,3141 +113,16016 @@ SwaggerAuthorizations.prototype.apply = function (obj, authorizations) { /** * ApiKeyAuthorization allows a query param or header to be injected */ -var ApiKeyAuthorization = function(name, value, type) { +var ApiKeyAuthorization = module.exports.ApiKeyAuthorization = function (name, value, type) { this.name = name; this.value = value; this.type = type; }; -ApiKeyAuthorization.prototype.apply = function(obj, authorizations) { - if (this.type === "query") { - if (obj.url.indexOf('?') > 0) - obj.url = obj.url + "&" + this.name + "=" + this.value; - else - obj.url = obj.url + "?" + this.name + "=" + this.value; +ApiKeyAuthorization.prototype.apply = function (obj) { + if (this.type === 'query') { + if (obj.url.indexOf('?') > 0) { + obj.url = obj.url + '&' + this.name + '=' + this.value; + } else { + obj.url = obj.url + '?' + this.name + '=' + this.value; + } + return true; - } else if (this.type === "header") { + } else if (this.type === 'header') { obj.headers[this.name] = this.value; + return true; } }; -var CookieAuthorization = function(cookie) { +var CookieAuthorization = module.exports.CookieAuthorization = function (cookie) { this.cookie = cookie; }; -CookieAuthorization.prototype.apply = function(obj, authorizations) { - obj.cookieJar = obj.cookieJar || CookieJar(); +CookieAuthorization.prototype.apply = function (obj) { + obj.cookieJar = obj.cookieJar || new CookieJar(); obj.cookieJar.setCookie(this.cookie); + return true; }; /** * Password Authorization is a basic auth implementation */ -var PasswordAuthorization = function(name, username, password) { +var PasswordAuthorization = module.exports.PasswordAuthorization = function (name, username, password) { this.name = name; this.username = username; this.password = password; - this._btoa = null; - if (typeof window !== 'undefined') - this._btoa = btoa; - else - this._btoa = require("btoa"); }; -PasswordAuthorization.prototype.apply = function(obj, authorizations) { - var base64encoder = this._btoa; - obj.headers.Authorization = "Basic " + base64encoder(this.username + ":" + this.password); +PasswordAuthorization.prototype.apply = function (obj) { + obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password); + return true; }; -var __bind = function(fn, me){ - return function(){ - return fn.apply(me, arguments); - }; -}; -fail = function(message) { - log(message); -}; +},{"btoa":16,"cookiejar":17}],3:[function(require,module,exports){ +'use strict'; -log = function(){ - log.history = log.history || []; - log.history.push(arguments); - if(this.console){ - console.log( Array.prototype.slice.call(arguments)[0] ); - } -}; +var helpers = require('./helpers'); +var SwaggerClient = require('./client'); +var SwaggerHttp = require('./http'); -if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function(obj, start) { - for (var i = (start || 0), j = this.length; i < j; i++) { - if (this[i] === obj) { return i; } - } - return -1; - }; -} +module.exports = SwaggerClient; /** * allows override of the default value based on the parameter being * supplied **/ var applyParameterMacro = function (operation, parameter) { - var e = (typeof window !== 'undefined' ? window : exports); - if(e.parameterMacro) - return e.parameterMacro(operation, parameter); - else + if (operation.api.parameterMacro) { + return operation.api.parameterMacro(operation, parameter); + } else { return parameter.defaultValue; + } }; /** * allows overriding the default value of an model property **/ var applyModelPropertyMacro = function (model, property) { - var e = (typeof window !== 'undefined' ? window : exports); - if(e.modelPropertyMacro) - return e.modelPropertyMacro(model, property); - else + if (model.api.modelPropertyMacro) { + return model.api.modelPropertyMacro(model, property); + } else { return property.defaultValue; + } }; -/** - * PrimitiveModel - **/ -var PrimitiveModel = function(definition) { - this.name = "name"; - this.definition = definition || {}; - this.properties = []; +var SwaggerModelProperty = function (name, obj, model) { + this.name = name; + this.dataType = obj.type || obj.dataType || obj.$ref; + this.isCollection = this.dataType && (this.dataType.toLowerCase() === 'array' || this.dataType.toLowerCase() === 'list' || this.dataType.toLowerCase() === 'set'); + this.descr = obj.description; + this.required = obj.required; + this.defaultValue = applyModelPropertyMacro(model, obj); - var requiredFields = definition.enum || []; - this.type = typeFromJsonSchema(definition.type, definition.format); -}; + if (obj.items) { + if (obj.items.type) { + this.refDataType = obj.items.type; + } -PrimitiveModel.prototype.createJSONSample = function(modelsToIgnore) { - var result = this.type; - return result; -}; + if (obj.items.$ref) { + this.refDataType = obj.items.$ref; + } + } -PrimitiveModel.prototype.getSampleValue = function() { - var result = this.type; - return null; -}; + this.dataTypeWithRef = this.refDataType ? (this.dataType + '[' + this.refDataType + ']') : this.dataType; -PrimitiveModel.prototype.getMockSignature = function(modelsToIgnore) { - var propertiesStr = []; - var i, prop; - for (i = 0; i < this.properties.length; i++) { - prop = this.properties[i]; - propertiesStr.push(prop.toString()); + if (obj.allowableValues) { + this.valueType = obj.allowableValues.valueType; + this.values = obj.allowableValues.values; + + if (this.values) { + this.valuesString = '\'' + this.values.join('\' or \'') + '\''; + } } - var strong = ''; - var stronger = ''; - var strongClose = ''; - var classOpen = strong + this.name + ' {' + strongClose; - var classClose = strong + '}' + strongClose; - var returnVal = classOpen + '
' + propertiesStr.join(',
') + '
' + classClose; + if (obj['enum']) { + this.valueType = 'string'; + this.values = obj['enum']; - if (!modelsToIgnore) - modelsToIgnore = {}; - modelsToIgnore[this.name] = this; - for (i = 0; i < this.properties.length; i++) { - prop = this.properties[i]; - var ref = prop.$ref; - var model = models[ref]; - if (model && typeof modelsToIgnore[ref] === 'undefined') { - returnVal = returnVal + ('
' + model.getMockSignature(modelsToIgnore)); + if (this.values) { + this.valueString = '\'' + this.values.join('\' or \'') + '\''; } } - return returnVal; }; -/** - * Resolves a spec's remote references - */ -var Resolver = function (){}; -Resolver.prototype.resolve = function(spec, callback, scope) { - this.scope = (scope || this); - var host, name, path, property, propertyName, type; - var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {}; +var SwaggerModel = function (modelName, obj, api) { + this.api = api; + this.name = typeof obj.id !== 'undefined' ? obj.id : modelName; + this.properties = []; + this.sampleModels = api.sampleModels; - // store objects for dereferencing - var resolutionTable = {}; + var propertyName; - // models - for(name in spec.definitions) { - var model = spec.definitions[name]; - for(propertyName in model.properties) { - property = model.properties[propertyName]; - this.resolveTo(property, resolutionTable); - } - } - // operations - for(name in spec.paths) { - var method, operation, responseCode; - path = spec.paths[name]; - for(method in path) { - operation = path[method]; - var i, parameters = operation.parameters; - for(i in parameters) { - var parameter = parameters[i]; - if(parameter.in === 'body' && parameter.schema) { - this.resolveTo(parameter.schema, resolutionTable); - } - if(parameter.$ref) { - this.resolveInline(spec, parameter, resolutionTable, unresolvedRefs); - } - } - for(responseCode in operation.responses) { - var response = operation.responses[responseCode]; - if(response.schema) { - this.resolveTo(response.schema, resolutionTable); + for (propertyName in obj.properties) { + if (obj.required) { + var value; + + for (value in obj.required) { + if (propertyName === obj.required[value]) { + obj.properties[propertyName].required = true; } } } + + var prop = new SwaggerModelProperty(propertyName, obj.properties[propertyName], this); + + this.properties.push(prop); } - // get hosts - var opts = {}, expectedCalls = 0; - for(name in resolutionTable) { - var parts = name.split('#'); - if(parts.length == 2) { - host = parts[0]; path = parts[1]; - if(!Array.isArray(opts[host])) { - opts[host] = []; - expectedCalls += 1; +}; + +var SwaggerOperation = function (nickname, path, method, parameters, summary, notes, type, responseMessages, resource, + consumes, produces, authorizations, deprecated, clientAuthorizations) { + var self = this; + var errors = []; + + this.clientAuthorizations = clientAuthorizations; + this.nickname = (nickname || errors.push('SwaggerOperations must have a nickname.')); + this.path = (path || errors.push('SwaggerOperation ' + nickname + ' is missing path.')); + this.method = (method || errors.push('SwaggerOperation ' + nickname + ' is missing method.')); + this.parameters = parameters ? parameters : []; + this.summary = summary; + this.notes = notes; + this.type = type; + this.responseMessages = (responseMessages || []); + this.resource = (resource || errors.push('Resource is required')); + this.consumes = consumes; + this.produces = produces; + this.authorizations = typeof authorizations !== 'undefined' ? authorizations : resource.authorizations; + this.deprecated = deprecated; + this.do = helpers.__bind(this.do, this); + this.api = this.resource.api; + + if (typeof this.deprecated === 'string') { + switch(this.deprecated.toLowerCase()) { + case 'true': case 'yes': case '1': { + this.deprecated = true; + + break; } - opts[host].push(path); + case 'false': case 'no': case '0': case null: { + this.deprecated = false; + + break; + } + default: this.deprecated = Boolean(this.deprecated); } } - for(name in opts) { - var self = this, opt = opts[name]; - host = name; + if (errors.length > 0) { + console.error('SwaggerOperation errors', errors, arguments); - var obj = { - useJQuery: false, // TODO - url: host, - method: "get", - headers: { - accept: this.scope.swaggerRequestHeaders || 'application/json' - }, - on: { - error: function(response) { - processedCalls += 1; - var i; - for(i = 0; i < opt.length; i++) { - // fail all of these - var resolved = host + '#' + opt[i]; - unresolvedRefs[resolved] = null; - } - if(processedCalls === expectedCalls) - self.finish(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback); - }, - response: function(response) { - var i, j, swagger = response.obj; - processedCalls += 1; - for(i = 0; i < opt.length; i++) { - var location = swagger, path = opt[i], parts = path.split('/'); - for(j = 0; j < parts.length; j++) { - var segment = parts[j]; - if(typeof location === 'undefined') - break; - if(segment.length > 0) - location = location[segment]; - } - var resolved = host + '#' + path, resolvedName = parts[j-1]; - if(typeof location !== 'undefined') { - resolvedRefs[resolved] = { - name: resolvedName, - obj: location - }; - } - else unresolvedRefs[resolved] = null; - } - if(processedCalls === expectedCalls) - self.finish(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback); - } - } - }; - authorizations.apply(obj); - new SwaggerHttp().execute(obj); + this.resource.api.fail(errors); } - if(Object.keys(opts).length === 0) - callback.call(this.scope, spec, unresolvedRefs); -}; -Resolver.prototype.finish = function(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback) { - // walk resolution table and replace with resolved refs - var ref; - for(ref in resolutionTable) { - var i, locations = resolutionTable[ref]; - for(i = 0; i < locations.length; i++) { - var resolvedTo = resolvedRefs[locations[i].obj.$ref]; - if(resolvedTo) { - if(!spec.definitions) - spec.definitions = {}; - if(locations[i].resolveAs === '$ref') { - spec.definitions[resolvedTo.name] = resolvedTo.obj; - locations[i].obj.$ref = '#/definitions/' + resolvedTo.name; - } - else if (locations[i].resolveAs === 'inline') { - var key; - var targetObj = locations[i].obj; - delete targetObj.$ref; - for(key in resolvedTo.obj) { - targetObj[key] = resolvedTo.obj[key]; - } - } - } - } + this.path = this.path.replace('{format}', 'json'); + this.method = this.method.toLowerCase(); + this.isGetMethod = this.method === 'get'; + + var i, j, v; + + this.resourceName = this.resource.name; + + if (typeof this.type !== 'undefined' && this.type === 'void') { + this.type = null; + } else { + this.responseClassSignature = this.getSignature(this.type, this.resource.models); + this.responseSampleJSON = this.getSampleJSON(this.type, this.resource.models); } - callback.call(this.scope, spec, unresolvedRefs); -}; -/** - * immediately in-lines local refs, queues remote refs - * for inline resolution - */ -Resolver.prototype.resolveInline = function (spec, property, objs, unresolvedRefs) { - var ref = property.$ref; - if(ref) { - if(ref.indexOf('http') === 0) { - if(Array.isArray(objs[ref])) { - objs[ref].push({obj: property, resolveAs: 'inline'}); - } - else { - objs[ref] = [{obj: property, resolveAs: 'inline'}]; - } + for (i = 0; i < this.parameters.length; i++) { + var param = this.parameters[i]; + + param.name = param.name || param.type || param.dataType; // might take this away + type = param.type || param.dataType; // for 1.1 compatibility + + if (type === 'array') { + type = 'array[' + (param.items.$ref ? param.items.$ref : param.items.type) + ']'; } - else if (ref.indexOf('#') === 0) { - // local resolve - var shortenedRef = ref.substring(1); - var i, parts = shortenedRef.split('/'), location = spec; - for(i = 0; i < parts.length; i++) { - var part = parts[i]; - if(part.length > 0) { - location = location[part]; + + param.type = type; + + if (type && type.toLowerCase() === 'boolean') { + param.allowableValues = {}; + param.allowableValues.values = ['true', 'false']; + } + + param.signature = this.getSignature(type, this.resource.models); + param.sampleJSON = this.getSampleJSON(type, this.resource.models); + + var enumValue = param['enum']; + + if (typeof enumValue !== 'undefined') { + param.isList = true; + param.allowableValues = {}; + param.allowableValues.descriptiveValues = []; + + for (j = 0; j < enumValue.length; j++) { + v = enumValue[j]; + + if (param.defaultValue) { + param.allowableValues.descriptiveValues.push({ + value: String(v), + isDefault: (v === param.defaultValue) + }); + } else { + param.allowableValues.descriptiveValues.push({ + value: String(v), + isDefault: false + }); } } - if(location) { - delete property.$ref; - var key; - for(key in location) { - property[key] = location[key]; + } else if (param.allowableValues) { + if (param.allowableValues.valueType === 'RANGE') { + param.isRange = true; + } else { + param.isList = true; + } + + if (param.allowableValues) { + param.allowableValues.descriptiveValues = []; + + if (param.allowableValues.values) { + for (j = 0; j < param.allowableValues.values.length; j++) { + v = param.allowableValues.values[j]; + + if (param.defaultValue !== null) { + param.allowableValues.descriptiveValues.push({ + value: String(v), + isDefault: (v === param.defaultValue) + }); + } else { + param.allowableValues.descriptiveValues.push({ + value: String(v), + isDefault: false + }); + } + } } } - else unresolvedRefs[ref] = null; } + + param.defaultValue = applyParameterMacro(this, param); } - else if(property.type === 'array') { - this.resolveTo(property.items, objs); - } -}; -Resolver.prototype.resolveTo = function (property, objs) { - var ref = property.$ref; - if(ref) { - if(ref.indexOf('http') === 0) { - if(Array.isArray(objs[ref])) { - objs[ref].push({obj: property, resolveAs: '$ref'}); - } - else { - objs[ref] = [{obj: property, resolveAs: '$ref'}]; - } + var defaultSuccessCallback = this.resource.api.defaultSuccessCallback || null; + var defaultErrorCallback = this.resource.api.defaultErrorCallback || null; + + this.resource[this.nickname] = function (args, opts, callback, error) { + var arg1, arg2, arg3, arg4; + + if (typeof args === 'function') { // right shift 3 + arg1 = {}; arg2 = {}; arg3 = args; arg4 = opts; + } else if (typeof args === 'object' && typeof opts === 'function') { // right shift 2 + arg1 = args; arg2 = {}; arg3 = opts; arg4 = callback; + } else { + arg1 = args; arg2 = opts; arg3 = callback; arg4 = error; } - } - else if(property.type === 'array') { - var items = property.items; - this.resolveTo(items, objs); - } -}; -var addModel = function(name, model) { - models[name] = model; -}; -var SwaggerClient = function(url, options) { - this.isBuilt = false; - this.url = null; - this.debug = false; - this.basePath = null; - this.modelsArray = []; - this.authorizations = null; - this.authorizationScheme = null; - this.isValid = false; - this.info = null; - this.useJQuery = false; - this.resourceCount = 0; + return self['do'](arg1 || {}, arg2 || {}, arg3 || defaultSuccessCallback, arg4 || defaultErrorCallback); + }; - if(typeof url !== 'undefined') - return this.initialize(url, options); + this.resource[this.nickname].help = function (dontPrint) { + return self.help(dontPrint); + }; + this.resource[this.nickname].asCurl = function (args) { + return self.asCurl(args); + }; }; -SwaggerClient.prototype.initialize = function (url, options) { - this.models = models = {}; +var SwaggerRequest = function (type, url, params, opts, successCallback, errorCallback, operation, execution) { + var _this = this; + var errors = []; - options = (options||{}); + this.useJQuery = (typeof operation.resource.useJQuery !== 'undefined' ? operation.resource.useJQuery : null); + this.type = (type || errors.push('SwaggerRequest type is required (get/post/put/delete/patch/options).')); + this.url = (url || errors.push('SwaggerRequest url is required.')); + this.params = params; + this.opts = opts; + this.successCallback = (successCallback || errors.push('SwaggerRequest successCallback is required.')); + this.errorCallback = (errorCallback || errors.push('SwaggerRequest error callback is required.')); + this.operation = (operation || errors.push('SwaggerRequest operation is required.')); + this.execution = execution; + this.headers = (params.headers || {}); - if(typeof url === 'string') - this.url = url; - else if(typeof url === 'object') { - options = url; - this.url = options.url; + if (errors.length > 0) { + throw errors; } - this.swaggerRequstHeaders = options.swaggerRequstHeaders || 'application/json;charset=utf-8,*/*'; - this.defaultSuccessCallback = options.defaultSuccessCallback || null; - this.defaultErrorCallback = options.defaultErrorCallback || null; - if (typeof options.success === 'function') - this.success = options.success; + this.type = this.type.toUpperCase(); - if (options.useJQuery) - this.useJQuery = options.useJQuery; + // set request, response content type headers + var headers = this.setHeaders(params, opts, this.operation); + var body = params.body; - if (options.authorizations) { - this.clientAuthorizations = options.authorizations; - } else { - this.clientAuthorizations = authorizations; - } + // encode the body for form submits + if (headers['Content-Type']) { + var key, value, values = {}, i; + var operationParams = this.operation.parameters; - this.supportedSubmitMethods = options.supportedSubmitMethods || []; - this.failure = options.failure || function() {}; - this.progress = options.progress || function() {}; - this.spec = options.spec; - this.options = options; + for (i = 0; i < operationParams.length; i++) { + var param = operationParams[i]; - if (typeof options.success === 'function') { - this.ready = true; - this.build(); - } -}; + if (param.paramType === 'form') { + values[param.name] = param; + } + } -SwaggerClient.prototype.build = function(mock) { - if (this.isBuilt) return this; - var self = this; - this.progress('fetching resource list: ' + this.url); - var obj = { - useJQuery: this.useJQuery, - url: this.url, - method: "get", - headers: { - accept: this.swaggerRequstHeaders - }, - on: { - error: function(response) { - if (self.url.substring(0, 4) !== 'http') - return self.fail('Please specify the protocol for ' + self.url); - else if (response.status === 0) - return self.fail('Can\'t read from server. It may not have the appropriate access-control-origin settings.'); - else if (response.status === 404) - return self.fail('Can\'t read swagger JSON from ' + self.url); - else - return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url); - }, - response: function(resp) { - var responseObj = resp.obj || JSON.parse(resp.data); - self.swaggerVersion = responseObj.swaggerVersion; + if (headers['Content-Type'].indexOf('application/x-www-form-urlencoded') === 0) { + var encoded = ''; - if(responseObj.swagger && parseInt(responseObj.swagger) === 2) { - self.swaggerVersion = responseObj.swagger; - new Resolver().resolve(responseObj, self.buildFromSpec, self); - self.isValid = true; - } - else { - if (self.swaggerVersion === '1.2') { - return self.buildFrom1_2Spec(responseObj); - } else { - return self.buildFrom1_1Spec(responseObj); + for (key in values) { + value = this.params[key]; + + if (typeof value !== 'undefined') { + if (encoded !== '') { + encoded += '&'; } + + encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value); } } - } - }; - if(this.spec) { - setTimeout(function() { - new Resolver().resolve(self.spec, self.buildFromSpec, self); - }, 10); - } - else { - authorizations.apply(obj); - if(mock) - return obj; - new SwaggerHttp().execute(obj); - } - return this; -}; -SwaggerClient.prototype.buildFromSpec = function(response) { - if(this.isBuilt) return this; + body = encoded; + } else if (headers['Content-Type'].indexOf('multipart/form-data') === 0) { + // encode the body for form submits + var data = ''; + var boundary = '----SwaggerFormBoundary' + Date.now(); - this.info = response.info || {}; - this.title = response.title || ''; - this.host = response.host || ''; - this.schemes = response.schemes || []; - this.basePath = response.basePath || ''; - this.apis = {}; - this.apisArray = []; - this.consumes = response.consumes; - this.produces = response.produces; - this.securityDefinitions = response.securityDefinitions; + for (key in values) { + value = this.params[key]; - // legacy support - this.authSchemes = response.securityDefinitions; + if (typeof value !== 'undefined') { + data += '--' + boundary + '\n'; + data += 'Content-Disposition: form-data; name="' + key + '"'; + data += '\n\n'; + data += value + '\n'; + } + } - var definedTags = {}; - if(Array.isArray(response.tags)) { - definedTags = {}; - for(k = 0; k < response.tags.length; k++) { - var t = response.tags[k]; - definedTags[t.name] = t; + data += '--' + boundary + '--\n'; + headers['Content-Type'] = 'multipart/form-data; boundary=' + boundary; + body = data; } } - var location; - if(typeof this.url === 'string') { - location = this.parseUri(this.url); - } + var obj; - if(typeof this.schemes === 'undefined' || this.schemes.length === 0) { - this.scheme = location.scheme || 'http'; - } - else { - this.scheme = this.schemes[0]; - } + if (!((this.headers) && (this.headers.mock))) { + obj = { + url: this.url, + method: this.type, + headers: headers, + body: body, + useJQuery: this.useJQuery, + on: { + error: function (response) { + return _this.errorCallback(response, _this.opts.parent); + }, + redirect: function (response) { + return _this.successCallback(response, _this.opts.parent); + }, + 307: function (response) { + return _this.successCallback(response, _this.opts.parent); + }, + response: function (response) { + return _this.successCallback(response, _this.opts.parent); + } + } + }; - if(typeof this.host === 'undefined' || this.host === '') { - this.host = location.host; - if (location.port) { - this.host = this.host + ':' + location.port; - } - } + var status = false; - this.definitions = response.definitions; - var key; - for(key in this.definitions) { - var model = new Model(key, this.definitions[key]); - if(model) { - models[key] = model; + if (this.operation.resource && this.operation.resource.api && this.operation.resource.api.clientAuthorizations) { + // Get the client authorizations from the resource declaration + status = this.operation.resource.api.clientAuthorizations.apply(obj, this.operation.authorizations); } - } - - // get paths, create functions for each operationId - var path; - var operations = []; - for(path in response.paths) { - if(typeof response.paths[path] === 'object') { - var httpMethod; - for(httpMethod in response.paths[path]) { - if(['delete', 'get', 'head', 'options', 'patch', 'post', 'put'].indexOf(httpMethod) === -1) { - continue; - } - var operation = response.paths[path][httpMethod]; - var tags = operation.tags; - if(typeof tags === 'undefined') { - operation.tags = [ 'default' ]; - tags = operation.tags; - } - var operationId = this.idFromOp(path, httpMethod, operation); - var operationObject = new Operation ( - this, - operation.scheme, - operationId, - httpMethod, - path, - operation, - this.definitions - ); - // bind this operation's execute command to the api - if(tags.length > 0) { - var i; - for(i = 0; i < tags.length; i++) { - var tag = this.tagFromLabel(tags[i]); - var operationGroup = this[tag]; - if(typeof this.apis[tag] === 'undefined') - this.apis[tag] = {}; - if(typeof operationGroup === 'undefined') { - this[tag] = []; - operationGroup = this[tag]; - operationGroup.operations = {}; - operationGroup.label = tag; - operationGroup.apis = []; - var tagObject = definedTags[tag]; - if(typeof tagObject === 'object') { - operationGroup.description = tagObject.description; - operationGroup.externalDocs = tagObject.externalDocs; - } - this[tag].help = this.help.bind(operationGroup); - this.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject)); - } - if(typeof this.apis[tag].help !== 'function') - this.apis[tag].help = this.help.bind(operationGroup); - // bind to the apis object - this.apis[tag][operationId] = operationObject.execute.bind(operationObject); - this.apis[tag][operationId].help = operationObject.help.bind(operationObject); - this.apis[tag][operationId].asCurl = operationObject.asCurl.bind(operationObject); - operationGroup[operationId] = operationObject.execute.bind(operationObject); - operationGroup[operationId].help = operationObject.help.bind(operationObject); - operationGroup[operationId].asCurl = operationObject.asCurl.bind(operationObject); - - operationGroup.apis.push(operationObject); - operationGroup.operations[operationId] = operationObject; - // legacy UI feature - var j; - var api; - for(j = 0; j < this.apisArray.length; j++) { - if(this.apisArray[j].tag === tag) { - api = this.apisArray[j]; - } - } - if(api) { - api.operationsArray.push(operationObject); - } - } - } - else { - log('no group to bind to'); - } + if (!opts.mock) { + if (status !== false) { + new SwaggerHttp().execute(obj); + } else { + obj.canceled = true; } + } else { + return obj; } } - this.isBuilt = true; - if (this.success) { - this.isValid = true; - this.isBuilt = true; - this.success(); - } - return this; -}; - -SwaggerClient.prototype.parseUri = function(uri) { - var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/; - var parts = urlParseRE.exec(uri); - return { - scheme: parts[4].replace(':',''), - host: parts[11], - port: parts[12], - path: parts[15] - }; -}; -SwaggerClient.prototype.help = function(dontPrint) { - var i; - var output = 'operations for the "' + this.label + '" tag'; - for(i = 0; i < this.apis.length; i++) { - var api = this.apis[i]; - output += '\n * ' + api.nickname + ': ' + api.operation.summary; - } - if(dontPrint) - return output; - else { - log(output); - return output; - } + return obj; }; -SwaggerClient.prototype.tagFromLabel = function(label) { - return label; -}; +var SwaggerResource = function (resourceObj, api) { + var self = this; -SwaggerClient.prototype.idFromOp = function(path, httpMethod, op) { - var opId = op.operationId || (path.substring(1) + '_' + httpMethod); - return opId.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()\+\s]/g,'_'); -}; + this.api = api; + this.swaggerRequstHeaders = api.swaggerRequstHeaders; + this.path = (typeof this.api.resourcePath === 'string') ? this.api.resourcePath : resourceObj.path; + this.description = resourceObj.description; + this.authorizations = (resourceObj.authorizations || {}); -SwaggerClient.prototype.fail = function(message) { - this.failure(message); - throw message; -}; + var parts = this.path.split('/'); -var OperationGroup = function(tag, description, externalDocs, operation) { - this.tag = tag; - this.path = tag; - this.description = description; - this.externalDocs = externalDocs; - this.name = tag; - this.operation = operation; + this.name = parts[parts.length - 1].replace('.{format}', ''); + this.basePath = this.api.basePath; + this.operations = {}; this.operationsArray = []; -}; - -var Operation = function(parent, scheme, operationId, httpMethod, path, args, definitions) { - var errors = []; - parent = parent||{}; - args = args||{}; + this.modelsArray = []; + this.models = api.models || {}; + this.rawModels = {}; + this.useJQuery = (typeof api.useJQuery !== 'undefined') ? api.useJQuery : null; - this.operations = {}; - this.operation = args; - this.deprecated = args.deprecated; - this.consumes = args.consumes; - this.produces = args.produces; - this.parent = parent; - this.host = parent.host || 'localhost'; - this.schemes = parent.schemes; - this.scheme = scheme || parent.scheme || 'http'; - this.basePath = parent.basePath || '/'; - this.nickname = (operationId||errors.push('Operations must have a nickname.')); - this.method = (httpMethod||errors.push('Operation ' + operationId + ' is missing method.')); - this.path = (path||errors.push('Operation ' + this.nickname + ' is missing path.')); - this.parameters = args !== null ? (args.parameters||[]) : {}; - this.summary = args.summary || ''; - this.responses = (args.responses||{}); - this.type = null; - this.security = args.security; - this.authorizations = args.security; - this.description = args.description; - this.useJQuery = parent.useJQuery; + if ((resourceObj.apis) && this.api.resourcePath) { + this.addApiDeclaration(resourceObj); + } else { + if (typeof this.path === 'undefined') { + this.api.fail('SwaggerResources must have a path.'); + } - if(typeof this.deprecated === 'string') { - switch(this.deprecated.toLowerCase()) { - case 'true': case 'yes': case '1': { - this.deprecated = true; - break; - } - case 'false': case 'no': case '0': case null: { - this.deprecated = false; - break; - } - default: this.deprecated = Boolean(this.deprecated); + if (this.path.substring(0, 4) === 'http') { + this.url = this.path.replace('{format}', 'json'); + } else { + this.url = this.api.basePath + this.path.replace('{format}', 'json'); } - } - var i, model; + this.api.progress('fetching resource ' + this.name + ': ' + this.url); - if(definitions) { - // add to global models - var key; - for(key in this.definitions) { - model = new Model(key, definitions[key]); - if(model) { - models[key] = model; + var obj = { + url: this.url, + method: 'GET', + useJQuery: this.useJQuery, + headers: { + accept: this.swaggerRequstHeaders + }, + on: { + response: function (resp) { + var responseObj = resp.obj || JSON.parse(resp.data); + self.api.resourceCount += 1; + return self.addApiDeclaration(responseObj); + }, + error: function (response) { + self.api.resourceCount += 1; + return self.api.fail('Unable to read api \'' + + self.name + '\' from path ' + self.url + ' (server returned ' + response.statusText + ')'); + } } - } - } - for(i = 0; i < this.parameters.length; i++) { - var param = this.parameters[i]; - if(param.type === 'array') { - param.isList = true; - param.allowMultiple = true; - } - var innerType = this.getType(param); - if(innerType && innerType.toString().toLowerCase() === 'boolean') { - param.allowableValues = {}; - param.isList = true; - param['enum'] = ["true", "false"]; - } - if(typeof param['enum'] !== 'undefined') { - var id; - param.allowableValues = {}; - param.allowableValues.values = []; - param.allowableValues.descriptiveValues = []; - for(id = 0; id < param['enum'].length; id++) { - var value = param['enum'][id]; - var isDefault = (value === param.default) ? true : false; - param.allowableValues.values.push(value); - param.allowableValues.descriptiveValues.push({value : value, isDefault: isDefault}); - } - } - if(param.type === 'array') { - innerType = [innerType]; - if(typeof param.allowableValues === 'undefined') { - // can't show as a list if no values to select from - delete param.isList; - delete param.allowMultiple; - } - } - param.signature = this.getModelSignature(innerType, models).toString(); - param.sampleJSON = this.getModelSampleJSON(innerType, models); - param.responseClassSignature = param.signature; - } + }; - var defaultResponseCode, response, responses = this.responses; + api.clientAuthorizations.apply(obj); - if(responses['200']) { - response = responses['200']; - defaultResponseCode = '200'; - } - else if(responses['201']) { - response = responses['201']; - defaultResponseCode = '201'; - } - else if(responses['202']) { - response = responses['202']; - defaultResponseCode = '202'; - } - else if(responses['203']) { - response = responses['203']; - defaultResponseCode = '203'; - } - else if(responses['204']) { - response = responses['204']; - defaultResponseCode = '204'; - } - else if(responses['205']) { - response = responses['205']; - defaultResponseCode = '205'; - } - else if(responses['206']) { - response = responses['206']; - defaultResponseCode = '206'; + new SwaggerHttp().execute(obj); } - else if(responses['default']) { - response = responses['default']; - defaultResponseCode = 'default'; +}; + +SwaggerClient.prototype.buildFrom1_2Spec = function (response) { // jshint ignore:line + if (response.apiVersion !== null) { + this.apiVersion = response.apiVersion; } - if(response && response.schema) { - var resolvedModel = this.resolveModel(response.schema, definitions); - delete responses[defaultResponseCode]; - if(resolvedModel) { - this.successResponse = {}; - this.successResponse[defaultResponseCode] = resolvedModel; - } - else { - this.successResponse = {}; - this.successResponse[defaultResponseCode] = response.schema.type; + this.apis = {}; + this.apisArray = []; + this.authSchemes = response.authorizations; + this.consumes = response.consumes; + this.info = this.convertInfo(response.info); + this.produces = response.produces; + + var isApi = false, i, res; + + for (i = 0; i < response.apis.length; i++) { + var api = response.apis[i]; + + if (api.operations) { + var j; + + for (j = 0; j < api.operations.length; j++) { + isApi = true; + } } - this.type = response; } - if (errors.length > 0) { - if(this.resource && this.resource.api && this.resource.api.fail) - this.resource.api.fail(errors); + if (response.basePath) { + this.basePath = response.basePath; + } else if (this.url.indexOf('?') > 0) { + this.basePath = this.url.substring(0, this.url.lastIndexOf('?')); + } else { + this.basePath = this.url; } - return this; -}; + if (isApi) { + var newName = response.resourcePath.replace(/\//g, ''); -OperationGroup.prototype.sort = function(sorter) { + this.resourcePath = response.resourcePath; -}; + res = new SwaggerResource(response, this); -Operation.prototype.getType = function (param) { - var type = param.type; - var format = param.format; - var isArray = false; - var str; - if(type === 'integer' && format === 'int32') - str = 'integer'; - else if(type === 'integer' && format === 'int64') - str = 'long'; - else if(type === 'integer') - str = 'integer'; - else if(type === 'string') { - if(format === 'date-time') - str = 'date-time'; - else if(format === 'date') - str = 'date'; - else - str = 'string'; - } - else if(type === 'number' && format === 'float') - str = 'float'; - else if(type === 'number' && format === 'double') - str = 'double'; - else if(type === 'number') - str = 'double'; - else if(type === 'boolean') - str = 'boolean'; - else if(type === 'array') { - isArray = true; - if(param.items) - str = this.getType(param.items); - } - if(param.$ref) - str = param.$ref; + this.apis[newName] = res; + this.apisArray.push(res); + this.finish(); + } else { + var k; - var schema = param.schema; - if(schema) { - var ref = schema.$ref; - if(ref) { - ref = simpleRef(ref); - if(isArray) - return [ ref ]; - else - return ref; - } - else - return this.getType(schema); - } - if(isArray) - return [ str ]; - else - return str; -}; + this.expectedResourceCount = response.apis.length; -Operation.prototype.resolveModel = function (schema, definitions) { - if(typeof schema.$ref !== 'undefined') { - var ref = schema.$ref; - if(ref.indexOf('#/definitions/') === 0) - ref = ref.substring('#/definitions/'.length); - if(definitions[ref]) { - return new Model(ref, definitions[ref]); + for (k = 0; k < response.apis.length; k++) { + var resource = response.apis[k]; + + res = new SwaggerResource(resource, this); + + this.apis[res.name] = res; + this.apisArray.push(res); } } - if(schema.type === 'array') - return new ArrayModel(schema); - else - return null; + + this.isValid = true; + + return this; }; -Operation.prototype.help = function(dontPrint) { - var out = this.nickname + ': ' + this.summary + '\n'; - for(var i = 0; i < this.parameters.length; i++) { - var param = this.parameters[i]; - var typeInfo = param.signature; - out += '\n * ' + param.name + ' (' + typeInfo + '): ' + param.description; +SwaggerClient.prototype.finish = function () { + if (typeof this.success === 'function') { + this.isValid = true; + this.ready = true; + this.isBuilt = true; + this.selfReflect(); + this.success(); } - if(typeof dontPrint === 'undefined') - log(out); - return out; }; -Operation.prototype.getModelSignature = function(type, definitions) { - var isPrimitive, listType; +SwaggerClient.prototype.buildFrom1_1Spec = function (response) { // jshint ignore:line + helpers.log('This API is using a deprecated version of Swagger! Please see http://github.com/wordnik/swagger-core/wiki for more info'); - if(type instanceof Array) { - listType = true; - type = type[0]; + if (response.apiVersion !== null) { + this.apiVersion = response.apiVersion; } - else if(typeof type === 'undefined') - type = 'undefined'; - if(type === 'string') - isPrimitive = true; - else - isPrimitive = (listType && definitions[listType]) || (definitions[type]) ? false : true; - if (isPrimitive) { - if(listType) - return 'Array[' + type + ']'; - else - return type.toString(); - } else { - if (listType) - return 'Array[' + definitions[type].getMockSignature() + ']'; - else - return definitions[type].getMockSignature(); - } -}; + this.apis = {}; + this.apisArray = []; + this.produces = response.produces; + this.info = this.convertInfo(response.info); -Operation.prototype.supportHeaderParams = function () { - return true; -}; + var isApi = false, res; -Operation.prototype.supportedSubmitMethods = function () { - return this.parent.supportedSubmitMethods; -}; + for (var i = 0; i < response.apis.length; i++) { + var api = response.apis[i]; -Operation.prototype.getHeaderParams = function (args) { - var headers = this.setContentTypes(args, {}); - for(var i = 0; i < this.parameters.length; i++) { - var param = this.parameters[i]; - if(typeof args[param.name] !== 'undefined') { - if (param.in === 'header') { - var value = args[param.name]; - if(Array.isArray(value)) - value = value.toString(); - headers[param.name] = value; + if (api.operations) { + for (var j = 0; j < api.operations.length; j++) { + isApi = true; + break; } } } - return headers; -}; - -Operation.prototype.urlify = function (args) { - var formParams = {}; - var requestUrl = this.path; - // grab params from the args, build the querystring along the way - var querystring = ''; - for(var i = 0; i < this.parameters.length; i++) { - var param = this.parameters[i]; - if(typeof args[param.name] !== 'undefined') { - if(param.in === 'path') { - var reg = new RegExp('\{' + param.name + '\}', 'gi'); - var value = args[param.name]; - if(Array.isArray(value)) - value = this.encodePathCollection(param.collectionFormat, param.name, value); - else - value = this.encodePathParam(value); - requestUrl = requestUrl.replace(reg, value); - } - else if (param.in === 'query' && typeof args[param.name] !== 'undefined') { - if(querystring === '') - querystring += '?'; - else - querystring += '&'; - if(typeof param.collectionFormat !== 'undefined') { - var qp = args[param.name]; - if(Array.isArray(qp)) - querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp); - else - querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]); - } - else - querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]); - } - else if (param.in === 'formData') - formParams[param.name] = args[param.name]; - } + if (response.basePath) { + this.basePath = response.basePath; + } else if (this.url.indexOf('?') > 0) { + this.basePath = this.url.substring(0, this.url.lastIndexOf('?')); + } else { + this.basePath = this.url; } - var url = this.scheme + '://' + this.host; - if(this.basePath !== '/') - url += this.basePath; + if (isApi) { + var newName = response.resourcePath.replace(/\//g, ''); - return url + requestUrl + querystring; -}; + this.resourcePath = response.resourcePath; + res = new SwaggerResource(response, this); + this.apis[newName] = res; + this.apisArray.push(res); + this.finish(); + } else { + this.expectedResourceCount = response.apis.length; -Operation.prototype.getMissingParams = function(args) { - var missingParams = []; - // check required params, track the ones that are missing - var i; - for(i = 0; i < this.parameters.length; i++) { - var param = this.parameters[i]; - if(param.required === true) { - if(typeof args[param.name] === 'undefined') - missingParams = param.name; + for (var k = 0; k < response.apis.length; k++) { + res = new SwaggerResource(response.apis[k], this); + this.apis[res.name] = res; + this.apisArray.push(res); } } - return missingParams; + + this.isValid = true; + + return this; }; -Operation.prototype.getBody = function(headers, args, opts) { - var formParams = {}, body, key; +SwaggerClient.prototype.convertInfo = function (resp) { + if (typeof resp === 'object') { + var info = {}; - for(var i = 0; i < this.parameters.length; i++) { - var param = this.parameters[i]; - if(typeof args[param.name] !== 'undefined') { - if (param.in === 'body') { - body = args[param.name]; - } else if(param.in === 'formData') { - formParams[param.name] = args[param.name]; - } - } + info.title = resp.title; + info.description = resp.description; + info.termsOfService = resp.termsOfServiceUrl; + info.contact = {}; + info.contact.name = resp.contact; + info.license = {}; + info.license.name = resp.license; + info.license.url = resp.licenseUrl; + + return info; } +}; - // handle form params - if(headers['Content-Type'] === 'application/x-www-form-urlencoded') { - var encoded = ""; - for(key in formParams) { - value = formParams[key]; - if(typeof value !== 'undefined'){ - if(encoded !== "") - encoded += "&"; - encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value); - } - } - body = encoded; +SwaggerClient.prototype.selfReflect = function () { + var tag, ref; + + if (this.apis === null) { + return false; } - else if (headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) { - if(opts.useJQuery) { - var bodyParam = new FormData(); - bodyParam.type = 'formData'; - for (key in formParams) { - value = args[key]; - if (typeof value !== 'undefined') { - // required for jquery file upload - if(value.type === 'file' && value.value) { - delete headers['Content-Type']; - bodyParam.append(key, value.value); - } - else - bodyParam.append(key, value); - } - } - body = bodyParam; + + ref = this.apis; + + for (tag in ref) { + var api = ref[tag]; + + if (api.ready === null) { + return false; } + + this[tag] = api; + this[tag].help = helpers.__bind(api.help, api); } - return body; + this.setConsolidatedModels(); + this.ready = true; }; -/** - * gets sample response for a single operation - **/ -Operation.prototype.getModelSampleJSON = function(type, models) { - var isPrimitive, listType, sampleJson; +SwaggerClient.prototype.setConsolidatedModels = function () { + var model, modelName, resource, resourceName, i, apis, models, results; - listType = (type instanceof Array); - isPrimitive = models[type] ? false : true; - sampleJson = isPrimitive ? void 0 : models[type].createJSONSample(); - if (sampleJson) { - sampleJson = listType ? [sampleJson] : sampleJson; - if(typeof sampleJson == 'string') - return sampleJson; - else if(typeof sampleJson === 'object') { - var t = sampleJson; - if(sampleJson instanceof Array && sampleJson.length > 0) { - t = sampleJson[0]; - } - if(t.nodeName) { - var xmlString = new XMLSerializer().serializeToString(t); - return this.formatXml(xmlString); + this.models = {}; + apis = this.apis; + + for (resourceName in apis) { + resource = apis[resourceName]; + + for (modelName in resource.models) { + if (typeof this.models[modelName] === 'undefined') { + this.models[modelName] = resource.models[modelName]; + this.modelsArray.push(resource.models[modelName]); } - else - return JSON.stringify(sampleJson, null, 2); } - else - return sampleJson; } -}; -/** - * legacy binding - **/ -Operation.prototype["do"] = function(args, opts, callback, error, parent) { - return this.execute(args, opts, callback, error, parent); -}; + models = this.modelsArray; + results = []; + for (i = 0; i < models.length; i++) { + model = models[i]; -/** - * executes an operation - **/ -Operation.prototype.execute = function(arg1, arg2, arg3, arg4, parent) { - var args = arg1 || {}; - var opts = {}, success, error; - if(typeof arg2 === 'object') { - opts = arg2; - success = arg3; - error = arg4; + results.push(model.setReferencedModels(this.models)); } - if(typeof arg2 === 'function') { - success = arg2; - error = arg3; - } + return results; +}; - success = (success||log); - error = (error||log); +SwaggerResource.prototype.help = function (dontPrint) { + var output = 'operations for the "' + this.name + '" tag'; + var i; - if(opts.useJQuery) - this.useJQuery = opts.useJQuery; + for (i = 0; i < this.operationsArray.length; i++) { + var api = this.operationsArray[i]; - var missingParams = this.getMissingParams(args); - if(missingParams.length > 0) { - var message = 'missing required params: ' + missingParams; - fail(message); - return; + output += '\n * ' + api.nickname + ': ' + api.description; } - var allHeaders = this.getHeaderParams(args); - var contentTypeHeaders = this.setContentTypes(args, opts); - - var headers = {}, attrname; - for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; } - for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; } - var body = this.getBody(headers, args, opts); - var url = this.urlify(args); + if (dontPrint) { + return output; + } else { + helpers.log(output); - var obj = { - url: url, - method: this.method.toUpperCase(), - body: body, - useJQuery: this.useJQuery, - headers: headers, - on: { - response: function(response) { - return success(response, parent); - }, - error: function(response) { - return error(response, parent); - } - } - }; - var status = authorizations.apply(obj, this.operation.security); - if(opts.mock === true) - return obj; - else - new SwaggerHttp().execute(obj, opts); + return output; + } }; -Operation.prototype.setContentTypes = function(args, opts) { - // default type - var accepts = 'application/json'; - var consumes = args.parameterContentType || 'application/json'; - var allDefinedParams = this.parameters; - var definedFormParams = []; - var definedFileParams = []; - var body; - var headers = {}; +SwaggerResource.prototype.getAbsoluteBasePath = function (relativeBasePath) { + var url = this.api.basePath; + var pos = url.lastIndexOf(relativeBasePath); + var parts = url.split('/'); + var rootUrl = parts[0] + '//' + parts[2]; - // get params from the operation and set them in definedFileParams, definedFormParams, headers - var i; - for(i = 0; i < allDefinedParams.length; i++) { - var param = allDefinedParams[i]; - if(param.in === 'formData') { - if(param.type === 'file') - definedFileParams.push(param); - else - definedFormParams.push(param); - } - else if(param.in === 'header' && opts) { - var key = param.name; - var headerValue = opts[param.name]; - if(typeof opts[param.name] !== 'undefined') - headers[key] = headerValue; - } - else if(param.in === 'body' && typeof args[param.name] !== 'undefined') { - body = args[param.name]; - } + if (relativeBasePath.indexOf('http') === 0) { + return relativeBasePath; } - // if there's a body, need to set the consumes header via requestContentType - if (body && (this.method === 'post' || this.method === 'put' || this.method === 'patch' || this.method === 'delete')) { - if (opts.requestContentType) - consumes = opts.requestContentType; + if (relativeBasePath === '/') { + return rootUrl; + } + + if (relativeBasePath.substring(0, 1) === '/') { + // use root + relative + return rootUrl + relativeBasePath; } else { - // if any form params, content type must be set - if(definedFormParams.length > 0) { - if(opts.requestContentType) // override if set - consumes = opts.requestContentType; - else if(definedFileParams.length > 0) // if a file, must be multipart/form-data - consumes = 'multipart/form-data'; - else // default to x-www-from-urlencoded - consumes = 'application/x-www-form-urlencoded'; + pos = this.basePath.lastIndexOf('/'); + + var base = this.basePath.substring(0, pos); + + if (base.substring(base.length - 1) === '/') { + return base + relativeBasePath; + } else { + return base + '/' + relativeBasePath; } - else if (this.type == 'DELETE') - body = '{}'; - else if (this.type != 'DELETE') - consumes = null; } +}; - if (consumes && this.consumes) { - if (this.consumes.indexOf(consumes) === -1) { - log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes)); - } +SwaggerResource.prototype.addApiDeclaration = function (response) { + if (typeof response.produces === 'string') { + this.produces = response.produces; } - if (opts.responseContentType) { - accepts = opts.responseContentType; - } else { - accepts = 'application/json'; + if (typeof response.consumes === 'string') { + this.consumes = response.consumes; } - if (accepts && this.produces) { - if (this.produces.indexOf(accepts) === -1) { - log('server can\'t produce ' + accepts); - } + + if ((typeof response.basePath === 'string') && response.basePath.replace(/\s/g, '').length > 0) { + this.basePath = response.basePath.indexOf('http') !== 0 ? this.getAbsoluteBasePath(response.basePath) : response.basePath; } - if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) - headers['Content-Type'] = consumes; - if (accepts) - headers.Accept = accepts; - return headers; -}; + this.resourcePath = response.resourcePath; + this.addModels(response.models); -Operation.prototype.asCurl = function (args) { - var obj = this.execute(args, {mock: true}); - authorizations.apply(obj); - var results = []; - results.push('-X ' + this.method.toUpperCase()); - if (obj.headers) { - var key; - for (key in obj.headers) - results.push('--header "' + key + ': ' + obj.headers[key] + '"'); - } - if(obj.body) { - var body; - if(typeof obj.body === 'object') - body = JSON.stringify(obj.body); - else - body = obj.body; - results.push('-d "' + body.replace(/"/g, '\\"') + '"'); + if (response.apis) { + for (var i = 0 ; i < response.apis.length; i++) { + var endpoint = response.apis[i]; + + this.addOperations(endpoint.path, endpoint.operations, response.consumes, response.produces); + } } - return 'curl ' + (results.join(' ')) + ' "' + obj.url + '"'; -}; -Operation.prototype.encodePathCollection = function(type, name, value) { - var encoded = ''; - var i; - var separator = ''; - if(type === 'ssv') - separator = '%20'; - else if(type === 'tsv') - separator = '\\t'; - else if(type === 'pipes') - separator = '|'; - else - separator = ','; + this.api[this.name] = this; + this.ready = true; - for(i = 0; i < value.length; i++) { - if(i === 0) - encoded = this.encodeQueryParam(value[i]); - else - encoded += separator + this.encodeQueryParam(value[i]); + if (this.api.resourceCount === this.api.expectedResourceCount) { + this.api.finish(); } - return encoded; + + return this; }; -Operation.prototype.encodeQueryCollection = function(type, name, value) { - var encoded = ''; - var i; - if(type === 'default' || type === 'multi') { - for(i = 0; i < value.length; i++) { - if(i > 0) encoded += '&'; - encoded += this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]); +SwaggerResource.prototype.addModels = function (models) { + if (typeof models === 'object') { + var modelName; + + for (modelName in models) { + if (typeof this.models[modelName] === 'undefined') { + var swaggerModel = new SwaggerModel(modelName, models[modelName], this.api); + + this.modelsArray.push(swaggerModel); + this.models[modelName] = swaggerModel; + this.rawModels[modelName] = models[modelName]; + } } - } - else { - var separator = ''; - if(type === 'csv') - separator = ','; - else if(type === 'ssv') - separator = '%20'; - else if(type === 'tsv') - separator = '\\t'; - else if(type === 'pipes') - separator = '|'; - else if(type === 'brackets') { - for(i = 0; i < value.length; i++) { - if(i !== 0) - encoded += '&'; - encoded += this.encodeQueryParam(name) + '[]=' + this.encodeQueryParam(value[i]); - } - } - if(separator !== '') { - for(i = 0; i < value.length; i++) { - if(i === 0) - encoded = this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]); - else - encoded += separator + this.encodeQueryParam(value[i]); - } - } - } - return encoded; -}; -Operation.prototype.encodeQueryParam = function(arg) { - return encodeURIComponent(arg); -}; + var output = []; -/** - * TODO revisit, might not want to leave '/' - **/ -Operation.prototype.encodePathParam = function(pathParam) { - var encParts, part, parts, i, len; - pathParam = pathParam.toString(); - if (pathParam.indexOf('/') === -1) { - return encodeURIComponent(pathParam); - } else { - parts = pathParam.split('/'); - encParts = []; - for (i = 0, len = parts.length; i < len; i++) { - encParts.push(encodeURIComponent(parts[i])); + for (var i = 0; i < this.modelsArray.length; i++) { + var model = this.modelsArray[i]; + + output.push(model.setReferencedModels(this.models)); } - return encParts.join('/'); + + return output; } }; -var Model = function(name, definition) { - this.name = name; - this.definition = definition || {}; - this.properties = []; - var requiredFields = definition.required || []; - if(definition.type === 'array') { - var out = new ArrayModel(definition); - return out; - } - var key; - var props = definition.properties; - if(props) { - for(key in props) { - var required = false; - var property = props[key]; - if(requiredFields.indexOf(key) >= 0) - required = true; - this.properties.push(new Property(key, property, required)); +SwaggerResource.prototype.addOperations = function (resourcePath, ops, consumes, produces) { + if (ops) { + var output = []; + + for (var i = 0; i < ops.length; i++) { + var o = ops[i]; + + consumes = this.consumes; + produces = this.produces; + + if (typeof o.consumes !== 'undefined') { + consumes = o.consumes; + } else { + consumes = this.consumes; + } + + if (typeof o.produces !== 'undefined') { + produces = o.produces; + } else { + produces = this.produces; + } + + var type = (o.type || o.responseClass); + + if (type === 'array') { + var ref = null; + + if (o.items) { + ref = o.items.type || o.items.$ref; + } + + type = 'array[' + ref + ']'; + } + + var responseMessages = o.responseMessages; + var method = o.method; + + if (o.httpMethod) { + method = o.httpMethod; + } + + if (o.supportedContentTypes) { + consumes = o.supportedContentTypes; + } + + if (o.errorResponses) { + responseMessages = o.errorResponses; + + for (var j = 0; j < responseMessages.length; j++) { + var r = responseMessages[j]; + + r.message = r.reason; + r.reason = null; + } + } + + o.nickname = this.sanitize(o.nickname); + + var op = new SwaggerOperation(o.nickname, + resourcePath, + method, + o.parameters, + o.summary, + o.notes, + type, + responseMessages, + this, + consumes, + produces, + o.authorizations, + o.deprecated, this.clientAuthorizations); + + this.operations[op.nickname] = op; + output.push(this.operationsArray.push(op)); } + + return output; } }; -Model.prototype.createJSONSample = function(modelsToIgnore) { - var i, result = {}, representations = {}; - modelsToIgnore = (modelsToIgnore||{}); - modelsToIgnore[this.name] = this; - for (i = 0; i < this.properties.length; i++) { - prop = this.properties[i]; - var sample = prop.getSampleValue(modelsToIgnore, representations); - result[prop.name] = sample; - } - delete modelsToIgnore[this.name]; - return result; +SwaggerResource.prototype.sanitize = function (nickname) { + var op = nickname.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_'); + + op = op.replace(/((_){2,})/g, '_'); + op = op.replace(/^(_)*/g, ''); + op = op.replace(/([_])*$/g, ''); + + return op; }; -Model.prototype.getSampleValue = function(modelsToIgnore) { - var i, obj = {}, representations = {}; - for(i = 0; i < this.properties.length; i++ ) { +SwaggerModel.prototype.setReferencedModels = function (allModels) { + var results = []; + + for (var i = 0; i < this.properties.length; i++) { var property = this.properties[i]; - obj[property.name] = property.sampleValue(false, modelsToIgnore, representations); + var type = property.type || property.dataType; + + if (allModels[type]) { + results.push(property.refModel = allModels[type]); + } else if ((property.refDataType) && (allModels[property.refDataType])) { + results.push(property.refModel = allModels[property.refDataType]); + } else { + results.push(void 0); + } } - return obj; + + return results; }; -Model.prototype.getMockSignature = function(modelsToIgnore) { +SwaggerModel.prototype.getMockSignature = function (modelsToIgnore) { var i, prop, propertiesStr = []; + for (i = 0; i < this.properties.length; i++) { prop = this.properties[i]; + propertiesStr.push(prop.toString()); } + var strong = ''; - var stronger = ''; var strongClose = ''; var classOpen = strong + this.name + ' {' + strongClose; var classClose = strong + '}' + strongClose; var returnVal = classOpen + '
' + propertiesStr.join(',
') + '
' + classClose; - if (!modelsToIgnore) - modelsToIgnore = {}; - modelsToIgnore[this.name] = this; + if (!modelsToIgnore) { + modelsToIgnore = []; + } + + modelsToIgnore.push(this.name); + for (i = 0; i < this.properties.length; i++) { prop = this.properties[i]; - var ref = prop.$ref; - var model = models[ref]; - if (model && typeof modelsToIgnore[model.name] === 'undefined') { - returnVal = returnVal + ('
' + model.getMockSignature(modelsToIgnore)); - } - } - return returnVal; -}; -var Property = function(name, obj, required) { - this.schema = obj; - this.required = required; - if(obj.$ref) - this.$ref = simpleRef(obj.$ref); - else if (obj.type === 'array' && obj.items) { - if(obj.items.$ref) - this.$ref = simpleRef(obj.items.$ref); - else - obj = obj.items; + if ((prop.refModel) && modelsToIgnore.indexOf(prop.refModel.name) === -1) { + returnVal = returnVal + ('
' + prop.refModel.getMockSignature(modelsToIgnore)); + } } - this.name = name; - this.description = obj.description; - this.obj = obj; - this.optional = true; - this.optional = !required; - this.default = obj.default || null; - this.example = obj.example !== undefined ? obj.example : null; - this.collectionFormat = obj.collectionFormat || null; - this.maximum = obj.maximum || null; - this.exclusiveMaximum = obj.exclusiveMaximum || null; - this.minimum = obj.minimum || null; - this.exclusiveMinimum = obj.exclusiveMinimum || null; - this.maxLength = obj.maxLength || null; - this.minLength = obj.minLength || null; - this.pattern = obj.pattern || null; - this.maxItems = obj.maxItems || null; - this.minItems = obj.minItems || null; - this.uniqueItems = obj.uniqueItems || null; - this['enum'] = obj['enum'] || null; - this.multipleOf = obj.multipleOf || null; -}; -Property.prototype.getSampleValue = function (modelsToIgnore, representations) { - return this.sampleValue(false, modelsToIgnore, representations); + return returnVal; }; -Property.prototype.isArray = function () { - var schema = this.schema; - if(schema.type === 'array') - return true; - else - return false; -}; +SwaggerModel.prototype.createJSONSample = function (modelsToIgnore) { + if (this.sampleModels[this.name]) { + return this.sampleModels[this.name]; + } else { + var result = {}; -Property.prototype.sampleValue = function(isArray, ignoredModels, representations) { - isArray = (isArray || this.isArray()); - ignoredModels = (ignoredModels || {}); - // representations = (representations || {}); + modelsToIgnore = (modelsToIgnore || []); + modelsToIgnore.push(this.name); - var type = getStringSignature(this.obj, true); - var output; + for (var i = 0; i < this.properties.length; i++) { + var prop = this.properties[i]; - if(this.$ref) { - var refModelName = simpleRef(this.$ref); - var refModel = models[refModelName]; - if(typeof representations[type] !== 'undefined') { - return representations[type]; + result[prop.name] = prop.getSampleValue(modelsToIgnore); } - else - if(refModel && typeof ignoredModels[type] === 'undefined') { - ignoredModels[type] = this; - output = refModel.getSampleValue(ignoredModels, representations); - representations[type] = output; - } - else { - output = (representations[type] || refModelName); - } + modelsToIgnore.pop(this.name); + + return result; } - else if(this.example) - output = this.example; - else if(this.default) - output = this.default; - else if(type === 'date-time') - output = new Date().toISOString(); - else if(type === 'date') - output = new Date().toISOString().split("T")[0]; - else if(type === 'string') - output = 'string'; - else if(type === 'integer') - output = 0; - else if(type === 'long') - output = 0; - else if(type === 'float') - output = 0.0; - else if(type === 'double') - output = 0.0; - else if(type === 'boolean') - output = true; - else - output = {}; - ignoredModels[type] = output; - if(isArray) - return [output]; - else - return output; }; -getStringSignature = function(obj, baseComponent) { - var str = ''; - if(typeof obj.$ref !== 'undefined') - str += simpleRef(obj.$ref); - else if(typeof obj.type === 'undefined') - str += 'object'; - else if(obj.type === 'array') { - if(baseComponent) - str += getStringSignature((obj.items || obj.$ref || {})); - else { - str += 'Array['; - str += getStringSignature((obj.items || obj.$ref || {})); - str += ']'; +SwaggerModelProperty.prototype.getSampleValue = function (modelsToIgnore) { + var result; + + if ((this.refModel) && (modelsToIgnore.indexOf(this.refModel.name) === -1)) { + result = this.refModel.createJSONSample(modelsToIgnore); + } else { + if (this.isCollection) { + result = this.toSampleValue(this.refDataType); + } else { + result = this.toSampleValue(this.dataType); } } - else if(obj.type === 'integer' && obj.format === 'int32') - str += 'integer'; - else if(obj.type === 'integer' && obj.format === 'int64') - str += 'long'; - else if(obj.type === 'integer' && typeof obj.format === 'undefined') - str += 'long'; - else if(obj.type === 'string' && obj.format === 'date-time') - str += 'date-time'; - else if(obj.type === 'string' && obj.format === 'date') - str += 'date'; - else if(obj.type === 'string' && typeof obj.format === 'undefined') - str += 'string'; - else if(obj.type === 'number' && obj.format === 'float') - str += 'float'; - else if(obj.type === 'number' && obj.format === 'double') - str += 'double'; - else if(obj.type === 'number' && typeof obj.format === 'undefined') - str += 'double'; - else if(obj.type === 'boolean') - str += 'boolean'; - else if(obj.$ref) - str += simpleRef(obj.$ref); - else - str += obj.type; - return str; + + if (this.isCollection) { + return [result]; + } else { + return result; + } }; -simpleRef = function(name) { - if(typeof name === 'undefined') - return null; - if(name.indexOf("#/definitions/") === 0) - return name.substring('#/definitions/'.length); - else - return name; +SwaggerModelProperty.prototype.toSampleValue = function (value) { + var result; + + if ((typeof this.defaultValue !== 'undefined') && this.defaultValue) { + result = this.defaultValue; + } else if (value === 'integer') { + result = 0; + } else if (value === 'boolean') { + result = false; + } else if (value === 'double' || value === 'number') { + result = 0.0; + } else if (value === 'string') { + result = ''; + } else { + result = value; + } + + return result; }; -Property.prototype.toString = function() { - var str = getStringSignature(this.obj); - if(str !== '') { - str = '' + this.name + ' (' + str + ''; - if(!this.required) - str += ', optional'; - str += ')'; +SwaggerModelProperty.prototype.toString = function () { + var req = this.required ? 'propReq' : 'propOpt'; + var str = '' + this.name + ' (' + this.dataTypeWithRef + ''; + + if (!this.required) { + str += ', optional'; } - else - str = this.name + ' (' + JSON.stringify(this.obj) + ')'; - if(typeof this.description !== 'undefined') - str += ': ' + this.description; + str += ')'; - if (this['enum']) { - str += ' = [\'' + this['enum'].join('\' or \'') + '\']'; + if (this.values) { + str += ' = [\'' + this.values.join('\' or \'') + '\']'; } + if (this.descr) { str += ': ' + this.descr + ''; } + return str; +}; - var options = ''; - var isArray = this.schema.type === 'array'; - var type; - - if(isArray) { - if(this.schema.items) - type = this.schema.items.type; - else - type = ''; - } - else { - type = this.schema.type; +SwaggerOperation.prototype.isListType = function (type) { + if (type && type.indexOf('[') >= 0) { + return type.substring(type.indexOf('[') + 1, type.indexOf(']')); + } else { + return void 0; } +}; - if (this.default) - options += optionHtml('Default', this.default); +SwaggerOperation.prototype.getSignature = function (type, models) { + var listType = this.isListType(type); + var isPrimitive = ((typeof listType !== 'undefined') && models[listType]) || (typeof models[type] !== 'undefined') ? false : true; - switch (type) { - case 'string': - if (this.minLength) - options += optionHtml('Min. Length', this.minLength); - if (this.maxLength) - options += optionHtml('Max. Length', this.maxLength); - if (this.pattern) - options += optionHtml('Reg. Exp.', this.pattern); - break; - case 'integer': - case 'number': - if (this.minimum) - options += optionHtml('Min. Value', this.minimum); - if (this.exclusiveMinimum) - options += optionHtml('Exclusive Min.', "true"); - if (this.maximum) - options += optionHtml('Max. Value', this.maximum); - if (this.exclusiveMaximum) - options += optionHtml('Exclusive Max.', "true"); - if (this.multipleOf) - options += optionHtml('Multiple Of', this.multipleOf); - break; + if (isPrimitive) { + return type; + } else { + if (typeof listType !== 'undefined') { + return models[listType].getMockSignature(); + } else { + return models[type].getMockSignature(); + } } +}; - if (isArray) { - if (this.minItems) - options += optionHtml('Min. Items', this.minItems); - if (this.maxItems) - options += optionHtml('Max. Items', this.maxItems); - if (this.uniqueItems) - options += optionHtml('Unique Items', "true"); - if (this.collectionFormat) - options += optionHtml('Coll. Format', this.collectionFormat); - } +SwaggerOperation.prototype.getSampleJSON = function (type, models) { + var listType = this.isListType(type); + var isPrimitive = ((typeof listType !== 'undefined') && models[listType]) || (typeof models[type] !== 'undefined') ? false : true; + var val = isPrimitive ? void 0 : (listType ? models[listType].createJSONSample() : models[type].createJSONSample()); - if (this['enum']) { - var enumString; + if (val) { + val = listType ? [val] : val; - if (type === 'number' || type === 'integer') - enumString = this['enum'].join(', '); - else { - enumString = '"' + this['enum'].join('", "') + '"'; + if (typeof val === 'string') { + return val; + } else if (typeof val === 'object') { + var t = val; + + if (val instanceof Array && val.length > 0) { + t = val[0]; + } + + if (t.nodeName) { + var xmlString = new XMLSerializer().serializeToString(t); + + return this.formatXml(xmlString); + } else { + return JSON.stringify(val, null, 2); + } + } else { + return val; } + } +}; - options += optionHtml('Enum', enumString); +SwaggerOperation.prototype['do'] = function (args, opts, callback, error) { + var key, param, params, possibleParams = [], req, value; + + if (typeof error !== 'function') { + error = function (xhr, textStatus, error) { + return helpers.log(xhr, textStatus, error); + }; } - if (options.length > 0) - str = '' + str + '' + options + '
' + this.name + '
'; + if (typeof callback !== 'function') { + callback = function (response) { + var content= null; - return str; -}; + if (response !== null) { + content = response.data; + } else { + content = 'no data'; + } -optionHtml = function(label, value) { - return '' + label + ':' + value + ''; -}; + return helpers.log('default callback: ' + content); + }; + } -typeFromJsonSchema = function(type, format) { - var str; - if(type === 'integer' && format === 'int32') - str = 'integer'; - else if(type === 'integer' && format === 'int64') - str = 'long'; - else if(type === 'integer' && typeof format === 'undefined') - str = 'long'; - else if(type === 'string' && format === 'date-time') - str = 'date-time'; - else if(type === 'string' && format === 'date') - str = 'date'; - else if(type === 'number' && format === 'float') - str = 'float'; - else if(type === 'number' && format === 'double') - str = 'double'; - else if(type === 'number' && typeof format === 'undefined') - str = 'double'; - else if(type === 'boolean') - str = 'boolean'; - else if(type === 'string') - str = 'string'; + params = {}; + params.headers = []; - return str; -}; + if (args.headers) { + params.headers = args.headers; -var sampleModels = {}; -var cookies = {}; -var models = {}; + delete args.headers; + } -SwaggerClient.prototype.buildFrom1_2Spec = function (response) { - if (response.apiVersion !== null) { - this.apiVersion = response.apiVersion; + // allow override from the opts + if (opts && opts.responseContentType) { + params.headers['Content-Type'] = opts.responseContentType; } - this.apis = {}; - this.apisArray = []; - this.consumes = response.consumes; - this.produces = response.produces; - this.authSchemes = response.authorizations; - this.info = this.convertInfo(response.info); - var isApi = false, i, res; - for (i = 0; i < response.apis.length; i++) { - var api = response.apis[i]; - if (api.operations) { - var j; - for (j = 0; j < api.operations.length; j++) { - operation = api.operations[j]; - isApi = true; - } - } + if (opts && opts.requestContentType) { + params.headers.Accept = opts.requestContentType; } - if (response.basePath) - this.basePath = response.basePath; - else if (this.url.indexOf('?') > 0) - this.basePath = this.url.substring(0, this.url.lastIndexOf('?')); - else - this.basePath = this.url; - if (isApi) { - var newName = response.resourcePath.replace(/\//g, ''); - this.resourcePath = response.resourcePath; - res = new SwaggerResource(response, this); - this.apis[newName] = res; - this.apisArray.push(res); - this.finish(); - } else { - var k; - this.expectedResourceCount = response.apis.length; - for (k = 0; k < response.apis.length; k++) { - var resource = response.apis[k]; - res = new SwaggerResource(resource, this); - this.apis[res.name] = res; - this.apisArray.push(res); + for (var i = 0; i < this.parameters.length; i++) { + param = this.parameters[i]; + + if (param.paramType === 'header') { + if (typeof args[param.name] !== 'undefined') { + params.headers[param.name] = args[param.name]; + } + } else if (param.paramType === 'form' || param.paramType.toLowerCase() === 'file') { + possibleParams.push(param); + } else if (param.paramType === 'body' && param.name !== 'body' && typeof args[param.name] !== 'undefined') { + if (args.body) { + throw new Error('Saw two body params in an API listing; expecting a max of one.'); + } + + args.body = args[param.name]; } } - this.isValid = true; - return this; -}; -SwaggerClient.prototype.finish = function() { - if (typeof this.success === 'function') { - this.isValid = true; - this.ready = true; - this.isBuilt = true; - this.selfReflect(); - this.success(); + if (typeof args.body !== 'undefined') { + params.body = args.body; + + delete args.body; } -}; -SwaggerClient.prototype.buildFrom1_1Spec = function (response) { - log('This API is using a deprecated version of Swagger! Please see http://github.com/wordnik/swagger-core/wiki for more info'); - if (response.apiVersion !== null) - this.apiVersion = response.apiVersion; - this.apis = {}; - this.apisArray = []; - this.produces = response.produces; - this.info = this.convertInfo(response.info); - var isApi = false, res; - for (var i = 0; i < response.apis.length; i++) { - var api = response.apis[i]; - if (api.operations) { - for (var j = 0; j < api.operations.length; j++) { - operation = api.operations[j]; - isApi = true; + if (possibleParams) { + for (key in possibleParams) { + value = possibleParams[key]; + + if (args[value.name]) { + params[value.name] = args[value.name]; } } } - if (response.basePath) { - this.basePath = response.basePath; - } else if (this.url.indexOf('?') > 0) { - this.basePath = this.url.substring(0, this.url.lastIndexOf('?')); - } else { - this.basePath = this.url; - } - if (isApi) { - var newName = response.resourcePath.replace(/\//g, ''); - this.resourcePath = response.resourcePath; - res = new SwaggerResource(response, this); - this.apis[newName] = res; - this.apisArray.push(res); - this.finish(); + + req = new SwaggerRequest(this.method, this.urlify(args), params, opts, callback, error, this); + + if (opts.mock) { + return req; } else { - this.expectedResourceCount = response.apis.length; - for (k = 0; k < response.apis.length; k++) { - resource = response.apis[k]; - res = new SwaggerResource(resource, this); - this.apis[res.name] = res; - this.apisArray.push(res); - } + return true; } - this.isValid = true; - return this; }; -SwaggerClient.prototype.convertInfo = function (resp) { - if(typeof resp == 'object') { - var info = {}; +SwaggerOperation.prototype.pathJson = function () { + return this.path.replace('{format}', 'json'); +}; - info.title = resp.title; - info.description = resp.description; - info.termsOfService = resp.termsOfServiceUrl; - info.contact = {}; - info.contact.name = resp.contact; - info.license = {}; - info.license.name = resp.license; - info.license.url = resp.licenseUrl; +SwaggerOperation.prototype.pathXml = function () { + return this.path.replace('{format}', 'xml'); +}; - return info; +SwaggerOperation.prototype.encodePathParam = function (pathParam) { + var encParts, part, parts, _i, _len; + + pathParam = pathParam.toString(); + + if (pathParam.indexOf('/') === -1) { + return encodeURIComponent(pathParam); + } else { + parts = pathParam.split('/'); + encParts = []; + + for (_i = 0, _len = parts.length; _i < _len; _i++) { + part = parts[_i]; + + encParts.push(encodeURIComponent(part)); + } + + return encParts.join('/'); } }; -SwaggerClient.prototype.selfReflect = function () { - var resource, tag, ref; - if (this.apis === null) { - return false; +SwaggerOperation.prototype.urlify = function (args) { + var i, j, param, url; + + // ensure no double slashing... + if (this.resource.basePath.length > 1 && this.resource.basePath.slice(-1) === '/' && this.pathJson().charAt(0) === '/') { + url = this.resource.basePath + this.pathJson().substring(1); + } else { + url = this.resource.basePath + this.pathJson(); } - ref = this.apis; - for (tag in ref) { - api = ref[tag]; - if (api.ready === null) { - return false; + + var params = this.parameters; + + for (i = 0; i < params.length; i++) { + param = params[i]; + + if (param.paramType === 'path') { + if (typeof args[param.name] !== 'undefined') { + // apply path params and remove from args + var reg = new RegExp('\\{\\s*?' + param.name + '[^\\{\\}\\/]*(?:\\{.*?\\}[^\\{\\}\\/]*)*\\}(?=(\\/?|$))', 'gi'); + + url = url.replace(reg, this.encodePathParam(args[param.name])); + + delete args[param.name]; + } else { + throw '' + param.name + ' is a required path param.'; + } } - this[tag] = api; - this[tag].help = __bind(api.help, api); } - this.setConsolidatedModels(); - this.ready = true; -}; -SwaggerClient.prototype.setConsolidatedModels = function () { - var model, modelName, resource, resource_name, i, apis, models, results; - this.models = {}; - apis = this.apis; - for (resource_name in apis) { - resource = apis[resource_name]; - for (modelName in resource.models) { - if (typeof this.models[modelName] === 'undefined') { - this.models[modelName] = resource.models[modelName]; - this.modelsArray.push(resource.models[modelName]); + var queryParams = ''; + + for (i = 0; i < params.length; i++) { + param = params[i]; + + if (param.paramType === 'query') { + var addition = ''; + + if (Array.isArray(param)) { + var output = ''; + + for (j = 0; j < param.length; j++) { + if (j > 0) { + output += ','; + } + + output += encodeURIComponent(param[j]); + } + + addition += encodeURIComponent(param.name) + '=' + output; + } else { + if (args[param.name]) { + addition += encodeURIComponent(param.name) + '=' + encodeURIComponent(args[param.name]); + } else { + if (param.required) { + throw '' + param.name + ' is a required query param.'; + } + } + } + + if (addition !== '' && queryParams.length > 0) { + queryParams += '&'; } + + queryParams += addition; } } - models = this.modelsArray; - results = []; - for (i = 0; i < models.length; i++) { - model = models[i]; - results.push(model.setReferencedModels(this.models)); + + if ((queryParams) && queryParams.length > 0) { + url += '?' + queryParams; } - return results; + + return url; }; -var SwaggerResource = function (resourceObj, api) { - var _this = this; - this.api = api; - this.swaggerRequstHeaders = api.swaggerRequstHeaders; - this.path = (typeof this.api.resourcePath === 'string') ? this.api.resourcePath : resourceObj.path; - this.description = resourceObj.description; - this.authorizations = (resourceObj.authorizations || {}); +SwaggerOperation.prototype.supportHeaderParams = function () { + return this.resource.api.supportHeaderParams; +}; - var parts = this.path.split('/'); - this.name = parts[parts.length - 1].replace('.{format}', ''); - this.basePath = this.api.basePath; - this.operations = {}; - this.operationsArray = []; - this.modelsArray = []; - this.models = api.models || {}; - this.rawModels = {}; - this.useJQuery = (typeof api.useJQuery !== 'undefined') ? api.useJQuery : null; +SwaggerOperation.prototype.supportedSubmitMethods = function () { + return this.resource.api.supportedSubmitMethods; +}; - if ((resourceObj.apis) && this.api.resourcePath) { - this.addApiDeclaration(resourceObj); - } else { - if (typeof this.path === 'undefined') { - this.api.fail('SwaggerResources must have a path.'); - } - if (this.path.substring(0, 4) === 'http') { - this.url = this.path.replace('{format}', 'json'); - } else { - this.url = this.api.basePath + this.path.replace('{format}', 'json'); - } - this.api.progress('fetching resource ' + this.name + ': ' + this.url); - var obj = { - url: this.url, - method: 'GET', - useJQuery: this.useJQuery, - headers: { - accept: this.swaggerRequstHeaders - }, - on: { - response: function (resp) { - var responseObj = resp.obj || JSON.parse(resp.data); - _this.api.resourceCount += 1; - return _this.addApiDeclaration(responseObj); - }, - error: function (response) { - _this.api.resourceCount += 1; - return _this.api.fail('Unable to read api \'' + - _this.name + '\' from path ' + _this.url + ' (server returned ' + response.statusText + ')'); - } - } - }; - var e = typeof window !== 'undefined' ? window : exports; - e.authorizations.apply(obj); - new SwaggerHttp().execute(obj); - } +SwaggerOperation.prototype.getQueryParams = function (args) { + return this.getMatchingParams(['query'], args); }; -SwaggerResource.prototype.help = function (dontPrint) { - var i; - var output = 'operations for the "' + this.name + '" tag'; - for(i = 0; i < this.operationsArray.length; i++) { - var api = this.operationsArray[i]; - output += '\n * ' + api.nickname + ': ' + api.description; - } - if(dontPrint) - return output; - else { - log(output); - return output; - } +SwaggerOperation.prototype.getHeaderParams = function (args) { + return this.getMatchingParams(['header'], args); }; -SwaggerResource.prototype.getAbsoluteBasePath = function (relativeBasePath) { - var pos, url; - url = this.api.basePath; - pos = url.lastIndexOf(relativeBasePath); - var parts = url.split('/'); - var rootUrl = parts[0] + '//' + parts[2]; +SwaggerOperation.prototype.getMatchingParams = function (paramTypes, args) { + var matchingParams = {}; + var params = this.parameters; - if (relativeBasePath.indexOf('http') === 0) - return relativeBasePath; - if (relativeBasePath === '/') - return rootUrl; - if (relativeBasePath.substring(0, 1) == '/') { - // use root + relative - return rootUrl + relativeBasePath; + for (var i = 0; i < params.length; i++) { + var param = params[i]; + + if (args && args[param.name]) { + matchingParams[param.name] = args[param.name]; + } } - else { - pos = this.basePath.lastIndexOf('/'); - var base = this.basePath.substring(0, pos); - if (base.substring(base.length - 1) == '/') - return base + relativeBasePath; - else - return base + '/' + relativeBasePath; + + var headers = this.resource.api.headers; + var name; + + for (name in headers) { + var value = headers[name]; + + matchingParams[name] = value; } + + return matchingParams; }; -SwaggerResource.prototype.addApiDeclaration = function (response) { - if (typeof response.produces === 'string') - this.produces = response.produces; - if (typeof response.consumes === 'string') - this.consumes = response.consumes; - if ((typeof response.basePath === 'string') && response.basePath.replace(/\s/g, '').length > 0) - this.basePath = response.basePath.indexOf('http') !== 0 ? this.getAbsoluteBasePath(response.basePath) : response.basePath; - this.resourcePath = response.resourcePath; - this.addModels(response.models); - if (response.apis) { - for (var i = 0 ; i < response.apis.length; i++) { - var endpoint = response.apis[i]; - this.addOperations(endpoint.path, endpoint.operations, response.consumes, response.produces); - } +SwaggerOperation.prototype.help = function (dontPrint) { + var msg = this.nickname + ': ' + this.summary; + var params = this.parameters; + + for (var i = 0; i < params.length; i++) { + var param = params[i]; + + msg += '\n* ' + param.name + (param.required ? ' (required)' : '') + ' - ' + param.description; + } + + if (dontPrint) { + return msg; + } else { + helpers.log(msg); + + return msg; } - this.api[this.name] = this; - this.ready = true; - if(this.api.resourceCount === this.api.expectedResourceCount) - this.api.finish(); - return this; }; -SwaggerResource.prototype.addModels = function (models) { - if (typeof models === 'object') { - var modelName; - for (modelName in models) { - if (typeof this.models[modelName] === 'undefined') { - var swaggerModel = new SwaggerModel(modelName, models[modelName]); - this.modelsArray.push(swaggerModel); - this.models[modelName] = swaggerModel; - this.rawModels[modelName] = models[modelName]; - } - } - var output = []; - for (var i = 0; i < this.modelsArray.length; i++) { - var model = this.modelsArray[i]; - output.push(model.setReferencedModels(this.models)); +SwaggerOperation.prototype.asCurl = function (args) { + var headers = SwaggerRequest.prototype.setHeaders(args, {}, this); + var results = []; + var i; + + for (i = 0; i < this.parameters.length; i++) { + var param = this.parameters[i]; + + if (param.paramType && param.paramType === 'header' && args[param.name]) { + headers[param.name] = args[param.name]; } - return output; } -}; -SwaggerResource.prototype.addOperations = function (resource_path, ops, consumes, produces) { - if (ops) { - var output = []; - for (var i = 0; i < ops.length; i++) { - var o = ops[i]; - consumes = this.consumes; - produces = this.produces; - if (typeof o.consumes !== 'undefined') - consumes = o.consumes; - else - consumes = this.consumes; - - if (typeof o.produces !== 'undefined') - produces = o.produces; - else - produces = this.produces; - var type = (o.type || o.responseClass); - - if (type === 'array') { - ref = null; - if (o.items) - ref = o.items.type || o.items.$ref; - type = 'array[' + ref + ']'; - } - var responseMessages = o.responseMessages; - var method = o.method; - if (o.httpMethod) { - method = o.httpMethod; - } - if (o.supportedContentTypes) { - consumes = o.supportedContentTypes; - } - if (o.errorResponses) { - responseMessages = o.errorResponses; - for (var j = 0; j < responseMessages.length; j++) { - r = responseMessages[j]; - r.message = r.reason; - r.reason = null; - } - } - o.nickname = this.sanitize(o.nickname); - var op = new SwaggerOperation(o.nickname, - resource_path, - method, - o.parameters, - o.summary, - o.notes, - type, - responseMessages, - this, - consumes, - produces, - o.authorizations, - o.deprecated); + var key; - this.operations[op.nickname] = op; - output.push(this.operationsArray.push(op)); - } - return output; + for (key in headers) { + results.push('--header "' + key + ': ' + headers[key] + '"'); } -}; -SwaggerResource.prototype.sanitize = function (nickname) { - var op; - op = nickname.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_'); - op = op.replace(/((_){2,})/g, '_'); - op = op.replace(/^(_)*/g, ''); - op = op.replace(/([_])*$/g, ''); - return op; + return 'curl ' + (results.join(' ')) + ' ' + this.urlify(args); }; -var SwaggerModel = function (modelName, obj) { - this.name = typeof obj.id !== 'undefined' ? obj.id : modelName; - this.properties = []; - var propertyName; - for (propertyName in obj.properties) { - if (obj.required) { - var value; - for (value in obj.required) { - if (propertyName === obj.required[value]) { - obj.properties[propertyName].required = true; +SwaggerOperation.prototype.formatXml = function (xml) { + var contexp, formatted, indent, lastType, lines, ln, pad, reg, transitions, wsexp, _fn, _i, _len; + + reg = /(>)(<)(\/*)/g; + wsexp = /[ ]*(.*)[ ]+\n/g; + contexp = /(<.+>)(.+\n)/g; + xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2'); + pad = 0; + formatted = ''; + lines = xml.split('\n'); + indent = 0; + lastType = 'other'; + transitions = { + 'single->single': 0, + 'single->closing': -1, + 'single->opening': 0, + 'single->other': 0, + 'closing->single': 0, + 'closing->closing': -1, + 'closing->opening': 0, + 'closing->other': 0, + 'opening->single': 1, + 'opening->closing': 0, + 'opening->opening': 1, + 'opening->other': 1, + 'other->single': 0, + 'other->closing': -1, + 'other->opening': 0, + 'other->other': 0 + }; + _fn = function (ln) { + var fromTo, j, key, padding, type, types, value; + + types = { + single: Boolean(ln.match(/<.+\/>/)), + closing: Boolean(ln.match(/<\/.+>/)), + opening: Boolean(ln.match(/<[^!?].*>/)) + }; + type = ((function () { + var _results; + _results = []; + for (key in types) { + value = types[key]; + if (value) { + _results.push(key); } } + return _results; + })())[0]; + type = type === void 0 ? 'other' : type; + fromTo = lastType + '->' + type; + lastType = type; + padding = ''; + indent += transitions[fromTo]; + padding = ((function () { + var _j, _ref5; + var _results = []; + + for (j = _j = 0, _ref5 = indent; 0 <= _ref5 ? _j < _ref5 : _j > _ref5; j = 0 <= _ref5 ? ++_j : --_j) { + _results.push(' '); + } + + return _results; + })()).join(''); + + if (fromTo === 'opening->closing') { + formatted = formatted.substr(0, formatted.length - 1) + ln + '\n'; + } else { + formatted += padding + ln + '\n'; } - var prop = new SwaggerModelProperty(propertyName, obj.properties[propertyName], this); - this.properties.push(prop); - } -}; + }; -SwaggerModel.prototype.setReferencedModels = function (allModels) { - var results = []; - for (var i = 0; i < this.properties.length; i++) { - var property = this.properties[i]; - var type = property.type || property.dataType; - if (allModels[type]) - results.push(property.refModel = allModels[type]); - else if ((property.refDataType) && (allModels[property.refDataType])) - results.push(property.refModel = allModels[property.refDataType]); - else - results.push(void 0); + for (_i = 0, _len = lines.length; _i < _len; _i++) { + ln = lines[_i]; + _fn(ln); } - return results; + + return formatted; }; -SwaggerModel.prototype.getMockSignature = function (modelsToIgnore) { - var i, prop, propertiesStr = []; - for (i = 0; i < this.properties.length; i++) { - prop = this.properties[i]; - propertiesStr.push(prop.toString()); - } +SwaggerRequest.prototype.setHeaders = function (params, opts, operation) { + var accepts = opts.responseContentType || 'application/json'; // default type + var consumes = opts.requestContentType || 'application/json'; // default type + var allDefinedParams = operation.parameters; + var definedFormParams = []; + var definedFileParams = []; + var body = params.body; + var headers = {}; + var i; - var strong = ''; - var strongClose = ''; - var classOpen = strong + this.name + ' {' + strongClose; - var classClose = strong + '}' + strongClose; - var returnVal = classOpen + '
' + propertiesStr.join(',
') + '
' + classClose; - if (!modelsToIgnore) - modelsToIgnore = []; - modelsToIgnore.push(this.name); + // get params from the operation and set them in definedFileParams, definedFormParams, headers + for (i = 0; i < allDefinedParams.length; i++) { + var param = allDefinedParams[i]; - for (i = 0; i < this.properties.length; i++) { - prop = this.properties[i]; - if ((prop.refModel) && modelsToIgnore.indexOf(prop.refModel.name) === -1) { - returnVal = returnVal + ('
' + prop.refModel.getMockSignature(modelsToIgnore)); - } - } - return returnVal; -}; + if (param.paramType === 'form') { + definedFormParams.push(param); + } else if (param.paramType === 'file') { + definedFileParams.push(param); + } else if (param.paramType === 'header' && this.params.headers) { + var key = param.name; + var headerValue = this.params.headers[param.name]; -SwaggerModel.prototype.createJSONSample = function (modelsToIgnore) { - if (sampleModels[this.name]) { - return sampleModels[this.name]; - } - else { - var result = {}; - modelsToIgnore = (modelsToIgnore || []); - modelsToIgnore.push(this.name); - for (var i = 0; i < this.properties.length; i++) { - var prop = this.properties[i]; - result[prop.name] = prop.getSampleValue(modelsToIgnore); + if (typeof this.params.headers[param.name] !== 'undefined') { + headers[key] = headerValue; + } } - modelsToIgnore.pop(this.name); - return result; } -}; -var SwaggerModelProperty = function (name, obj, model) { - this.name = name; - this.dataType = obj.type || obj.dataType || obj.$ref; - this.isCollection = this.dataType && (this.dataType.toLowerCase() === 'array' || this.dataType.toLowerCase() === 'list' || this.dataType.toLowerCase() === 'set'); - this.descr = obj.description; - this.required = obj.required; - this.defaultValue = applyModelPropertyMacro(obj, model); - if (obj.items) { - if (obj.items.type) { - this.refDataType = obj.items.type; - } - if (obj.items.$ref) { - this.refDataType = obj.items.$ref; + // if there's a body, need to set the accepts header via requestContentType + if (body && (this.type === 'POST' || this.type === 'PUT' || this.type === 'PATCH' || this.type === 'DELETE')) { + if (this.opts.requestContentType) { + consumes = this.opts.requestContentType; } - } - this.dataTypeWithRef = this.refDataType ? (this.dataType + '[' + this.refDataType + ']') : this.dataType; - if (obj.allowableValues) { - this.valueType = obj.allowableValues.valueType; - this.values = obj.allowableValues.values; - if (this.values) { - this.valuesString = '\'' + this.values.join('\' or \'') + '\''; + } else { + // if any form params, content type must be set + if (definedFormParams.length > 0) { + if (definedFileParams.length > 0) { + consumes = 'multipart/form-data'; + } else { + consumes = 'application/x-www-form-urlencoded'; + } + } else if (this.type === 'DELETE') { + body = '{}'; + } else if (this.type !== 'DELETE') { + consumes = null; } } - if (obj['enum']) { - this.valueType = 'string'; - this.values = obj['enum']; - if (this.values) { - this.valueString = '\'' + this.values.join('\' or \'') + '\''; + + if (consumes && this.operation.consumes) { + if (this.operation.consumes.indexOf(consumes) === -1) { + helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.operation.consumes)); } } -}; -SwaggerModelProperty.prototype.getSampleValue = function (modelsToIgnore) { - var result; - if ((this.refModel) && (modelsToIgnore.indexOf(this.refModel.name) === -1)) { - result = this.refModel.createJSONSample(modelsToIgnore); + if (this.opts && this.opts.responseContentType) { + accepts = this.opts.responseContentType; } else { - if (this.isCollection) { - result = this.toSampleValue(this.refDataType); - } else { - result = this.toSampleValue(this.dataType); + accepts = 'application/json'; + } + + if (accepts && operation.produces) { + if (operation.produces.indexOf(accepts) === -1) { + helpers.log('server can\'t produce ' + accepts); } } - if (this.isCollection) { - return [result]; - } else { - return result; + + if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) { + headers['Content-Type'] = consumes; + } + + if (accepts) { + headers.Accept = accepts; } + + return headers; }; -SwaggerModelProperty.prototype.toSampleValue = function (value) { - var result; - if ((typeof this.defaultValue !== 'undefined') && this.defaultValue) { - result = this.defaultValue; - } else if (value === 'integer') { - result = 0; - } else if (value === 'boolean') { - result = false; - } else if (value === 'double' || value === 'number') { - result = 0.0; - } else if (value === 'string') { - result = ''; - } else { - result = value; +},{"./client":4,"./helpers":5,"./http":6}],4:[function(require,module,exports){ +'use strict'; + +var auth = require('./auth'); +var helpers = require('./helpers'); +var Model = require('./types/model'); +var Operation = require('./types/operation'); +var OperationGroup = require('./types/operationGroup'); +var Resolver = require('./resolver'); +var SwaggerHttp = require('./http'); + +var SwaggerClient = module.exports = function (url, options) { + this.authorizationScheme = null; + this.authorizations = null; + this.basePath = null; + this.debug = false; + this.info = null; + this.isBuilt = false; + this.isValid = false; + this.modelsArray = []; + this.resourceCount = 0; + this.url = null; + this.useJQuery = false; + + if (typeof url !== 'undefined') { + return this.initialize(url, options); } - return result; }; -SwaggerModelProperty.prototype.toString = function () { - var req = this.required ? 'propReq' : 'propOpt'; - var str = '' + this.name + ' (' + this.dataTypeWithRef + ''; - if (!this.required) { - str += ', optional'; +SwaggerClient.prototype.initialize = function (url, options) { + this.models = {}; + this.sampleModels = {}; + + options = (options||{}); + + if (typeof url === 'string') { + this.url = url; + } else if (typeof url === 'object') { + options = url; + this.url = options.url; } - str += ')'; - if (this.values) { - str += ' = [\'' + this.values.join('\' or \'') + '\']'; + + this.swaggerRequstHeaders = options.swaggerRequstHeaders || 'application/json;charset=utf-8,*/*'; + this.defaultSuccessCallback = options.defaultSuccessCallback || null; + this.defaultErrorCallback = options.defaultErrorCallback || null; + + if (typeof options.success === 'function') { + this.success = options.success; } - if (this.descr) { - str += ': ' + this.descr + ''; + + if (options.useJQuery) { + this.useJQuery = options.useJQuery; + } + + if (options.authorizations) { + this.clientAuthorizations = options.authorizations; + } else { + this.clientAuthorizations = new auth.SwaggerAuthorizations(); + } + + this.supportedSubmitMethods = options.supportedSubmitMethods || []; + this.failure = options.failure || function () {}; + this.progress = options.progress || function () {}; + this.spec = options.spec; + this.options = options; + + if (typeof options.success === 'function') { + this.ready = true; + this.build(); } - return str; }; -var SwaggerOperation = function (nickname, path, method, parameters, summary, notes, type, responseMessages, resource, consumes, produces, authorizations, deprecated) { - var _this = this; +SwaggerClient.prototype.build = function (mock) { + if (this.isBuilt) { + return this; + } - var errors = []; - this.nickname = (nickname || errors.push('SwaggerOperations must have a nickname.')); - this.path = (path || errors.push('SwaggerOperation ' + nickname + ' is missing path.')); - this.method = (method || errors.push('SwaggerOperation ' + nickname + ' is missing method.')); - this.parameters = parameters ? parameters : []; - this.summary = summary; - this.notes = notes; - this.type = type; - this.responseMessages = (responseMessages || []); - this.resource = (resource || errors.push('Resource is required')); - this.consumes = consumes; - this.produces = produces; - this.authorizations = typeof authorizations !== 'undefined' ? authorizations : resource.authorizations; - this.deprecated = deprecated; - this['do'] = __bind(this['do'], this); + var self = this; + this.progress('fetching resource list: ' + this.url); - if(typeof this.deprecated === 'string') { - switch(this.deprecated.toLowerCase()) { - case 'true': case 'yes': case '1': { - this.deprecated = true; - break; - } - case 'false': case 'no': case '0': case null: { - this.deprecated = false; - break; + var obj = { + useJQuery: this.useJQuery, + url: this.url, + method: 'get', + headers: { + accept: this.swaggerRequstHeaders + }, + on: { + error: function (response) { + if (self.url.substring(0, 4) !== 'http') { + return self.fail('Please specify the protocol for ' + self.url); + } else if (response.status === 0) { + return self.fail('Can\'t read from server. It may not have the appropriate access-control-origin settings.'); + } else if (response.status === 404) { + return self.fail('Can\'t read swagger JSON from ' + self.url); + } else { + return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url); + } + }, + response: function (resp) { + var responseObj = resp.obj || JSON.parse(resp.data); + self.swaggerVersion = responseObj.swaggerVersion; + + if (responseObj.swagger && parseInt(responseObj.swagger) === 2) { + self.swaggerVersion = responseObj.swagger; + + new Resolver().resolve(responseObj, self.buildFromSpec, self); + + self.isValid = true; + } else { + if (self.swaggerVersion === '1.2') { + return self.buildFrom1_2Spec(responseObj); // jshint ignore:line + } else { + return self.buildFrom1_1Spec(responseObj); // jshint ignore:line + } + } } - default: this.deprecated = Boolean(this.deprecated); } + }; + + if (this.spec) { + setTimeout(function () { + new Resolver().resolve(self.spec, self.buildFromSpec, self); + }, 10); + } else { + this.clientAuthorizations.apply(obj); + + if (mock) { + return obj; + } + + new SwaggerHttp().execute(obj); } - if (errors.length > 0) { - console.error('SwaggerOperation errors', errors, arguments); - this.resource.api.fail(errors); + return this; +}; + +SwaggerClient.prototype.buildFromSpec = function (response) { + if (this.isBuilt) { + return this; } - this.path = this.path.replace('{format}', 'json'); - this.method = this.method.toLowerCase(); - this.isGetMethod = this.method === 'get'; + this.apis = {}; + this.apisArray = []; + this.basePath = response.basePath || ''; + this.consumes = response.consumes; + this.host = response.host || ''; + this.info = response.info || {}; + this.produces = response.produces; + this.schemes = response.schemes || []; + this.securityDefinitions = response.securityDefinitions; + this.title = response.title || ''; - var i, j, v; - this.resourceName = this.resource.name; - if (typeof this.type !== 'undefined' && this.type === 'void') - this.type = null; - else { - this.responseClassSignature = this.getSignature(this.type, this.resource.models); - this.responseSampleJSON = this.getSampleJSON(this.type, this.resource.models); + // legacy support + this.authSchemes = response.securityDefinitions; + + var definedTags = {}; + var k; + + if (Array.isArray(response.tags)) { + definedTags = {}; + + for (k = 0; k < response.tags.length; k++) { + var t = response.tags[k]; + + definedTags[t.name] = t; + } } - for (i = 0; i < this.parameters.length; i++) { - var param = this.parameters[i]; - // might take this away - param.name = param.name || param.type || param.dataType; - // for 1.1 compatibility - type = param.type || param.dataType; - if (type === 'array') { - type = 'array[' + (param.items.$ref ? param.items.$ref : param.items.type) + ']'; + var location; + + if (typeof this.url === 'string') { + location = this.parseUri(this.url); + } + + if (typeof this.schemes === 'undefined' || this.schemes.length === 0) { + this.scheme = location.scheme || 'http'; + } else { + this.scheme = this.schemes[0]; + } + + if (typeof this.host === 'undefined' || this.host === '') { + this.host = location.host; + + if (location.port) { + this.host = this.host + ':' + location.port; } - param.type = type; + } - if (type && type.toLowerCase() === 'boolean') { - param.allowableValues = {}; - param.allowableValues.values = ['true', 'false']; + this.definitions = response.definitions; + + var key; + + for (key in this.definitions) { + var model = new Model(key, this.definitions[key], this.models); + + if (model) { + this.models[key] = model; } - param.signature = this.getSignature(type, this.resource.models); - param.sampleJSON = this.getSampleJSON(type, this.resource.models); + } - var enumValue = param['enum']; - if (typeof enumValue !== 'undefined') { - param.isList = true; - param.allowableValues = {}; - param.allowableValues.descriptiveValues = []; + // get paths, create functions for each operationId + var path; - for (j = 0; j < enumValue.length; j++) { - v = enumValue[j]; - if (param.defaultValue) { - param.allowableValues.descriptiveValues.push({ - value: String(v), - isDefault: (v === param.defaultValue) - }); - } - else { - param.allowableValues.descriptiveValues.push({ - value: String(v), - isDefault: false - }); + for (path in response.paths) { + if (typeof response.paths[path] === 'object') { + var httpMethod; + + for (httpMethod in response.paths[path]) { + if (['delete', 'get', 'head', 'options', 'patch', 'post', 'put'].indexOf(httpMethod) === -1) { + continue; } - } - } - else if (param.allowableValues) { - if (param.allowableValues.valueType === 'RANGE') - param.isRange = true; - else - param.isList = true; - if (param.allowableValues) { - param.allowableValues.descriptiveValues = []; - if (param.allowableValues.values) { - for (j = 0; j < param.allowableValues.values.length; j++) { - v = param.allowableValues.values[j]; - if (param.defaultValue !== null) { - param.allowableValues.descriptiveValues.push({ - value: String(v), - isDefault: (v === param.defaultValue) - }); - } - else { - param.allowableValues.descriptiveValues.push({ - value: String(v), - isDefault: false - }); - } - } + + var operation = response.paths[path][httpMethod]; + var tags = operation.tags; + + if (typeof tags === 'undefined') { + operation.tags = [ 'default' ]; + tags = operation.tags; } - } - } - param.defaultValue = applyParameterMacro(this, param); - } - var defaultSuccessCallback = this.resource.api.defaultSuccessCallback || null; - var defaultErrorCallback = this.resource.api.defaultErrorCallback || null; - this.resource[this.nickname] = function (args, opts, callback, error) { - var arg1, arg2, arg3, arg4; - if(typeof args === 'function') { // right shift 3 - arg1 = {}; arg2 = {}; arg3 = args; arg4 = opts; - } - else if(typeof args === 'object' && typeof opts === 'function') { // right shift 2 - arg1 = args; arg2 = {}; arg3 = opts; arg4 = callback; - } - else { - arg1 = args; arg2 = opts; arg3 = callback; arg4 = error; - } - return _this['do'](arg1 || {}, arg2 || {}, arg3 || defaultSuccessCallback, arg4 || defaultErrorCallback); - }; + var operationId = this.idFromOp(path, httpMethod, operation); + var operationObject = new Operation ( + this, + operation.scheme, + operationId, + httpMethod, + path, + operation, + this.definitions, + this.models, + this.clientAuthorizations + ); + + // bind this operation's execute command to the api + if (tags.length > 0) { + var i; + + for (i = 0; i < tags.length; i++) { + var tag = this.tagFromLabel(tags[i]); + var operationGroup = this[tag]; + + if (typeof this.apis[tag] === 'undefined') { + this.apis[tag] = {}; + } + + if (typeof operationGroup === 'undefined') { + this[tag] = []; + operationGroup = this[tag]; + operationGroup.operations = {}; + operationGroup.label = tag; + operationGroup.apis = []; + + var tagObject = definedTags[tag]; + + if (typeof tagObject === 'object') { + operationGroup.description = tagObject.description; + operationGroup.externalDocs = tagObject.externalDocs; + } + + this[tag].help = this.help.bind(operationGroup); + this.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject)); + } + + if (typeof this.apis[tag].help !== 'function') { + this.apis[tag].help = this.help.bind(operationGroup); + } + + // bind to the apis object + this.apis[tag][operationId] = operationObject.execute.bind(operationObject); + this.apis[tag][operationId].help = operationObject.help.bind(operationObject); + this.apis[tag][operationId].asCurl = operationObject.asCurl.bind(operationObject); + + operationGroup[operationId] = operationObject.execute.bind(operationObject); + operationGroup[operationId].help = operationObject.help.bind(operationObject); + operationGroup[operationId].asCurl = operationObject.asCurl.bind(operationObject); + + operationGroup.apis.push(operationObject); + operationGroup.operations[operationId] = operationObject; + + // legacy UI feature + var j; + var api; + + for (j = 0; j < this.apisArray.length; j++) { + if (this.apisArray[j].tag === tag) { + api = this.apisArray[j]; + } + } + + if (api) { + api.operationsArray.push(operationObject); + } + } + } else { + helpers.log('no group to bind to'); + } + } + } + } + + this.isBuilt = true; + + if (this.success) { + this.isValid = true; + this.isBuilt = true; + this.success(); + } + + return this; +}; + +SwaggerClient.prototype.parseUri = function (uri) { + var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/; + var parts = urlParseRE.exec(uri); + + return { + scheme: parts[4].replace(':',''), + host: parts[11], + port: parts[12], + path: parts[15] + }; +}; + +SwaggerClient.prototype.help = function (dontPrint) { + var i; + var output = 'operations for the "' + this.label + '" tag'; + + for (i = 0; i < this.apis.length; i++) { + var api = this.apis[i]; + + output += '\n * ' + api.nickname + ': ' + api.operation.summary; + } + + if (dontPrint) { + return output; + } else { + helpers.log(output); + + return output; + } +}; + +SwaggerClient.prototype.tagFromLabel = function (label) { + return label; +}; + +SwaggerClient.prototype.idFromOp = function (path, httpMethod, op) { + var opId = op.operationId || (path.substring(1) + '_' + httpMethod); + + return opId.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()\+\s]/g,'_'); +}; + +SwaggerClient.prototype.fail = function (message) { + this.failure(message); + + throw message; +}; + +},{"./auth":2,"./helpers":5,"./http":6,"./resolver":7,"./types/model":9,"./types/operation":10,"./types/operationGroup":11}],5:[function(require,module,exports){ +'use strict'; + +module.exports.__bind = function (fn, me) { + return function(){ + return fn.apply(me, arguments); + }; +}; + +var log = module.exports.log = function() { + log.history = log.history || []; + log.history.push(arguments); + + if (console) { + console.log(Array.prototype.slice.call(arguments)[0]); + } +}; + +module.exports.fail = function (message) { + log(message); +}; + +module.exports.optionHtml = function (label, value) { + return '' + label + ':' + value + ''; +}; + +module.exports.typeFromJsonSchema = function (type, format) { + var str; + + if (type === 'integer' && format === 'int32') { + str = 'integer'; + } else if (type === 'integer' && format === 'int64') { + str = 'long'; + } else if (type === 'integer' && typeof format === 'undefined') { + str = 'long'; + } else if (type === 'string' && format === 'date-time') { + str = 'date-time'; + } else if (type === 'string' && format === 'date') { + str = 'date'; + } else if (type === 'number' && format === 'float') { + str = 'float'; + } else if (type === 'number' && format === 'double') { + str = 'double'; + } else if (type === 'number' && typeof format === 'undefined') { + str = 'double'; + } else if (type === 'boolean') { + str = 'boolean'; + } else if (type === 'string') { + str = 'string'; + } + + return str; +}; + +var simpleRef = module.exports.simpleRef = function (name) { + if (typeof name === 'undefined') { + return null; + } + + if (name.indexOf('#/definitions/') === 0) { + return name.substring('#/definitions/'.length); + } else { + return name; + } +}; + +var getStringSignature = module.exports.getStringSignature = function (obj, baseComponent) { + var str = ''; + + if (typeof obj.$ref !== 'undefined') { + str += simpleRef(obj.$ref); + } else if (typeof obj.type === 'undefined') { + str += 'object'; + } else if (obj.type === 'array') { + if (baseComponent) { + str += getStringSignature((obj.items || obj.$ref || {})); + } else { + str += 'Array['; + str += getStringSignature((obj.items || obj.$ref || {})); + str += ']'; + } + } else if (obj.type === 'integer' && obj.format === 'int32') { + str += 'integer'; + } else if (obj.type === 'integer' && obj.format === 'int64') { + str += 'long'; + } else if (obj.type === 'integer' && typeof obj.format === 'undefined') { + str += 'long'; + } else if (obj.type === 'string' && obj.format === 'date-time') { + str += 'date-time'; + } else if (obj.type === 'string' && obj.format === 'date') { + str += 'date'; + } else if (obj.type === 'string' && typeof obj.format === 'undefined') { + str += 'string'; + } else if (obj.type === 'number' && obj.format === 'float') { + str += 'float'; + } else if (obj.type === 'number' && obj.format === 'double') { + str += 'double'; + } else if (obj.type === 'number' && typeof obj.format === 'undefined') { + str += 'double'; + } else if (obj.type === 'boolean') { + str += 'boolean'; + } else if (obj.$ref) { + str += simpleRef(obj.$ref); + } else { + str += obj.type; + } + + return str; +}; + +},{}],6:[function(require,module,exports){ +'use strict'; + +var helpers = require('./helpers'); +var jQuery = require('jquery'); +var request = require('superagent'); + +/* + * JQueryHttpClient is a light-weight, node or browser HTTP client + */ +var JQueryHttpClient = function () {}; + +/* + * SuperagentHttpClient is a light-weight, node or browser HTTP client + */ +var SuperagentHttpClient = function () {}; + +/** + * SwaggerHttp is a wrapper for executing requests + */ +var SwaggerHttp = module.exports = function () {}; + +SwaggerHttp.prototype.execute = function (obj, opts) { + if (obj && (typeof obj.useJQuery === 'boolean')) { + this.useJQuery = obj.useJQuery; + } else { + this.useJQuery = this.isIE8(); + } + + if (obj && typeof obj.body === 'object') { + // special processing for file uploads via jquery + if (obj.body.type && obj.body.type === 'formData'){ + obj.contentType = false; + obj.processData = false; + + delete obj.headers['Content-Type']; + } else { + obj.body = JSON.stringify(obj.body); + } + } + + if (this.useJQuery) { + return new JQueryHttpClient(opts).execute(obj); + } else { + return new SuperagentHttpClient(opts).execute(obj); + } +}; + +SwaggerHttp.prototype.isIE8 = function () { + var detectedIE = false; + + if (typeof navigator !== 'undefined' && navigator.userAgent) { + var nav = navigator.userAgent.toLowerCase(); + + if (nav.indexOf('msie') !== -1) { + var version = parseInt(nav.split('msie')[1]); + + if (version <= 8) { + detectedIE = true; + } + } + } + + return detectedIE; +}; + +JQueryHttpClient.prototype.execute = function (obj) { + var cb = obj.on; + var request = obj; + + obj.type = obj.method; + obj.cache = false; + delete obj.useJQuery; + + /* + obj.beforeSend = function (xhr) { + var key, results; + if (obj.headers) { + results = []; + for (key in obj.headers) { + if (key.toLowerCase() === 'content-type') { + results.push(obj.contentType = obj.headers[key]); + } else if (key.toLowerCase() === 'accept') { + results.push(obj.accepts = obj.headers[key]); + } else { + results.push(xhr.setRequestHeader(key, obj.headers[key])); + } + } + return results; + } + };*/ + + obj.data = obj.body; + + delete obj.body; + + obj.complete = function (response) { + var headers = {}; + var headerArray = response.getAllResponseHeaders().split('\n'); + + for (var i = 0; i < headerArray.length; i++) { + var toSplit = headerArray[i].trim(); + + if (toSplit.length === 0) { + continue; + } + + var separator = toSplit.indexOf(':'); + + if (separator === -1) { + // Name but no value in the header + headers[toSplit] = null; + + continue; + } + + var name = toSplit.substring(0, separator).trim(); + var value = toSplit.substring(separator + 1).trim(); + + headers[name] = value; + } + + var out = { + url: request.url, + method: request.method, + status: response.status, + statusText: response.statusText, + data: response.responseText, + headers: headers + }; + + var contentType = (headers['content-type'] || headers['Content-Type'] || null); + + if (contentType) { + if (contentType.indexOf('application/json') === 0 || contentType.indexOf('+json') > 0) { + try { + out.obj = response.responseJSON || JSON.parse(out.data) || {}; + } catch (ex) { + // do not set out.obj + helpers.log('unable to parse JSON content'); + } + } + } + + if (response.status >= 200 && response.status < 300) { + cb.response(out); + } else if (response.status === 0 || (response.status >= 400 && response.status < 599)) { + cb.error(out); + } else { + return cb.response(out); + } + }; + + jQuery.support.cors = true; + + return jQuery.ajax(obj); +}; + +SuperagentHttpClient.prototype.execute = function (obj) { + var method = obj.method.toLowerCase(); + + if (method === 'delete') { + method = 'del'; + } + + var headers = obj.headers || {}; + var r = request[method](obj.url); + var name; + + for (name in headers) { + r.set(name, headers[name]); + } + + if (obj.body) { + r.send(obj.body); + } + + r.end(function (err, res) { + var response = { + url: obj.url, + method: obj.method, + headers: headers + }; + var cb; + + if (!err && res.error) { + err = res.error; + } + + if (err && obj.on && obj.on.error) { + response.obj = err; + response.status = res ? res.status : 500; + response.statusText = res ? res.text : err.message; + cb = obj.on.error; + } else if (res && obj.on && obj.on.response) { + response.obj = (typeof res.body !== 'undefined') ? res.body : res.text; + response.status = res.status; + response.statusText = res.text; + cb = obj.on.response; + } + response.data = response.statusText; + + if (cb) { + cb(response); + } + }); +}; + +},{"./helpers":5,"jquery":18,"superagent":19}],7:[function(require,module,exports){ +'use strict'; + +var SwaggerHttp = require('./http'); + +/** + * Resolves a spec's remote references + */ +var Resolver = module.exports = function () {}; + +Resolver.prototype.resolve = function (spec, callback, scope) { + this.scope = (scope || this); + + var host, name, path, property, propertyName; + var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {}; + var resolutionTable = {}; // store objects for dereferencing + + // models + for (name in spec.definitions) { + var model = spec.definitions[name]; + + for (propertyName in model.properties) { + property = model.properties[propertyName]; + + this.resolveTo(property, resolutionTable); + } + } + + // operations + for (name in spec.paths) { + var method, operation, responseCode; + + path = spec.paths[name]; + + for (method in path) { + operation = path[method]; + + var i, parameters = operation.parameters; + + for (i in parameters) { + var parameter = parameters[i]; + + if (parameter.in === 'body' && parameter.schema) { + this.resolveTo(parameter.schema, resolutionTable); + } + + if (parameter.$ref) { + this.resolveInline(spec, parameter, resolutionTable, unresolvedRefs); + } + } + + for (responseCode in operation.responses) { + var response = operation.responses[responseCode]; + + if (response.schema) { + this.resolveTo(response.schema, resolutionTable); + } + } + } + } + + // get hosts + var opts = {}, expectedCalls = 0; + + for (name in resolutionTable) { + var parts = name.split('#'); + + if (parts.length === 2) { + host = parts[0]; path = parts[1]; + + if (!Array.isArray(opts[host])) { + opts[host] = []; + expectedCalls += 1; + } + + opts[host].push(path); + } + } + + for (name in opts) { + var self = this, opt = opts[name]; + + host = name; + + var obj = { + useJQuery: false, // TODO + url: host, + method: 'get', + headers: { + accept: this.scope.swaggerRequestHeaders || 'application/json' + }, + on: { + error: function () { + processedCalls += 1; + + var i; + + for (i = 0; i < opt.length; i++) { + // fail all of these + var resolved = host + '#' + opt[i]; + + unresolvedRefs[resolved] = null; + } + + if (processedCalls === expectedCalls) { + self.finish(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback); + } + }, // jshint ignore:line + response: function (response) { + var i, j, swagger = response.obj; + + processedCalls += 1; + + for (i = 0; i < opt.length; i++) { + var location = swagger, path = opt[i], parts = path.split('/'); + + for (j = 0; j < parts.length; j++) { + var segment = parts[j]; + + if (typeof location === 'undefined') { + break; + } + + if (segment.length > 0) { + location = location[segment]; + } + } + + var resolved = host + '#' + path, resolvedName = parts[j-1]; + + if (typeof location !== 'undefined') { + resolvedRefs[resolved] = { + name: resolvedName, + obj: location + }; + } else { + unresolvedRefs[resolved] = null; + } + } + if (processedCalls === expectedCalls) { + self.finish(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback); + } + } + } // jshint ignore:line + }; + + if (scope && scope.clientAuthorizations) { + scope.clientAuthorizations.apply(obj); + } + + new SwaggerHttp().execute(obj); + } + + if (Object.keys(opts).length === 0) { + callback.call(this.scope, spec, unresolvedRefs); + } +}; + +Resolver.prototype.finish = function (spec, resolutionTable, resolvedRefs, unresolvedRefs, callback) { + // walk resolution table and replace with resolved refs + var ref; + + for (ref in resolutionTable) { + var i, locations = resolutionTable[ref]; + + for (i = 0; i < locations.length; i++) { + var resolvedTo = resolvedRefs[locations[i].obj.$ref]; + + if (resolvedTo) { + if (!spec.definitions) { + spec.definitions = {}; + } + + if (locations[i].resolveAs === '$ref') { + spec.definitions[resolvedTo.name] = resolvedTo.obj; + locations[i].obj.$ref = '#/definitions/' + resolvedTo.name; + } else if (locations[i].resolveAs === 'inline') { + var targetObj = locations[i].obj; + var key; + + delete targetObj.$ref; + + for (key in resolvedTo.obj) { + targetObj[key] = resolvedTo.obj[key]; + } + } + } + } + } + + callback.call(this.scope, spec, unresolvedRefs); +}; + +/** + * immediately in-lines local refs, queues remote refs + * for inline resolution + */ +Resolver.prototype.resolveInline = function (spec, property, objs, unresolvedRefs) { + var ref = property.$ref; + + if (ref) { + if (ref.indexOf('http') === 0) { + if (Array.isArray(objs[ref])) { + objs[ref].push({obj: property, resolveAs: 'inline'}); + } else { + objs[ref] = [{obj: property, resolveAs: 'inline'}]; + } + } else if (ref.indexOf('#') === 0) { + // local resolve + var shortenedRef = ref.substring(1); + var i, parts = shortenedRef.split('/'), location = spec; + + for (i = 0; i < parts.length; i++) { + var part = parts[i]; + + if (part.length > 0) { + location = location[part]; + } + } + + if (location) { + delete property.$ref; + + var key; + + for (key in location) { + property[key] = location[key]; + } + } else { + unresolvedRefs[ref] = null; + } + } + } else if (property.type === 'array') { + this.resolveTo(property.items, objs); + } +}; + +Resolver.prototype.resolveTo = function (property, objs) { + var ref = property.$ref; + + if (ref) { + if (ref.indexOf('http') === 0) { + if (Array.isArray(objs[ref])) { + objs[ref].push({obj: property, resolveAs: '$ref'}); + } else { + objs[ref] = [{obj: property, resolveAs: '$ref'}]; + } + } + } else if (property.type === 'array') { + var items = property.items; + + this.resolveTo(items, objs); + } +}; + +},{"./http":6}],8:[function(require,module,exports){ +'use strict'; + +var helpers = require('../helpers'); + +var ArrayModel = module.exports = function (definition, models) { + this.models = models; + this.name = 'arrayModel'; + this.definition = definition || {}; + this.properties = []; + + var innerType = definition.items; + + if (innerType) { + if (innerType.type) { + this.type = helpers.typeFromJsonSchema(innerType.type, innerType.format); + } else { + this.ref = innerType.$ref; + } + } + + return this; +}; + +ArrayModel.prototype.createJSONSample = function (modelsToIgnore) { + var result; + + modelsToIgnore = (modelsToIgnore||{}); + + if (this.type) { + result = this.type; + } else if (this.ref) { + var name = helpers.simpleRef(this.ref); + + if (typeof modelsToIgnore[name] === 'undefined') { + modelsToIgnore[name] = this; + + result = this.models[name].createJSONSample(modelsToIgnore); + } else { + return name; + } + } + + return [ result ]; +}; + +ArrayModel.prototype.getSampleValue = function (modelsToIgnore) { + var result; + + modelsToIgnore = (modelsToIgnore || {}); + + if (this.type) { + result = this.type; + } else if (this.ref) { + var name = helpers.simpleRef(this.ref); + + result = this.models[name].getSampleValue(modelsToIgnore); + } + + return [ result ]; +}; + +ArrayModel.prototype.getMockSignature = function (modelsToIgnore) { + var propertiesStr = []; + var i, prop; + + for (i = 0; i < this.properties.length; i++) { + prop = this.properties[i]; + propertiesStr.push(prop.toString()); + } + + var strong = ''; + var strongClose = ''; + var classOpen = strong + 'array' + ' {' + strongClose; + var classClose = strong + '}' + strongClose; + var returnVal = classOpen + '
' + propertiesStr.join(',
') + '
' + classClose; + + if (!modelsToIgnore) { + modelsToIgnore = {}; + } + + modelsToIgnore[this.name] = this; + + for (i = 0; i < this.properties.length; i++) { + prop = this.properties[i]; + + var ref = prop.$ref; + var model = this.models[ref]; + + if (model && typeof modelsToIgnore[ref] === 'undefined') { + returnVal = returnVal + ('
' + model.getMockSignature(modelsToIgnore)); + } + } + + return returnVal; +}; + +},{"../helpers":5}],9:[function(require,module,exports){ +'use strict'; + +var ArrayModel = require('./arrayModel'); +var helpers = require('../helpers'); + +var Property = module.exports = function (name, obj, required, models) { + this.models = models; + this.schema = obj; + this.required = required; + + if (obj.$ref) { + this.$ref = helpers.simpleRef(obj.$ref); + } else if (obj.type === 'array' && obj.items) { + if (obj.items.$ref) { + this.$ref = helpers.simpleRef(obj.items.$ref); + } else { + obj = obj.items; + } + } + + this.name = name; + this.description = obj.description; + this.obj = obj; + this.optional = true; + this.optional = !required; + this.default = obj.default || null; + this.example = obj.example !== undefined ? obj.example : null; + this.collectionFormat = obj.collectionFormat || null; + this.maximum = obj.maximum || null; + this.exclusiveMaximum = obj.exclusiveMaximum || null; + this.minimum = obj.minimum || null; + this.exclusiveMinimum = obj.exclusiveMinimum || null; + this.maxLength = obj.maxLength || null; + this.minLength = obj.minLength || null; + this.pattern = obj.pattern || null; + this.maxItems = obj.maxItems || null; + this.minItems = obj.minItems || null; + this.uniqueItems = obj.uniqueItems || null; + this['enum'] = obj['enum'] || null; + this.multipleOf = obj.multipleOf || null; +}; + +var Model = module.exports = function (name, definition, models) { + this.models = models || {}; + this.name = name; + this.definition = definition || {}; + this.properties = []; + + if (definition.type === 'array') { + return new ArrayModel(definition, models); + } + + var requiredFields = definition.required || []; + var key; + var props = definition.properties; + + if (props) { + for (key in props) { + var required = false; + var property = props[key]; + + if (requiredFields.indexOf(key) >= 0) { + required = true; + } + + this.properties.push(new Property(key, property, required, this.models)); + } + } + + return this; +}; + +Model.prototype.createJSONSample = function (modelsToIgnore) { + var i, result = {}, representations = {}; + + modelsToIgnore = (modelsToIgnore||{}); + modelsToIgnore[this.name] = this; + + for (i = 0; i < this.properties.length; i++) { + var prop = this.properties[i]; + + var sample = prop.getSampleValue(modelsToIgnore, representations); + + result[prop.name] = sample; + } + + delete modelsToIgnore[this.name]; + + return result; +}; + +Model.prototype.getSampleValue = function (modelsToIgnore) { + var i, obj = {}, representations = {}; + + for (i = 0; i < this.properties.length; i++ ) { + var property = this.properties[i]; + + obj[property.name] = property.sampleValue(false, modelsToIgnore, representations); + } + + return obj; +}; + +Model.prototype.getMockSignature = function (modelsToIgnore) { + var i, prop, propertiesStr = []; + + for (i = 0; i < this.properties.length; i++) { + prop = this.properties[i]; + propertiesStr.push(prop.toString()); + } + + var strong = ''; + var strongClose = ''; + var classOpen = strong + this.name + ' {' + strongClose; + var classClose = strong + '}' + strongClose; + var returnVal = classOpen + '
' + propertiesStr.join(',
') + '
' + classClose; + + if (!modelsToIgnore) { + modelsToIgnore = {}; + } + + modelsToIgnore[this.name] = this; + + for (i = 0; i < this.properties.length; i++) { + prop = this.properties[i]; + + var ref = prop.$ref; + var model = this.models[ref]; + + if (model && typeof modelsToIgnore[model.name] === 'undefined') { + returnVal = returnVal + ('
' + model.getMockSignature(modelsToIgnore)); + } + } + + return returnVal; +}; + +Property.prototype.getSampleValue = function (modelsToIgnore, representations) { + return this.sampleValue(false, modelsToIgnore, representations); +}; + +Property.prototype.isArray = function () { + var schema = this.schema; + + if (schema.type === 'array') { + return true; + } else { + return false; + } +}; + +Property.prototype.sampleValue = function (isArray, ignoredModels, representations) { + isArray = (isArray || this.isArray()); + ignoredModels = (ignoredModels || {}); + // representations = (representations || {}); + + var self = this; + var getRefValue = function (ref) { + var refModelName = helpers.simpleRef(ref); + var refModel = self.models[refModelName]; + var output; + + if (typeof representations[type] !== 'undefined') { + output = representations[type]; + } + + if (refModel && typeof ignoredModels[type] === 'undefined') { + ignoredModels[type] = this; + output = refModel.getSampleValue(ignoredModels, representations); + representations[type] = output; + } else { + output = (representations[type] || refModelName); + } + + return output; + }; + + var type = helpers.getStringSignature(this.obj, true); + var output; + + if (this.$ref) { + output = getRefValue(this.$ref); + } else if (this.example) { + output = this.example; + } else if (this.default) { + output = this.default; + } else if (type === 'date-time') { + output = new Date().toISOString(); + } else if (type === 'date') { + output = new Date().toISOString().split('T')[0]; + } else if (type === 'string') { + output = 'string'; + } else if (type === 'integer') { + output = 0; + } else if (type === 'long') { + output = 0; + } else if (type === 'float') { + output = 0.0; + } else if (type === 'double') { + output = 0.0; + } else if (type === 'boolean') { + output = true; + } else if (this.schema.$ref) { + output = getRefValue(this.schema.$ref); + } else if (this.schema.properties) { + output = new Model('InlineModel-' + new Date(), this.schema, this.models).getSampleValue(); + } else { + output = {}; + } + + ignoredModels[type] = output; + + if (isArray) { + return [output]; + } else { + return output; + } +}; + +Property.prototype.toString = function () { + var str = helpers.getStringSignature(this.obj); + var strong =''; + var strongClose = ''; + var propertiesStr = []; + var prop; + + if (str === 'object') { + for (var name in this.schema.properties) { + if (this.schema.properties.hasOwnProperty(name)) { + prop = new Property(name, this.schema.properties[name], (this.schema.required || []).indexOf(name) > -1, this.models); + + propertiesStr.push(prop.toString()); + } + } + + str = strong + this.name + ' {' + strongClose + '
' + propertiesStr.join(',
') + '
' + strong + '}' + strongClose; + } else if (str !== '') { + str = '' + this.name + ' (' + str + ''; + + if (!this.required) { + str += ', optional'; + } + + str += ')'; + } else { + str = this.name + ' (' + JSON.stringify(this.obj) + ')'; + } + + if (typeof this.description !== 'undefined') { + str += ': ' + this.description; + } + + if (this['enum']) { + str += ' = [\'' + this['enum'].join('\' or \'') + '\']'; + } + + if (this.descr) { + str += ': ' + this.descr + ''; + } + + var options = ''; + var isArray = this.schema.type === 'array'; + var type; + + if (isArray) { + if (this.schema.items) { + type = this.schema.items.type; + } else { + type = ''; + } + } else { + type = this.schema.type; + } + + if (this.default) { + options += helpers.optionHtml('Default', this.default); + } + + switch (type) { + case 'string': + if (this.minLength) { + options += helpers.optionHtml('Min. Length', this.minLength); + } + + if (this.maxLength) { + options += helpers.optionHtml('Max. Length', this.maxLength); + } + + if (this.pattern) { + options += helpers.optionHtml('Reg. Exp.', this.pattern); + } + break; + case 'integer': + case 'number': + if (this.minimum) { + options += helpers.optionHtml('Min. Value', this.minimum); + } + + if (this.exclusiveMinimum) { + options += helpers.optionHtml('Exclusive Min.', 'true'); + } + + if (this.maximum) { + options += helpers.optionHtml('Max. Value', this.maximum); + } + + if (this.exclusiveMaximum) { + options += helpers.optionHtml('Exclusive Max.', 'true'); + } + + if (this.multipleOf) { + options += helpers.optionHtml('Multiple Of', this.multipleOf); + } + + break; + } + + if (isArray) { + if (this.minItems) { + options += helpers.optionHtml('Min. Items', this.minItems); + } + + if (this.maxItems) { + options += helpers.optionHtml('Max. Items', this.maxItems); + } + + if (this.uniqueItems) { + options += helpers.optionHtml('Unique Items', 'true'); + } + + if (this.collectionFormat) { + options += helpers.optionHtml('Coll. Format', this.collectionFormat); + } + } + + if (this['enum']) { + var enumString; + + if (type === 'number' || type === 'integer') { + enumString = this['enum'].join(', '); + } else { + enumString = '"' + this['enum'].join('", "') + '"'; + } + + options += helpers.optionHtml('Enum', enumString); + } + + if (options.length > 0) { + str = '' + str + '' + options + '
' + this.name + '
'; + } + + return str; +}; + +},{"../helpers":5,"./arrayModel":8}],10:[function(require,module,exports){ +'use strict'; + +var ArrayModel = require('./arrayModel'); +var helpers = require('../helpers'); +var Model = require('./model'); +var SwaggerHttp = require('../http'); + +var Operation = module.exports = function (parent, scheme, operationId, httpMethod, path, args, definitions, models, clientAuthorizations) { + var errors = []; + + parent = parent || {}; + args = args || {}; + + this.authorizations = args.security; + this.basePath = parent.basePath || '/'; + this.clientAuthorizations = clientAuthorizations; + this.consumes = args.consumes; + this.deprecated = args.deprecated; + this.description = args.description; + this.host = parent.host || 'localhost'; + this.method = (httpMethod || errors.push('Operation ' + operationId + ' is missing method.')); + this.models = models || {}; + this.nickname = (operationId || errors.push('Operations must have a nickname.')); + this.operation = args; + this.operations = {}; + this.parameters = args !== null ? (args.parameters || []) : {}; + this.parent = parent; + this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.')); + this.produces = args.produces; + this.responses = (args.responses || {}); + this.scheme = scheme || parent.scheme || 'http'; + this.schemes = parent.schemes; + this.security = args.security; + this.summary = args.summary || ''; + this.type = null; + this.useJQuery = parent.useJQuery; + + if (typeof this.deprecated === 'string') { + switch(this.deprecated.toLowerCase()) { + case 'true': case 'yes': case '1': { + this.deprecated = true; + break; + } + + case 'false': case 'no': case '0': case null: { + this.deprecated = false; + break; + } + + default: this.deprecated = Boolean(this.deprecated); + } + } + + var i, model; + + if (definitions) { + // add to global models + var key; + + for (key in this.definitions) { + model = new Model(key, definitions[key], this.models); + + if (model) { + this.models[key] = model; + } + } + } + for (i = 0; i < this.parameters.length; i++) { + var param = this.parameters[i]; + + if (param.type === 'array') { + param.isList = true; + param.allowMultiple = true; + } + + var innerType = this.getType(param); + + if (innerType && innerType.toString().toLowerCase() === 'boolean') { + param.allowableValues = {}; + param.isList = true; + param['enum'] = ['true', 'false']; + } + + if (typeof param['enum'] !== 'undefined') { + var id; + + param.allowableValues = {}; + param.allowableValues.values = []; + param.allowableValues.descriptiveValues = []; + + for (id = 0; id < param['enum'].length; id++) { + var value = param['enum'][id]; + var isDefault = (value === param.default) ? true : false; + + param.allowableValues.values.push(value); + param.allowableValues.descriptiveValues.push({value : value, isDefault: isDefault}); + } + } + + if (param.type === 'array') { + innerType = [innerType]; + + if (typeof param.allowableValues === 'undefined') { + // can't show as a list if no values to select from + delete param.isList; + delete param.allowMultiple; + } + } + + param.signature = this.getModelSignature(innerType, this.models).toString(); + param.sampleJSON = this.getModelSampleJSON(innerType, this.models); + param.responseClassSignature = param.signature; + } + + var defaultResponseCode, response, responses = this.responses; + + if (responses['200']) { + response = responses['200']; + defaultResponseCode = '200'; + } else if (responses['201']) { + response = responses['201']; + defaultResponseCode = '201'; + } else if (responses['202']) { + response = responses['202']; + defaultResponseCode = '202'; + } else if (responses['203']) { + response = responses['203']; + defaultResponseCode = '203'; + } else if (responses['204']) { + response = responses['204']; + defaultResponseCode = '204'; + } else if (responses['205']) { + response = responses['205']; + defaultResponseCode = '205'; + } else if (responses['206']) { + response = responses['206']; + defaultResponseCode = '206'; + } else if (responses['default']) { + response = responses['default']; + defaultResponseCode = 'default'; + } + + if (response && response.schema) { + var resolvedModel = this.resolveModel(response.schema, definitions); + + delete responses[defaultResponseCode]; + + if (resolvedModel) { + this.successResponse = {}; + this.successResponse[defaultResponseCode] = resolvedModel; + } else { + this.successResponse = {}; + this.successResponse[defaultResponseCode] = response.schema.type; + } + + this.type = response; + } + + if (errors.length > 0) { + if (this.resource && this.resource.api && this.resource.api.fail) { + this.resource.api.fail(errors); + } + } + + return this; +}; + +Operation.prototype.getType = function (param) { + var type = param.type; + var format = param.format; + var isArray = false; + var str; + + if (type === 'integer' && format === 'int32') { + str = 'integer'; + } else if (type === 'integer' && format === 'int64') { + str = 'long'; + } else if (type === 'integer') { + str = 'integer'; + } else if (type === 'string') { + if (format === 'date-time') { + str = 'date-time'; + } else if (format === 'date') { + str = 'date'; + } else { + str = 'string'; + } + } else if (type === 'number' && format === 'float') { + str = 'float'; + } else if (type === 'number' && format === 'double') { + str = 'double'; + } else if (type === 'number') { + str = 'double'; + } else if (type === 'boolean') { + str = 'boolean'; + } else if (type === 'array') { + isArray = true; + + if (param.items) { + str = this.getType(param.items); + } + } + + if (param.$ref) { + str = param.$ref; + } + + var schema = param.schema; + + if (schema) { + var ref = schema.$ref; + + if (ref) { + ref = helpers.simpleRef(ref); + + if (isArray) { + return [ ref ]; + } else { + return ref; + } + } else { + return this.getType(schema); + } + } + if (isArray) { + return [ str ]; + } else { + return str; + } +}; + +Operation.prototype.resolveModel = function (schema, definitions) { + if (typeof schema.$ref !== 'undefined') { + var ref = schema.$ref; + + if (ref.indexOf('#/definitions/') === 0) { + ref = ref.substring('#/definitions/'.length); + } + + if (definitions[ref]) { + return new Model(ref, definitions[ref], this.models); + } + } + + if (schema.type === 'array') { + return new ArrayModel(schema, this.models); + } else { + return null; + } +}; + +Operation.prototype.help = function (dontPrint) { + var out = this.nickname + ': ' + this.summary + '\n'; + + for (var i = 0; i < this.parameters.length; i++) { + var param = this.parameters[i]; + var typeInfo = param.signature; + + out += '\n * ' + param.name + ' (' + typeInfo + '): ' + param.description; + } + + if (typeof dontPrint === 'undefined') { + helpers.log(out); + } + + return out; +}; + +Operation.prototype.getModelSignature = function (type, definitions) { + var isPrimitive, listType; + + if (type instanceof Array) { + listType = true; + type = type[0]; + } else if (typeof type === 'undefined') { + type = 'undefined'; + } + + if (type === 'string') { + isPrimitive = true; + } else { + isPrimitive = (listType && definitions[listType]) || (definitions[type]) ? false : true; + } + + if (isPrimitive) { + if (listType) { + return 'Array[' + type + ']'; + } else { + return type.toString(); + } + } else { + if (listType) { + return 'Array[' + definitions[type].getMockSignature() + ']'; + } else { + return definitions[type].getMockSignature(); + } + } +}; + +Operation.prototype.supportHeaderParams = function () { + return true; +}; + +Operation.prototype.supportedSubmitMethods = function () { + return this.parent.supportedSubmitMethods; +}; + +Operation.prototype.getHeaderParams = function (args) { + var headers = this.setContentTypes(args, {}); + + for (var i = 0; i < this.parameters.length; i++) { + var param = this.parameters[i]; + + if (typeof args[param.name] !== 'undefined') { + if (param.in === 'header') { + var value = args[param.name]; + + if (Array.isArray(value)) { + value = value.toString(); + } + + headers[param.name] = value; + } + } + } + + return headers; +}; + +Operation.prototype.urlify = function (args) { + var formParams = {}; + var requestUrl = this.path; + var querystring = ''; // grab params from the args, build the querystring along the way + + for (var i = 0; i < this.parameters.length; i++) { + var param = this.parameters[i]; + + if (typeof args[param.name] !== 'undefined') { + if (param.in === 'path') { + var reg = new RegExp('\{' + param.name + '\}', 'gi'); + var value = args[param.name]; + + if (Array.isArray(value)) { + value = this.encodePathCollection(param.collectionFormat, param.name, value); + } else { + value = this.encodePathParam(value); + } + + requestUrl = requestUrl.replace(reg, value); + } else if (param.in === 'query' && typeof args[param.name] !== 'undefined') { + if (querystring === '') { + querystring += '?'; + } else { + querystring += '&'; + } + + if (typeof param.collectionFormat !== 'undefined') { + var qp = args[param.name]; + + if (Array.isArray(qp)) { + querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp); + } else { + querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]); + } + } else { + querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]); + } + } else if (param.in === 'formData') { + formParams[param.name] = args[param.name]; + } + } + } + + var url = this.scheme + '://' + this.host; + + if (this.basePath !== '/') { + url += this.basePath; + } + + return url + requestUrl + querystring; +}; + +Operation.prototype.getMissingParams = function (args) { + var missingParams = []; // check required params, track the ones that are missing + var i; + + for (i = 0; i < this.parameters.length; i++) { + var param = this.parameters[i]; + + if (param.required === true) { + if (typeof args[param.name] === 'undefined') { + missingParams = param.name; + } + } + } + + return missingParams; +}; + +Operation.prototype.getBody = function (headers, args, opts) { + var formParams = {}, body, key, value; + + for (var i = 0; i < this.parameters.length; i++) { + var param = this.parameters[i]; + + if (typeof args[param.name] !== 'undefined') { + if (param.in === 'body') { + body = args[param.name]; + } else if (param.in === 'formData') { + formParams[param.name] = args[param.name]; + } + } + } + + // handle form params + if (headers['Content-Type'] === 'application/x-www-form-urlencoded') { + var encoded = ''; + + for (key in formParams) { + value = formParams[key]; + + if (typeof value !== 'undefined') { + if (encoded !== '') { + encoded += '&'; + } + + encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value); + } + } + + body = encoded; + } else if (headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) { + if (opts.useJQuery) { + var bodyParam = new FormData(); + + bodyParam.type = 'formData'; + + for (key in formParams) { + value = args[key]; + + if (typeof value !== 'undefined') { + // required for jquery file upload + if (value.type === 'file' && value.value) { + delete headers['Content-Type']; + + bodyParam.append(key, value.value); + } else { + bodyParam.append(key, value); + } + } + } + + body = bodyParam; + } + } + + return body; +}; + +/** + * gets sample response for a single operation + **/ +Operation.prototype.getModelSampleJSON = function (type, models) { + var isPrimitive, listType, sampleJson; + + listType = (type instanceof Array); + isPrimitive = models[type] ? false : true; + sampleJson = isPrimitive ? void 0 : models[type].createJSONSample(); + + if (sampleJson) { + sampleJson = listType ? [sampleJson] : sampleJson; + + if (typeof sampleJson === 'string') { + return sampleJson; + } else if (typeof sampleJson === 'object') { + var t = sampleJson; + + if (sampleJson instanceof Array && sampleJson.length > 0) { + t = sampleJson[0]; + } + + if (t.nodeName) { + var xmlString = new XMLSerializer().serializeToString(t); + + return this.formatXml(xmlString); + } else { + return JSON.stringify(sampleJson, null, 2); + } + } else { + return sampleJson; + } + } +}; + +/** + * legacy binding + **/ +Operation.prototype.do = function (args, opts, callback, error, parent) { + return this.execute(args, opts, callback, error, parent); +}; + +/** + * executes an operation + **/ +Operation.prototype.execute = function (arg1, arg2, arg3, arg4, parent) { + var args = arg1 || {}; + var opts = {}, success, error; + + if (typeof arg2 === 'object') { + opts = arg2; + success = arg3; + error = arg4; + } + + if (typeof arg2 === 'function') { + success = arg2; + error = arg3; + } + + success = (success || helpers.log); + error = (error || helpers.log); + + if (opts.useJQuery) { + this.useJQuery = opts.useJQuery; + } + + var missingParams = this.getMissingParams(args); + + if (missingParams.length > 0) { + var message = 'missing required params: ' + missingParams; + + helpers.fail(message); + + return; + } + + var allHeaders = this.getHeaderParams(args); + var contentTypeHeaders = this.setContentTypes(args, opts); + var headers = {}, attrname; + + for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; } + for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; } + + var body = this.getBody(headers, args, opts); + var url = this.urlify(args); + + var obj = { + url: url, + method: this.method.toUpperCase(), + body: body, + useJQuery: this.useJQuery, + headers: headers, + on: { + response: function (response) { + return success(response, parent); + }, + error: function (response) { + return error(response, parent); + } + } + }; + + this.clientAuthorizations.apply(obj, this.operation.security); + + if (opts.mock === true) { + return obj; + } else { + new SwaggerHttp().execute(obj, opts); + } +}; + +Operation.prototype.setContentTypes = function (args, opts) { + // default type + var accepts = 'application/json'; + var allDefinedParams = this.parameters; + var body; + var consumes = args.parameterContentType || 'application/json'; + var definedFileParams = []; + var definedFormParams = []; + var headers = {}; + var i; + + // get params from the operation and set them in definedFileParams, definedFormParams, headers + for (i = 0; i < allDefinedParams.length; i++) { + var param = allDefinedParams[i]; + + if (param.in === 'formData') { + if (param.type === 'file') { + definedFileParams.push(param); + } else { + definedFormParams.push(param); + } + } else if (param.in === 'header' && opts) { + var key = param.name; + var headerValue = opts[param.name]; + + if (typeof opts[param.name] !== 'undefined') { + headers[key] = headerValue; + } + } else if (param.in === 'body' && typeof args[param.name] !== 'undefined') { + body = args[param.name]; + } + } + + // if there's a body, need to set the consumes header via requestContentType + if (body && (this.method === 'post' || this.method === 'put' || this.method === 'patch' || this.method === 'delete')) { + if (opts.requestContentType) { + consumes = opts.requestContentType; + } + } else { + // if any form params, content type must be set + if (definedFormParams.length > 0) { + if (opts.requestContentType) { // override if set + consumes = opts.requestContentType; + } else if (definedFileParams.length > 0) { // if a file, must be multipart/form-data + consumes = 'multipart/form-data'; + } else { // default to x-www-from-urlencoded + consumes = 'application/x-www-form-urlencoded'; + } + } else if (this.type === 'DELETE') { + body = '{}'; + } else if (this.type !== 'DELETE') { + consumes = null; + } + } + + if (consumes && this.consumes) { + if (this.consumes.indexOf(consumes) === -1) { + helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes)); + } + } + + if (opts.responseContentType) { + accepts = opts.responseContentType; + } else { + accepts = 'application/json'; + } + + if (accepts && this.produces) { + if (this.produces.indexOf(accepts) === -1) { + helpers.log('server can\'t produce ' + accepts); + } + } + + if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) { + headers['Content-Type'] = consumes; + } + + if (accepts) { + headers.Accept = accepts; + } + + return headers; +}; + +Operation.prototype.asCurl = function (args) { + var obj = this.execute(args, {mock: true}); + + this.clientAuthorizations.apply(obj); + + var results = []; + + results.push('-X ' + this.method.toUpperCase()); + + if (obj.headers) { + var key; + + for (key in obj.headers) { + results.push('--header "' + key + ': ' + obj.headers[key] + '"'); + } + } + + if (obj.body) { + var body; + + if (typeof obj.body === 'object') { + body = JSON.stringify(obj.body); + } else { + body = obj.body; + } + + results.push('-d "' + body.replace(/"/g, '\\"') + '"'); + } + + return 'curl ' + (results.join(' ')) + ' "' + obj.url + '"'; +}; + +Operation.prototype.encodePathCollection = function (type, name, value) { + var encoded = ''; + var i; + var separator = ''; + + if (type === 'ssv') { + separator = '%20'; + } else if (type === 'tsv') { + separator = '\\t'; + } else if (type === 'pipes') { + separator = '|'; + } else { + separator = ','; + } + + for (i = 0; i < value.length; i++) { + if (i === 0) { + encoded = this.encodeQueryParam(value[i]); + } else { + encoded += separator + this.encodeQueryParam(value[i]); + } + } + + return encoded; +}; + +Operation.prototype.encodeQueryCollection = function (type, name, value) { + var encoded = ''; + var i; + + if (type === 'default' || type === 'multi') { + for (i = 0; i < value.length; i++) { + if (i > 0) {encoded += '&';} + + encoded += this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]); + } + } else { + var separator = ''; + + if (type === 'csv') { + separator = ','; + } else if (type === 'ssv') { + separator = '%20'; + } else if (type === 'tsv') { + separator = '\\t'; + } else if (type === 'pipes') { + separator = '|'; + } else if (type === 'brackets') { + for (i = 0; i < value.length; i++) { + if (i !== 0) { + encoded += '&'; + } + + encoded += this.encodeQueryParam(name) + '[]=' + this.encodeQueryParam(value[i]); + } + } + + if (separator !== '') { + for (i = 0; i < value.length; i++) { + if (i === 0) { + encoded = this.encodeQueryParam(name) + '=' + this.encodeQueryParam(value[i]); + } else { + encoded += separator + this.encodeQueryParam(value[i]); + } + } + } + } + + return encoded; +}; + +Operation.prototype.encodeQueryParam = function (arg) { + return encodeURIComponent(arg); +}; + +/** + * TODO revisit, might not want to leave '/' + **/ +Operation.prototype.encodePathParam = function (pathParam) { + var encParts, parts, i, len; + + pathParam = pathParam.toString(); + + if (pathParam.indexOf('/') === -1) { + return encodeURIComponent(pathParam); + } else { + parts = pathParam.split('/'); + encParts = []; + + for (i = 0, len = parts.length; i < len; i++) { + encParts.push(encodeURIComponent(parts[i])); + } + + return encParts.join('/'); + } +}; + +},{"../helpers":5,"../http":6,"./arrayModel":8,"./model":9}],11:[function(require,module,exports){ +'use strict'; + +var OperationGroup = module.exports = function (tag, description, externalDocs, operation) { + this.tag = tag; + this.path = tag; + this.description = description; + this.externalDocs = externalDocs; + this.name = tag; + this.operation = operation; + this.operationsArray = []; +}; + +OperationGroup.prototype.sort = function () { + +}; + + +},{}],12:[function(require,module,exports){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') +var isArray = require('is-array') + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 // not used by this implementation + +var kMaxLength = 0x3fffffff +var rootParent = {} + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Note: + * + * - Implementation must support adding new properties to `Uint8Array` instances. + * Firefox 4-29 lacked support, fixed in Firefox 30+. + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + * + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will + * get the Object implementation, which is slower but will work correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = (function () { + try { + var buf = new ArrayBuffer(0) + var arr = new Uint8Array(buf) + arr.foo = function () { return 42 } + return arr.foo() === 42 && // typed array instances can be augmented + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } +})() + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (subject, encoding, noZero) { + if (!(this instanceof Buffer)) + return new Buffer(subject, encoding, noZero) + + var type = typeof subject + + // Find the length + var length + if (type === 'number') { + length = +subject + } else if (type === 'string') { + length = Buffer.byteLength(subject, encoding) + } else if (type === 'object' && subject !== null) { // assume object is array-like + if (subject.type === 'Buffer' && isArray(subject.data)) + subject = subject.data + length = +subject.length + } else { + throw new TypeError('must start with number, buffer, array or string') + } + + if (length > kMaxLength) + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength.toString(16) + ' bytes') + + if (length < 0) + length = 0 + else + length >>>= 0 // Coerce to uint32. + + var self = this + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Preferred: Return an augmented `Uint8Array` instance for best performance + /*eslint-disable consistent-this */ + self = Buffer._augment(new Uint8Array(length)) + /*eslint-enable consistent-this */ + } else { + // Fallback: Return THIS instance of Buffer (created by `new`) + self.length = length + self._isBuffer = true + } + + var i + if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') { + // Speed optimization -- use set if we're copying from a typed array + self._set(subject) + } else if (isArrayish(subject)) { + // Treat array-ish objects as a byte array + if (Buffer.isBuffer(subject)) { + for (i = 0; i < length; i++) + self[i] = subject.readUInt8(i) + } else { + for (i = 0; i < length; i++) + self[i] = ((subject[i] % 256) + 256) % 256 + } + } else if (type === 'string') { + self.write(subject, 0, encoding) + } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT && !noZero) { + for (i = 0; i < length; i++) { + self[i] = 0 + } + } + + if (length > 0 && length <= Buffer.poolSize) + self.parent = rootParent + + return self +} + +function SlowBuffer (subject, encoding, noZero) { + if (!(this instanceof SlowBuffer)) + return new SlowBuffer(subject, encoding, noZero) + + var buf = new Buffer(subject, encoding, noZero) + delete buf.parent + return buf +} + +Buffer.isBuffer = function (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) + throw new TypeError('Arguments must be Buffers') + + if (a === b) return 0 + + var x = a.length + var y = b.length + for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {} + if (i !== len) { + x = a[i] + y = b[i] + } + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'raw': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function (list, totalLength) { + if (!isArray(list)) throw new TypeError('Usage: Buffer.concat(list[, length])') + + if (list.length === 0) { + return new Buffer(0) + } else if (list.length === 1) { + return list[0] + } + + var i + if (totalLength === undefined) { + totalLength = 0 + for (i = 0; i < list.length; i++) { + totalLength += list[i].length + } + } + + var buf = new Buffer(totalLength) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +Buffer.byteLength = function (str, encoding) { + var ret + str = str + '' + switch (encoding || 'utf8') { + case 'ascii': + case 'binary': + case 'raw': + ret = str.length + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = str.length * 2 + break + case 'hex': + ret = str.length >>> 1 + break + case 'utf8': + case 'utf-8': + ret = utf8ToBytes(str).length + break + case 'base64': + ret = base64ToBytes(str).length + break + default: + ret = str.length + } + return ret +} + +// pre-set for values that may exist in the future +Buffer.prototype.length = undefined +Buffer.prototype.parent = undefined + +// toString(encoding, start=0, end=buffer.length) +Buffer.prototype.toString = function (encoding, start, end) { + var loweredCase = false + + start = start >>> 0 + end = end === undefined || end === Infinity ? this.length : end >>> 0 + + if (!encoding) encoding = 'utf8' + if (start < 0) start = 0 + if (end > this.length) end = this.length + if (end <= start) return '' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'binary': + return binarySlice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) + throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.equals = function (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) + str += ' ... ' + } + return '' +} + +Buffer.prototype.compare = function (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return 0 + return Buffer.compare(this, b) +} + +// `get` will be removed in Node 0.13+ +Buffer.prototype.get = function (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` will be removed in Node 0.13+ +Buffer.prototype.set = function (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new Error('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(byte)) throw new Error('Invalid hex string') + buf[offset + i] = byte + } + return i +} + +function utf8Write (buf, string, offset, length) { + var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) + return charsWritten +} + +function asciiWrite (buf, string, offset, length) { + var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length) + return charsWritten +} + +function binaryWrite (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length) + return charsWritten +} + +function utf16leWrite (buf, string, offset, length) { + var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) + return charsWritten +} + +Buffer.prototype.write = function (string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length + length = undefined + } + } else { // legacy + var swap = encoding + encoding = offset + offset = length + length = swap + } + + offset = Number(offset) || 0 + + if (length < 0 || offset < 0 || offset > this.length) + throw new RangeError('attempt to write outside buffer bounds') + + var remaining = this.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + encoding = String(encoding || 'utf8').toLowerCase() + + var ret + switch (encoding) { + case 'hex': + ret = hexWrite(this, string, offset, length) + break + case 'utf8': + case 'utf-8': + ret = utf8Write(this, string, offset, length) + break + case 'ascii': + ret = asciiWrite(this, string, offset, length) + break + case 'binary': + ret = binaryWrite(this, string, offset, length) + break + case 'base64': + ret = base64Write(this, string, offset, length) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = utf16leWrite(this, string, offset, length) + break + default: + throw new TypeError('Unknown encoding: ' + encoding) + } + return ret +} + +Buffer.prototype.toJSON = function () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + var res = '' + var tmp = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + if (buf[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) + tmp = '' + } else { + tmp += '%' + buf[i].toString(16) + } + } + + return res + decodeUtf8Char(tmp) +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function binarySlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; i++) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) + start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) + end = 0 + } else if (end > len) { + end = len + } + + if (end < start) + end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined, true) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + } + + if (newBuf.length) + newBuf.parent = this.parent || this + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) + throw new RangeError('offset is not uint') + if (offset + ext > length) + throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function (offset, byteLength, noAssert) { + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) + checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) + val += this[offset + i] * mul + + return val +} + +Buffer.prototype.readUIntBE = function (offset, byteLength, noAssert) { + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) + checkOffset(offset, byteLength, this.length) + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) + val += this[offset + --byteLength] * mul + + return val +} + +Buffer.prototype.readUInt8 = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function (offset, byteLength, noAssert) { + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) + checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) + val += this[offset + i] * mul + mul *= 0x80 + + if (val >= mul) + val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function (offset, byteLength, noAssert) { + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) + checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) + val += this[offset + --i] * mul + mul *= 0x80 + + if (val >= mul) + val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) + return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') +} + +Buffer.prototype.writeUIntLE = function (value, offset, byteLength, noAssert) { + value = +value + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) + checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) + this[offset + i] = (value / mul) >>> 0 & 0xFF + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function (value, offset, byteLength, noAssert) { + value = +value + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) + checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) + this[offset + i] = (value / mul) >>> 0 & 0xFF + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = value + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else objectWriteUInt16(this, value, offset, true) + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else objectWriteUInt16(this, value, offset, false) + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = value + } else objectWriteUInt32(this, value, offset, true) + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else objectWriteUInt32(this, value, offset, false) + return offset + 4 +} + +Buffer.prototype.writeIntLE = function (value, offset, byteLength, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) { + checkInt(this, + value, + offset, + byteLength, + Math.pow(2, 8 * byteLength - 1) - 1, + -Math.pow(2, 8 * byteLength - 1)) + } + + var i = 0 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function (value, offset, byteLength, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) { + checkInt(this, + value, + offset, + byteLength, + Math.pow(2, 8 * byteLength - 1) - 1, + -Math.pow(2, 8 * byteLength - 1)) + } + + var i = byteLength - 1 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = value + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else objectWriteUInt16(this, value, offset, true) + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else objectWriteUInt16(this, value, offset, false) + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else objectWriteUInt32(this, value, offset, true) + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else objectWriteUInt32(this, value, offset, false) + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') + if (offset < 0) throw new RangeError('index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function (target, target_start, start, end) { + var self = this // source + + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (target_start >= target.length) target_start = target.length + if (!target_start) target_start = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || self.length === 0) return 0 + + // Fatal error conditions + if (target_start < 0) + throw new RangeError('targetStart out of bounds') + if (start < 0 || start >= self.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) + end = this.length + if (target.length - target_start < end - start) + end = target.length - target_start + start + + var len = end - start + + if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < len; i++) { + target[i + target_start] = this[i + start] + } + } else { + target._set(this.subarray(start, start + len), target_start) + } + + return len +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (end < start) throw new RangeError('end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') + if (end < 0 || end > this.length) throw new RangeError('end out of bounds') + + var i + if (typeof value === 'number') { + for (i = start; i < end; i++) { + this[i] = value + } + } else { + var bytes = utf8ToBytes(value.toString()) + var len = bytes.length + for (i = start; i < end; i++) { + this[i] = bytes[i % len] + } + } + + return this +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer.TYPED_ARRAY_SUPPORT) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) { + buf[i] = this[i] + } + return buf.buffer + } + } else { + throw new TypeError('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function (arr) { + arr.constructor = Buffer + arr._isBuffer = true + + // save reference to original Uint8Array get/set methods before overwriting + arr._get = arr.get + arr._set = arr.set + + // deprecated, will be removed in node 0.13+ + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.equals = BP.equals + arr.compare = BP.compare + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUIntLE = BP.readUIntLE + arr.readUIntBE = BP.readUIntBE + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readIntLE = BP.readIntLE + arr.readIntBE = BP.readIntBE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUIntLE = BP.writeUIntLE + arr.writeUIntBE = BP.writeUIntBE + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeIntLE = BP.writeIntLE + arr.writeIntBE = BP.writeIntBE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function isArrayish (subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number' +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + var i = 0 + + for (; i < length; i++) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (leadSurrogate) { + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } else { + // valid surrogate pair + codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 + leadSurrogate = null + } + } else { + // no lead yet + + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else { + // valid lead + leadSurrogate = codePoint + continue + } + } + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = null + } + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x200000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) + break + dst[i + offset] = src[i] + } + return i +} + +function decodeUtf8Char (str) { + try { + return decodeURIComponent(str) + } catch (err) { + return String.fromCharCode(0xFFFD) // UTF 8 invalid char + } +} + +},{"base64-js":13,"ieee754":14,"is-array":15}],13:[function(require,module,exports){ +var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +;(function (exports) { + 'use strict'; + + var Arr = (typeof Uint8Array !== 'undefined') + ? Uint8Array + : Array + + var PLUS = '+'.charCodeAt(0) + var SLASH = '/'.charCodeAt(0) + var NUMBER = '0'.charCodeAt(0) + var LOWER = 'a'.charCodeAt(0) + var UPPER = 'A'.charCodeAt(0) + var PLUS_URL_SAFE = '-'.charCodeAt(0) + var SLASH_URL_SAFE = '_'.charCodeAt(0) + + function decode (elt) { + var code = elt.charCodeAt(0) + if (code === PLUS || + code === PLUS_URL_SAFE) + return 62 // '+' + if (code === SLASH || + code === SLASH_URL_SAFE) + return 63 // '/' + if (code < NUMBER) + return -1 //no match + if (code < NUMBER + 10) + return code - NUMBER + 26 + 26 + if (code < UPPER + 26) + return code - UPPER + if (code < LOWER + 26) + return code - LOWER + 26 + } + + function b64ToByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + + if (b64.length % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + var len = b64.length + placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(b64.length * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length + + var L = 0 + + function push (v) { + arr[L++] = v + } + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) + push((tmp & 0xFF0000) >> 16) + push((tmp & 0xFF00) >> 8) + push(tmp & 0xFF) + } + + if (placeHolders === 2) { + tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) + push(tmp & 0xFF) + } else if (placeHolders === 1) { + tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) + push((tmp >> 8) & 0xFF) + push(tmp & 0xFF) + } + + return arr + } + + function uint8ToBase64 (uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length + + function encode (num) { + return lookup.charAt(num) + } + + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output += tripletToBase64(temp) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1] + output += encode(temp >> 2) + output += encode((temp << 4) & 0x3F) + output += '==' + break + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) + output += encode(temp >> 10) + output += encode((temp >> 4) & 0x3F) + output += encode((temp << 2) & 0x3F) + output += '=' + break + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +},{}],14:[function(require,module,exports){ +exports.read = function(buffer, offset, isLE, mLen, nBytes) { + var e, m, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isLE ? (nBytes - 1) : 0, + d = isLE ? -1 : 1, + s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; + +exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isLE ? 0 : (nBytes - 1), + d = isLE ? 1 : -1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); + + buffer[offset + i - d] |= s * 128; +}; + +},{}],15:[function(require,module,exports){ + +/** + * isArray + */ + +var isArray = Array.isArray; + +/** + * toString + */ + +var str = Object.prototype.toString; + +/** + * Whether or not the given `val` + * is an array. + * + * example: + * + * isArray([]); + * // > true + * isArray(arguments); + * // > false + * isArray(''); + * // > false + * + * @param {mixed} val + * @return {bool} + */ + +module.exports = isArray || function (val) { + return !! val && '[object Array]' == str.call(val); +}; + +},{}],16:[function(require,module,exports){ +(function (Buffer){ +(function () { + "use strict"; + + function btoa(str) { + var buffer + ; + + if (str instanceof Buffer) { + buffer = str; + } else { + buffer = new Buffer(str.toString(), 'binary'); + } + + return buffer.toString('base64'); + } + + module.exports = btoa; +}()); + +}).call(this,require("buffer").Buffer) + +},{"buffer":12}],17:[function(require,module,exports){ +/* jshint node: true */ +(function () { + "use strict"; + + function CookieAccessInfo(domain, path, secure, script) { + if (this instanceof CookieAccessInfo) { + this.domain = domain || undefined; + this.path = path || "/"; + this.secure = !!secure; + this.script = !!script; + return this; + } + return new CookieAccessInfo(domain, path, secure, script); + } + exports.CookieAccessInfo = CookieAccessInfo; + + function Cookie(cookiestr, request_domain, request_path) { + if (cookiestr instanceof Cookie) { + return cookiestr; + } + if (this instanceof Cookie) { + this.name = null; + this.value = null; + this.expiration_date = Infinity; + this.path = String(request_path || "/"); + this.explicit_path = false; + this.domain = request_domain || null; + this.explicit_domain = false; + this.secure = false; //how to define default? + this.noscript = false; //httponly + if (cookiestr) { + this.parse(cookiestr, request_domain, request_path); + } + return this; + } + return new Cookie(cookiestr); + } + exports.Cookie = Cookie; + + Cookie.prototype.toString = function toString() { + var str = [this.name + "=" + this.value]; + if (this.expiration_date !== Infinity) { + str.push("expires=" + (new Date(this.expiration_date)).toGMTString()); + } + if (this.domain) { + str.push("domain=" + this.domain); + } + if (this.path) { + str.push("path=" + this.path); + } + if (this.secure) { + str.push("secure"); + } + if (this.noscript) { + str.push("httponly"); + } + return str.join("; "); + }; + + Cookie.prototype.toValueString = function toValueString() { + return this.name + "=" + this.value; + }; + + var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g; + Cookie.prototype.parse = function parse(str, request_domain, request_path) { + if (this instanceof Cookie) { + var parts = str.split(";").filter(function (value) { + return !!value; + }), + pair = parts[0].match(/([^=]+)=([\s\S]*)/), + key = pair[1], + value = pair[2], + i; + this.name = key; + this.value = value; + + for (i = 1; i < parts.length; i += 1) { + pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/); + key = pair[1].trim().toLowerCase(); + value = pair[2]; + switch (key) { + case "httponly": + this.noscript = true; + break; + case "expires": + this.expiration_date = value ? + Number(Date.parse(value)) : + Infinity; + break; + case "path": + this.path = value ? + value.trim() : + ""; + this.explicit_path = true; + break; + case "domain": + this.domain = value ? + value.trim() : + ""; + this.explicit_domain = !!this.domain; + break; + case "secure": + this.secure = true; + break; + } + } + + if (!this.explicit_path) { + this.path = request_path || "/"; + } + if (!this.explicit_domain) { + this.domain = request_domain; + } + + return this; + } + return new Cookie().parse(str, request_domain, request_path); + }; + + Cookie.prototype.matches = function matches(access_info) { + if (this.noscript && access_info.script || + this.secure && !access_info.secure || + !this.collidesWith(access_info)) { + return false; + } + return true; + }; + + Cookie.prototype.collidesWith = function collidesWith(access_info) { + if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) { + return false; + } + if (this.path && access_info.path.indexOf(this.path) !== 0) { + return false; + } + if (!this.explicit_path) { + if (this.path !== access_info.path) { + return false; + } + } + var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,''); + var cookie_domain = this.domain && this.domain.replace(/^[\.]/,''); + if (cookie_domain === access_domain) { + return true; + } + if (cookie_domain) { + if (!this.explicit_domain) { + return false; // we already checked if the domains were exactly the same + } + var wildcard = access_domain.indexOf(cookie_domain); + if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) { + return false; + } + return true; + } + return true; + }; + + function CookieJar() { + var cookies, cookies_list, collidable_cookie; + if (this instanceof CookieJar) { + cookies = Object.create(null); //name: [Cookie] + + this.setCookie = function setCookie(cookie, request_domain, request_path) { + var remove, i; + cookie = new Cookie(cookie, request_domain, request_path); + //Delete the cookie if the set is past the current time + remove = cookie.expiration_date <= Date.now(); + if (cookies[cookie.name] !== undefined) { + cookies_list = cookies[cookie.name]; + for (i = 0; i < cookies_list.length; i += 1) { + collidable_cookie = cookies_list[i]; + if (collidable_cookie.collidesWith(cookie)) { + if (remove) { + cookies_list.splice(i, 1); + if (cookies_list.length === 0) { + delete cookies[cookie.name]; + } + return false; + } + cookies_list[i] = cookie; + return cookie; + } + } + if (remove) { + return false; + } + cookies_list.push(cookie); + return cookie; + } + if (remove) { + return false; + } + cookies[cookie.name] = [cookie]; + return cookies[cookie.name]; + }; + //returns a cookie + this.getCookie = function getCookie(cookie_name, access_info) { + var cookie, i; + cookies_list = cookies[cookie_name]; + if (!cookies_list) { + return; + } + for (i = 0; i < cookies_list.length; i += 1) { + cookie = cookies_list[i]; + if (cookie.expiration_date <= Date.now()) { + if (cookies_list.length === 0) { + delete cookies[cookie.name]; + } + continue; + } + if (cookie.matches(access_info)) { + return cookie; + } + } + }; + //returns a list of cookies + this.getCookies = function getCookies(access_info) { + var matches = [], cookie_name, cookie; + for (cookie_name in cookies) { + cookie = this.getCookie(cookie_name, access_info); + if (cookie) { + matches.push(cookie); + } + } + matches.toString = function toString() { + return matches.join(":"); + }; + matches.toValueString = function toValueString() { + return matches.map(function (c) { + return c.toValueString(); + }).join(';'); + }; + return matches; + }; + + return this; + } + return new CookieJar(); + } + exports.CookieJar = CookieJar; + + //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned. + CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) { + cookies = Array.isArray(cookies) ? + cookies : + cookies.split(cookie_str_splitter); + var successful = [], + i, + cookie; + cookies = cookies.map(Cookie); + for (i = 0; i < cookies.length; i += 1) { + cookie = cookies[i]; + if (this.setCookie(cookie, request_domain, request_path)) { + successful.push(cookie); + } + } + return successful; + }; +}()); + +},{}],18:[function(require,module,exports){ +/*! + * jQuery JavaScript Library v2.1.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-12-18T15:11Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Support: Firefox 18+ +// Can't be in strict mode, several libs including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// + +var arr = []; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + version = "2.1.3", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // 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 just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // 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 ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + 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: arr.sort, + splice: arr.splice +}; + +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; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // 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 ( i === length ) { + 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({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + }, + + isPlainObject: function( obj ) { + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + // Support: Android<4.0, iOS<6 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf("use strict") === 1 ) { + script = document.createElement("script"); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE9-11+ + // 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.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return 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 ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + 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 + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, 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 || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.0-pre + * http://sizzlejs.com/ + * + * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-12-16 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + nodeType = context.nodeType; + + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + if ( !seed && documentIsHTML ) { + + // Try to shortcut find operations when possible (e.g., not under DocumentFragment) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType !== 1 && selector; + + // 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 + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = 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).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + parent = doc.defaultView; + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Support tests + ---------------------------------------------------------------------- */ + documentIsHTML = !isXML( doc ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "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; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + len = this.length, + ret = [], + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[0] === "<" && selector[ 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 = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Support: Blackberry 4.6 + // gEBID returns nodes no longer in the document (#6963) + if ( elem && elem.parentNode ) { + // 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: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; + }, + + sibling: function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter(function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} + return cur; +} + +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 sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "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 elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.unique( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // Add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // If we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // 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 ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // 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.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * The ready event handler and self cleanup method + */ +function completed() { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + jQuery.ready(); +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // We once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[0], key ) : emptyGet; +}; + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( owner ) { + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + +function Data() { + // Support: Android<4, + // Old WebKit does not have Object.preventExtensions/freeze method, + // return new empty object instead with no [[set]] accessor + Object.defineProperty( this.cache = {}, 0, { + get: function() { + return {}; + } + }); + + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; +Data.accepts = jQuery.acceptData; + +Data.prototype = { + key: function( owner ) { + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return the key for a frozen object. + if ( !Data.accepts( owner ) ) { + return 0; + } + + var descriptor = {}, + // Check if the owner object already has a cache key + unlock = owner[ this.expando ]; + + // If not, create one + if ( !unlock ) { + unlock = Data.uid++; + + // Secure it in a non-enumerable, non-writable property + try { + descriptor[ this.expando ] = { value: unlock }; + Object.defineProperties( owner, descriptor ); + + // Support: Android<4 + // Fallback to a less secure definition + } catch ( e ) { + descriptor[ this.expando ] = unlock; + jQuery.extend( owner, descriptor ); + } + } + + // Ensure the cache object + if ( !this.cache[ unlock ] ) { + this.cache[ unlock ] = {}; + } + + return unlock; + }, + set: function( owner, data, value ) { + var prop, + // There may be an unlock assigned to this node, + // if there is no entry for this "owner", create one inline + // and set the unlock as though an owner entry had always existed + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + // Fresh assignments by object are shallow copied + if ( jQuery.isEmptyObject( cache ) ) { + jQuery.extend( this.cache[ unlock ], data ); + // Otherwise, copy the properties one-by-one to the cache object + } else { + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + } + return cache; + }, + get: function( owner, key ) { + // Either a valid cache is found, or will be created. + // New caches will be created and the unlock returned, + // allowing direct access to the newly created + // empty data object. A valid owner object must be provided. + var cache = this.cache[ this.key( owner ) ]; + + return key === undefined ? + cache : cache[ key ]; + }, + access: function( owner, key, value ) { + var stored; + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ((key && typeof key === "string") && value === undefined) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase(key) ); + } + + // [*]When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + if ( key === undefined ) { + this.cache[ unlock ] = {}; + + } else { + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + }, + hasData: function( owner ) { + return !jQuery.isEmptyObject( + this.cache[ owner[ this.expando ] ] || {} + ); + }, + discard: function( owner ) { + if ( owner[ this.expando ] ) { + delete this.cache[ owner[ this.expando ] ]; + } + } +}; +var data_priv = new Data(); + +var data_user = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + data_user.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend({ + hasData: function( elem ) { + return data_user.hasData( elem ) || data_priv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return data_user.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + data_user.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to data_priv methods, these can be deprecated. + _data: function( elem, name, data ) { + return data_priv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + data_priv.remove( elem, name ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = data_user.get( elem ); + + if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + data_priv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + data_user.set( this, key ); + }); + } + + return access( this, function( value ) { + var data, + camelKey = jQuery.camelCase( key ); + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + // Attempt to get data from the cache + // with the key as-is + data = data_user.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to get data from the cache + // with the key camelized + data = data_user.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each(function() { + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = data_user.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + data_user.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf("-") !== -1 && data !== undefined ) { + data_user.set( this, key, value ); + } + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + data_user.remove( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = data_priv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = data_priv.access( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return data_priv.get( elem, key ) || data_priv.access( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + data_priv.remove( elem, [ type + "queue", key ] ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + 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, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = data_priv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Safari<=5.1 + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari<=5.1, Android<4.2 + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<=11+ + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +})(); +var strundefined = typeof undefined; + + + +support.focusinBubbles = "onfocusin" in window; + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = 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 !== strundefined && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.hasData( elem ) && data_priv.get( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + data_priv.remove( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome<28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // 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. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } +}; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + 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.defaultPrevented === undefined && + // Support: Android<4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = 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 = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && e.preventDefault ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && e.stopPropagation ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// Support: Chrome 15+ +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// Support: Firefox, Chrome, Safari +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + data_priv.remove( doc, fix ); + + } else { + data_priv.access( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +var + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + + // Support: IE9 + option: [ 1, "" ], + + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] + }; + +// Support: IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: 1.x compatibility +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute("type"); + } + + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + data_priv.set( + elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) + ); + } +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( data_priv.hasData( src ) ) { + pdataOld = data_priv.access( src ); + pdataCur = data_priv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( data_user.hasData( src ) ) { + udataOld = data_user.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + data_user.set( dest, udataCur ); + } +} + +function getAll( context, tag ) { + var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : + context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + // Support: QtWebKit, PhantomJS + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: QtWebKit, PhantomJS + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; + }, + + cleanData: function( elems ) { + var data, elem, type, key, + special = jQuery.event.special, + i = 0; + + for ( ; (elem = elems[ i ]) !== undefined; i++ ) { + if ( jQuery.acceptData( elem ) ) { + key = elem[ data_priv.expando ]; + + if ( key && (data = data_priv.cache[ key ]) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + if ( data_priv.cache[ key ] ) { + // Discard any remaining `private` data + delete data_priv.cache[ key ]; + } + } + } + // Discard any remaining `user` data + delete data_user.cache[ elem[ data_user.expando ] ]; + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each(function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + }); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: QtWebKit + // .get() because push.apply(_, arraylike) throws + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optimization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "