!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.swaggerAngularClient=e()}}(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o parseInt(dataType.maximum, 10)){ return new errorTypes.NumberTooLargeError(candidate, dataType.maximum); } } exports.validateNumber = validateNumber; function validateBoolean(candidate){ if(!(typeof candidate === 'boolean' || candidate instanceof Boolean)){ return new errorTypes.NotABooleanError(candidate, typeof candidate); } } exports.validateBoolean = validateBoolean; function validateVoid(candidate){ if(candidate != null){ return new errorTypes.NotVoidError(candidate, typeof candidate); } } exports.validateVoid = validateVoid; function validateFile(){ // Not sure how to check this, since anything could qualify as 'File'. } exports.validateFile = validateFile; function validateString(candidate, dataType){ if(typeof candidate !== 'string' && !(candidate instanceof String)){ return new errorTypes.NotAStringError(candidate, typeof candidate); } if('enum' in dataType){ if(dataType.enum.indexOf(candidate) === -1) { return new errorTypes.StringNotInEnumError(candidate, dataType.enum); } } } exports.validateString = validateString; },{"./errorTypes":1}],8:[function(_dereq_,module,exports){ 'use strict'; var MissingAuthorizationError = _dereq_('./errorTypes').MissingAuthorizationError; module.exports = function applyAuthData(operation, authData, request){ var authMap = operation.authorizations; if(!authMap) authMap = operation.apiObject.apiDeclaration.authorizations; if(!authMap) return; var authNames = Object.keys(authMap).filter(function(authName){ // Currently unable to handle oauth2 return authMap[authName].type !== 'oauth2'; }); if(authNames.length === 0) return; if(authNames.length === 1){ var authName = authNames[0]; var auth = authMap[authName]; if(!authData) throw new MissingAuthorizationError(authName, auth); // Unpack nested authData for single auth ops: { apiKey: '123' } -> '123' if(authData[authName]) authData = authData[authName]; if(auth.type === 'apiKey'){ applyApiKey(auth, authName, authData, request); } else if(auth.type === 'basicAuth') { applyBasicAuth(auth, authName, authData.username, authData.password, request); } } else { var hasAuth = authNames.some(function(authName){ var auth = authMap[authName]; var data = authData[authName]; if(!data) return false; if(auth.type === 'apiKey'){ applyApiKey(auth, authName, data, request); } else if(auth.type === 'basicAuth'){ applyBasicAuth(auth, authName, data.username, data.password, request); } return true; }); if(!hasAuth){ throw new MissingAuthorizationError(authNames.join(', '), authMap); } } }; function applyApiKey(auth, authName, apiKey, request){ if(!apiKey) throw new MissingAuthorizationError(authName, auth); if(auth.passAs === 'header'){ request.headers[auth.keyname] = apiKey; } else if(auth.passAs === 'query'){ var url = request.url; var queryParam = auth.keyname + '=' + encodeURIComponent(apiKey); if(url.indexOf('?') === -1){ url += '?' + queryParam; } else { url = url.replace('?', '?' + queryParam + '&'); } request.url = url; } } function applyBasicAuth(auth, authName, username, password, request){ if(!username || !password) throw new MissingAuthorizationError(authName, auth); var url = request.url; // Only add basic auth once if(url.indexOf('@') === -1){ url = url.replace('://', '://' + username + ':' + password + '@'); } request.url = url; } },{"./errorTypes":11}],9:[function(_dereq_,module,exports){ 'use strict'; var createOperationHandler = _dereq_('./createOperationHandler'); function createClient(schema, requestHandler){ var api = {}, apiAuthData, authMethodName = 'auth'; schema = processSchema(schema); // If the 'auth' key is used for any resource or operation, we'll use // 'authorization' instead for the auth methods var authIsInUse = schema.apis.some(function(resourceObject){ return resourceObject.apiDeclaration.apis.some(function(apiObject){ var resourceApiName = getApiName(apiObject.apiDeclaration.resourcePath || apiObject.path); if(resourceApiName === 'auth') return true; return apiObject.operations.some(function(operation){ return operation.nickname === 'auth'; }); }); }); if(authIsInUse) authMethodName = 'authorization'; api[authMethodName] = function(){ if(arguments.length === 0) return apiAuthData; apiAuthData = processApiAuthArgs(arguments); }; schema.apis.forEach(function(resourceObject){ var resourceName, resourceApi, resourceAuthData; if(resourceObject.apiDeclaration.resourcePath){ resourceName = getApiName(resourceObject.apiDeclaration.resourcePath); resourceApi = api[resourceName] = {}; resourceApi[authMethodName] = function(){ if(arguments.length === 0) return resourceAuthData; resourceAuthData = processApiAuthArgs(arguments); }; } resourceObject.apiDeclaration.apis.forEach(function(apiObject){ var apiObjectName = resourceName, apiObjectApi = resourceApi, apiObjectAuthData; if(!apiObjectName){ apiObjectName = getApiName(apiObject.path); apiObjectApi = api[apiObjectName] = {}; apiObjectApi[authMethodName] = function(){ if(arguments.length === 0) return apiObjectAuthData; apiObjectAuthData = processApiAuthArgs(arguments); }; } apiObject.operations.forEach(function(operation){ var operationHandlerName = operation.nickname, operationAuthData, operationHandler; function getAuthData(){ return operationAuthData || apiObjectAuthData || resourceAuthData || apiAuthData; } operationHandler = createOperationHandler(operation, getAuthData, requestHandler); operationHandler[authMethodName] = function(){ if(arguments.length === 0) return operationAuthData; operationAuthData = processApiAuthArgs(arguments); }; apiObjectApi[operationHandlerName] = operationHandler; }); }); }); return api; } module.exports = createClient; function processApiAuthArgs(args){ // for basic auth, allow calls with two args (username, password) if(typeof args[0] === 'string' && typeof args[1] === 'string') { return { username: args[0], password: args[1] }; } else { return args[0]; } } // Helpper method which assings back pointer to object parents and returns // the api objects within the given schema. function processSchema(schema){ schema.apis.forEach(function(resourceObject){ resourceObject.resourceListing = schema; resourceObject.apiDeclaration.apis.forEach(function(apiObject){ apiObject.resourceObject = resourceObject; apiObject.apiDeclaration = resourceObject.apiDeclaration; apiObject.operations.forEach(function(operation){ operation.apiObject = apiObject; operation.parameters.forEach(function(parameter){ parameter.operation = operation; }); }); }); }); return schema; } // Takes a path and returns a JavaScript-friendly variable name function getApiName(name){ // String non-word characters name = name.replace(/\W/g, '/'); // Turn paths which look/like/this to lookLikeThis name = name.replace(/(\w)\/(\w)/g, function(match, p1, p2){ return p1 + p2.toUpperCase(); }); name = name.replace(/\//g, ''); return name; } },{"./createOperationHandler":10}],10:[function(_dereq_,module,exports){ 'use strict'; var getRequestHeaders = _dereq_('./getRequestHeaders'), getRequestUrl = _dereq_('./getRequestUrl'), getRequestBody = _dereq_('./getRequestBody'), applyAuthData = _dereq_('./applyAuthData'), errorTypes = _dereq_('./errorTypes'), swaggerValidate = _dereq_('swagger-validate'); var allErrorTypes = {}; Object.keys(swaggerValidate.errors).forEach(function(errorName){ allErrorTypes[errorName] = swaggerValidate.errors[errorName]; }); Object.keys(errorTypes).forEach(function(errorName){ allErrorTypes[errorName] = errorTypes[errorName]; }); function createOperationHandler(operation, getAuthData, requestHandler){ function Request(data, options){ this.method = operation.method; this.operation = operation; this.errorTypes = allErrorTypes; this.data = data; this.options = options; } var operationHandler = function(data, options){ var error, request; options = options || {}; if(data == null) data = {}; // if a function is passed in as options, assume it's a callback function // for convenience if(typeof options === 'function'){ options.callback = options; } try{ data = prune(data); data = singleParamConvenienceProcessor(operation, data); data = removeUnknownParams(operation, data); error = swaggerValidate.operation(data, operation, operation.apiObject.apiDeclaration.models); request = new Request(data, options); // If we know there is an error, don't attempt to craft the request params. // The request param generators assume valid data to work properly. if(!error){ request.url = getRequestUrl(operation, data); request.headers = getRequestHeaders(operation, data, options); request.body = getRequestBody(operation, data, request.headers); applyAuthData(operation, getAuthData(), request); } } catch(e){ error = e; } return requestHandler(error, request); }; // Useful for instanceof checks operationHandler.Request = Request; operationHandler.errorTypes = allErrorTypes; // Useful for reflection operationHandler.operation = operation; // Can be used to preemptively validate without action operationHandler.validate = function(data){ return swaggerValidate.operation(data, operation, operation.apiObject.apiDeclaration.models); }; return operationHandler; } module.exports = createOperationHandler; function noop(){} createOperationHandler.logger = { debug: noop, info: noop, warn: noop, error: noop }; // Stringify and parse the data to clean up undefined, and non-scalar properties function prune(data){ return JSON.parse(JSON.stringify(data)); } // Enables data to be passed directly for single param operations. function singleParamConvenienceProcessor(operation, data){ // If there are more than one params, bail var requiredParams = operation.parameters.filter(function(param){ return param.required; }); // If there are more than one required params, or if there is no required param // and there are many optional params, bail if(requiredParams.length > 1) return data; if(requiredParams.length !== 1 && operation.parameters.length !== 1) return data; var param = requiredParams[0] || operation.parameters[0]; // If the param is already defined explicitly, bail if(typeof data === 'object' && data[param.name] !== undefined) return data; var models = operation.apiObject.apiDeclaration.models; // If the data passed is is not valid for the param data type, bail var error; try { error = swaggerValidate.dataType(data, param, models); } catch(e){ return data; } // If the data passed is a valid param data type, bail if(!error){ var wrapper = {}; wrapper[param.name] = data; return wrapper; } else { return data; } } function removeUnknownParams(operation, data){ if(!data || typeof data !== 'object') return data; var paramNames = {}; operation.parameters.forEach(function(param){ paramNames[param.name] = true; }); var unknownKeys = Object.keys(data).filter(function(key){ return !(key in paramNames); }); createOperationHandler.logger.warn('Unknown parameters removed from request:', unknownKeys.join(', ')); unknownKeys.forEach(function(key){ delete data[key]; }); return data; } },{"./applyAuthData":8,"./errorTypes":11,"./getRequestBody":12,"./getRequestHeaders":13,"./getRequestUrl":14,"swagger-validate":2}],11:[function(_dereq_,module,exports){ 'use strict'; function InvalidRequestError(message){ this.name = 'InvalidRequestError'; this.message = message || 'Invalid request'; } InvalidRequestError.prototype = Object.create(Error.prototype); InvalidRequestError.prototype.constructor = InvalidRequestError; exports.InvalidRequestError = InvalidRequestError; function MissingAuthorizationError(authName, auth){ this.name = 'MissingAuthorizationError'; this.message = 'No data found for authorization: ' + authName; this.authorization = auth; } MissingAuthorizationError.prototype = Object.create(InvalidRequestError.prototype); MissingAuthorizationError.prototype.constructor = MissingAuthorizationError; exports.MissingAuthorizationError = MissingAuthorizationError; function MissingPathParamsError(pathParams){ this.name = 'MissingPathParamsError'; this.message = 'Missing the following required path parameters: ' + pathParams.join(''); } MissingPathParamsError.prototype = Object.create(InvalidRequestError.prototype); MissingPathParamsError.prototype.constructor = MissingPathParamsError; exports.MissingPathParamsError = MissingPathParamsError; function ContentTypeNotSupportedError(contentType, operation){ var apiDeclaration = operation.apiObject.apiDeclaration; var consumes = operation.consumes || apiDeclaration.consumes || []; this.name = 'ContentTypeNotSupportedError'; this.message = 'Operation [' + operation.nickname + '] does not accept ' + contentType + '. It supports: ' + consumes.join(', '); } ContentTypeNotSupportedError.prototype = Object.create(InvalidRequestError.prototype); ContentTypeNotSupportedError.prototype.constructor = ContentTypeNotSupportedError; exports.ContentTypeNotSupportedError = ContentTypeNotSupportedError; function AcceptsNotSupportedError(accepts, operation){ var apiDeclaration = operation.apiObject.apiDeclaration; var produces = operation.produces || apiDeclaration.produces || []; this.name = 'AcceptsNotSupportedError'; this.message = 'Operation [' + operation.nickname + '] does not produce ' + accepts + '. It supports: ' + produces.join(', '); } AcceptsNotSupportedError.prototype = Object.create(InvalidRequestError.prototype); AcceptsNotSupportedError.prototype.constructor = AcceptsNotSupportedError; exports.AcceptsNotSupportedError = AcceptsNotSupportedError; function OperationValidationError(operation, errors){ this.name = 'OperationValidationError'; this.message = operation.nickname + ' failed validation: \n\t' + errors.join('\n\t'); } OperationValidationError.prototype = Object.create(InvalidRequestError.prototype); OperationValidationError.prototype.constructor = OperationValidationError; exports.OperationValidationError = OperationValidationError; function ParameterValidationError(parameter, errors){ this.name = 'ParameterValidationError'; this.message = parameter.name + ' failed validation: \n\t' + errors.join('\n\t'); } ParameterValidationError.prototype = Object.create(InvalidRequestError.prototype); ParameterValidationError.prototype.constructor = ParameterValidationError; exports.ParameterValidationError = ParameterValidationError; function DataTypeValidationError(message){ this.name = 'DataTypeValidationError'; this.message = message || 'Invalid data type'; } DataTypeValidationError.prototype = Object.create(Error.prototype); DataTypeValidationError.prototype.constructor = DataTypeValidationError; exports.DataTypeValidationError = DataTypeValidationError; },{}],12:[function(_dereq_,module,exports){ 'use strict'; module.exports = function getRequestBody(operation, data, headers){ var body = operation.parameters.filter(function(param){ return param.paramType === 'body' && data[param.name] != null; }).map(function(param){ return data[param.name]; })[0]; if(!(headers && headers['Content-Type'])) return body; var contentType = headers['Content-Type']; var presentFormParams = operation.parameters.filter(function(param){ return param.paramType === 'form' && data[param.name] != null; }); if(contentType.indexOf('application/x-www-form-urlencoded') !== -1){ body = presentFormParams.map(function(param){ var key = param.name, value = data[key]; return encodeURIComponent(key) + '=' + encodeURIComponent(value); }).join('&'); } else if(contentType.indexOf('multipart/form-data') !== -1){ var randomness = Math.random().toString(16).substr(2); var boundary = 'SwaggerBoundary' + randomness; body = presentFormParams.map(function(param){ var key = param.name, value = data[key], result = '--' + boundary; result += '\nContent-Disposition: form-data; name="' + key + '"'; if(value.contentType){ if(value.name){ result += '; filename="' + value.name + '"'; } result += '\nContent-Type: ' + value.contentType; } if(value.contentTransferEncoding){ result += '\nContent-Transfer-Encoding: ' + value.contentTransferEncoding; } if(value.body){ result += '\n\n' + value.body; } else { result += '\n\n' + value; } return result; }).join('\n'); body += '\n--' + boundary + '--\n'; headers['Content-Type'] = contentType.replace( 'multipart/form-data', 'multipart/form-data; boundary=' + boundary ); } else if(contentType.indexOf('application/json') !== -1){ if(typeof body !== 'string'){ body = JSON.stringify(body); } } return body; }; },{}],13:[function(_dereq_,module,exports){ 'use strict'; var errorTypes = _dereq_('./errorTypes'), ContentTypeNotSupportedError = errorTypes.ContentTypeNotSupportedError, AcceptsNotSupportedError = errorTypes.AcceptsNotSupportedError; var DEFAULT_ACCEPT = 'application/json'; module.exports = function getRequestHeaders(operation, data, options){ data = data || {}; options = options || {}; var headers = {}; operation.parameters.forEach(function(param){ if(param.paramType === 'header' && data[param.name] != null){ headers[param.name] = data[param.name]; } }); // Passed headers if(options.headers){ Object.keys(options.headers).forEach(function(key){ headers[key] = options.headers[key]; }); } // Content-Type var contentType = options.contentType || getContentType(operation, data, options); if(contentType) { if(hasAccept(operation, contentType)){ headers['Content-Type'] = contentType; } else { throw new ContentTypeNotSupportedError(contentType, operation); } } // Accept var accept = options.accept || DEFAULT_ACCEPT; if(accept){ if(hasContentType(operation, accept)){ headers.Accept = accept; } else { throw new AcceptsNotSupportedError(accept, operation); } } return headers; }; function getContentType(operation, data){ var hasBody = operation.parameters.some(function(param){ return param.paramType === 'body' && data[param.name] !== undefined; }); if (hasBody){ return 'application/json'; } else { var hasFormParams = operation.parameters.some(function(param){ return param.paramType === 'form' && data[param.name] !== undefined; }); var hasFileParam = hasFormParams && operation.parameters.some(function(param){ return param.type === 'File' && data[param.name] !== undefined; }); if(hasFileParam) return 'multipart/form-data'; else if(hasFormParams) return 'application/x-www-form-urlencoded'; } } // Accepts is an optional field in the spec, but must be enforced when present function hasAccept(operation, contentType){ var apiDeclaration = operation.apiObject.apiDeclaration; var accepts = operation.consumes || apiDeclaration.consumes; if(accepts && accepts.length){ return accepts.indexOf(contentType) !== -1; } else { return true; } } exports.hasAccept = hasAccept; // Content-Type (produces) is an optional field in the spec, but must be enforced when present function hasContentType(operation, contentType){ var apiDeclaration = operation.apiObject.apiDeclaration, contentTypes = operation.produces || apiDeclaration.produces; if(contentTypes && contentTypes.length){ return contentTypes.indexOf(contentType) !== -1; } else { return true; } } exports.hasContentType = hasContentType; },{"./errorTypes":11}],14:[function(_dereq_,module,exports){ 'use strict'; var errorTypes = _dereq_('./errorTypes'), MissingPathParamsError = errorTypes.MissingPathParamsError; module.exports = function getRequestUrl(operation, data){ var url = getUrlTemplate(operation); url = applyPathParams(url, operation, data); if(!data) return url; var queryParams = operation.parameters.filter(function(param){ return param.paramType === 'query' && data[param.name] !== undefined; }).map(function(param){ var key = param.name; var encodedKey = encodeURIComponent(key); var value = data[key]; // For arrays, create multiple of the same query params to accomodate // the spec ambiguity on the issue: http://docs.oracle.com/javaee/6/api/ // javax/servlet/ServletRequest.html#getParameterValues(java.lang.String) if(param.type === 'array' && Array.isArray(value)){ return value.map(function(item){ return encodedKey + '=' + encodeURIComponent(item); }).join('&'); } else { return encodedKey + '=' + encodeURIComponent(value); } }).join('&'); if(queryParams) url += '?' + queryParams; return url; }; function applyPathParams(url, operation, data){ var pathParams = operation.parameters.filter(function(param){ return param.paramType === 'path'; }); var missingParams = pathParams.filter(function(param){ return data[param.name] === undefined; }); if(missingParams.length){ throw new MissingPathParamsError(missingParams.map(function(param){ return param.name; })); } pathParams.forEach(function(param){ var key = param.name; var exp = new RegExp('{' + key + '[^}]*}', 'gi'); var value = data[key].toString(); delete data[key]; value = value.split('/').map(encodeURIComponent).join('/'); url = url.replace(exp, value); }); return url; } function getUrlTemplate(operation){ var apiObject = operation.apiObject; var basePath = apiObject.apiDeclaration.basePath; var path = apiObject.path.replace('{format}', 'json'); return basePath + path; } },{"./errorTypes":11}]},{},[9]) (9) }); }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],2:[function(_dereq_,module,exports){ 'use strict'; var clientGenerator = _dereq_('../bower_components/swagger-client-generator/dist/swagger-client-generator.js'); /* global angular */ angular.module('swagger-client', []) .factory('swaggerClient', ['$log', '$http', '$q', function($log, $http, $q){ function requestHandler(error, request){ if(error){ $log.error(error); return $q.reject(error); } // Strip $$hashKeys from the body if json try { request.body = angular.toJson(JSON.parse(request.body)); } catch(e){ } return $http({ method: request.method, url: request.url, headers: request.headers, data: request.body }).then(function(response){ return response.data; }); } return function(schema){ return clientGenerator(schema, requestHandler); }; }]); },{"../bower_components/swagger-client-generator/dist/swagger-client-generator.js":1}]},{},[2]) (2) }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9vemFuL2NvZGUvc3dhZ2dlci1hbmd1bGFyLWNsaWVudC9ub2RlX21vZHVsZXMvYm9pbGVycGxhdGUtZ3VscC1hbmd1bGFyL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvb3phbi9jb2RlL3N3YWdnZXItY2xpZW50LWdlbmVyYXRvci9ub2RlX21vZHVsZXMvYm9pbGVycGxhdGUtZ3VscC9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiL1VzZXJzL296YW4vY29kZS9zd2FnZ2VyLWFuZ3VsYXItY2xpZW50L3NyYy9zd2FnZ2VyQ2xpZW50LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQWhLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQWpGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQWpGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQXJJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBeEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUEvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJzd2FnZ2VyLWFuZ3VsYXItY2xpZW50LmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpfXZhciBmPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChmLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGYsZi5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3Rocm93IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIil9dmFyIGY9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGYuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sZixmLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNsaWVudEdlbmVyYXRvciA9IHJlcXVpcmUoJy4uL2Jvd2VyX2NvbXBvbmVudHMvc3dhZ2dlci1jbGllbnQtZ2VuZXJhdG9yL2Rpc3Qvc3dhZ2dlci1jbGllbnQtZ2VuZXJhdG9yLmpzJyk7XG5cbi8qIGdsb2JhbCBhbmd1bGFyICovXG5hbmd1bGFyLm1vZHVsZSgnc3dhZ2dlci1jbGllbnQnLCBbXSlcbiAgLmZhY3RvcnkoJ3N3YWdnZXJDbGllbnQnLCBbJyRsb2cnLCAnJGh0dHAnLCAnJHEnLCBmdW5jdGlvbigkbG9nLCAkaHR0cCwgJHEpe1xuICAgIGZ1bmN0aW9uIHJlcXVlc3RIYW5kbGVyKGVycm9yLCByZXF1ZXN0KXtcbiAgICAgIGlmKGVycm9yKXtcbiAgICAgICAgJGxvZy5lcnJvcihlcnJvcik7XG4gICAgICAgIHJldHVybiAkcS5yZWplY3QoZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICAvLyBTdHJpcCAkJGhhc2hLZXlzIGZyb20gdGhlIGJvZHkgaWYganNvblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmVxdWVzdC5ib2R5ID0gYW5ndWxhci50b0pzb24oSlNPTi5wYXJzZShyZXF1ZXN0LmJvZHkpKTtcbiAgICAgIH0gY2F0Y2goZSl7XG5cbiAgICAgIH1cblxuICAgICAgcmV0dXJuICRodHRwKHtcbiAgICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICBkYXRhOiByZXF1ZXN0LmJvZHlcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2Upe1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UuZGF0YTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbihzY2hlbWEpe1xuICAgICAgcmV0dXJuIGNsaWVudEdlbmVyYXRvcihzY2hlbWEsIHJlcXVlc3RIYW5kbGVyKTtcbiAgICB9O1xuICB9XSk7XG4iXSwic291cmNlUm9vdCI6Ii9zb3VyY2UvIn0=