Dactyloidae/devtools/shared/sourcemap/tests/unit/test_util.js

651 lines
56 KiB
JavaScript
Raw Normal View History

function run_test() {
for (var k in SOURCE_MAP_TEST_MODULE) {
if (/^test/.test(k)) {
SOURCE_MAP_TEST_MODULE[k](assert);
}
}
}
var SOURCE_MAP_TEST_MODULE =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2014 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
{
var libUtil = __webpack_require__(1);
exports['test urls'] = function (assert) {
var assertUrl = function (url) {
assert.equal(url, libUtil.urlGenerate(libUtil.urlParse(url)));
};
assertUrl('http://');
assertUrl('http://www.example.com');
assertUrl('http://user:pass@www.example.com');
assertUrl('http://www.example.com:80');
assertUrl('http://www.example.com/');
assertUrl('http://www.example.com/foo/bar');
assertUrl('http://www.example.com/foo/bar/');
assertUrl('http://user:pass@www.example.com:80/foo/bar/');
assertUrl('//');
assertUrl('//www.example.com');
assertUrl('file:///www.example.com');
assert.equal(libUtil.urlParse(''), null);
assert.equal(libUtil.urlParse('.'), null);
assert.equal(libUtil.urlParse('..'), null);
assert.equal(libUtil.urlParse('a'), null);
assert.equal(libUtil.urlParse('a/b'), null);
assert.equal(libUtil.urlParse('a//b'), null);
assert.equal(libUtil.urlParse('/a'), null);
assert.equal(libUtil.urlParse('data:foo,bar'), null);
};
exports['test normalize()'] = function (assert) {
assert.equal(libUtil.normalize('/..'), '/');
assert.equal(libUtil.normalize('/../'), '/');
assert.equal(libUtil.normalize('/../../../..'), '/');
assert.equal(libUtil.normalize('/../../../../a/b/c'), '/a/b/c');
assert.equal(libUtil.normalize('/a/b/c/../../../d/../../e'), '/e');
assert.equal(libUtil.normalize('..'), '..');
assert.equal(libUtil.normalize('../'), '../');
assert.equal(libUtil.normalize('../../a/'), '../../a/');
assert.equal(libUtil.normalize('a/..'), '.');
assert.equal(libUtil.normalize('a/../../..'), '../..');
assert.equal(libUtil.normalize('/.'), '/');
assert.equal(libUtil.normalize('/./'), '/');
assert.equal(libUtil.normalize('/./././.'), '/');
assert.equal(libUtil.normalize('/././././a/b/c'), '/a/b/c');
assert.equal(libUtil.normalize('/a/b/c/./././d/././e'), '/a/b/c/d/e');
assert.equal(libUtil.normalize(''), '.');
assert.equal(libUtil.normalize('.'), '.');
assert.equal(libUtil.normalize('./'), '.');
assert.equal(libUtil.normalize('././a'), 'a');
assert.equal(libUtil.normalize('a/./'), 'a/');
assert.equal(libUtil.normalize('a/././.'), 'a');
assert.equal(libUtil.normalize('/a/b//c////d/////'), '/a/b/c/d/');
assert.equal(libUtil.normalize('///a/b//c////d/////'), '///a/b/c/d/');
assert.equal(libUtil.normalize('a/b//c////d'), 'a/b/c/d');
assert.equal(libUtil.normalize('.///.././../a/b//./..'), '../../a')
assert.equal(libUtil.normalize('http://www.example.com'), 'http://www.example.com');
assert.equal(libUtil.normalize('http://www.example.com/'), 'http://www.example.com/');
assert.equal(libUtil.normalize('http://www.example.com/./..//a/b/c/.././d//'), 'http://www.example.com/a/b/d/');
};
exports['test join()'] = function (assert) {
assert.equal(libUtil.join('a', 'b'), 'a/b');
assert.equal(libUtil.join('a/', 'b'), 'a/b');
assert.equal(libUtil.join('a//', 'b'), 'a/b');
assert.equal(libUtil.join('a', 'b/'), 'a/b/');
assert.equal(libUtil.join('a', 'b//'), 'a/b/');
assert.equal(libUtil.join('a/', '/b'), '/b');
assert.equal(libUtil.join('a//', '//b'), '//b');
assert.equal(libUtil.join('a', '..'), '.');
assert.equal(libUtil.join('a', '../b'), 'b');
assert.equal(libUtil.join('a/b', '../c'), 'a/c');
assert.equal(libUtil.join('a', '.'), 'a');
assert.equal(libUtil.join('a', './b'), 'a/b');
assert.equal(libUtil.join('a/b', './c'), 'a/b/c');
assert.equal(libUtil.join('a', 'http://www.example.com'), 'http://www.example.com');
assert.equal(libUtil.join('a', 'data:foo,bar'), 'data:foo,bar');
assert.equal(libUtil.join('', 'b'), 'b');
assert.equal(libUtil.join('.', 'b'), 'b');
assert.equal(libUtil.join('', 'b/'), 'b/');
assert.equal(libUtil.join('.', 'b/'), 'b/');
assert.equal(libUtil.join('', 'b//'), 'b/');
assert.equal(libUtil.join('.', 'b//'), 'b/');
assert.equal(libUtil.join('', '..'), '..');
assert.equal(libUtil.join('.', '..'), '..');
assert.equal(libUtil.join('', '../b'), '../b');
assert.equal(libUtil.join('.', '../b'), '../b');
assert.equal(libUtil.join('', '.'), '.');
assert.equal(libUtil.join('.', '.'), '.');
assert.equal(libUtil.join('', './b'), 'b');
assert.equal(libUtil.join('.', './b'), 'b');
assert.equal(libUtil.join('', 'http://www.example.com'), 'http://www.example.com');
assert.equal(libUtil.join('.', 'http://www.example.com'), 'http://www.example.com');
assert.equal(libUtil.join('', 'data:foo,bar'), 'data:foo,bar');
assert.equal(libUtil.join('.', 'data:foo,bar'), 'data:foo,bar');
assert.equal(libUtil.join('..', 'b'), '../b');
assert.equal(libUtil.join('..', 'b/'), '../b/');
assert.equal(libUtil.join('..', 'b//'), '../b/');
assert.equal(libUtil.join('..', '..'), '../..');
assert.equal(libUtil.join('..', '../b'), '../../b');
assert.equal(libUtil.join('..', '.'), '..');
assert.equal(libUtil.join('..', './b'), '../b');
assert.equal(libUtil.join('..', 'http://www.example.com'), 'http://www.example.com');
assert.equal(libUtil.join('..', 'data:foo,bar'), 'data:foo,bar');
assert.equal(libUtil.join('a', ''), 'a');
assert.equal(libUtil.join('a', '.'), 'a');
assert.equal(libUtil.join('a/', ''), 'a');
assert.equal(libUtil.join('a/', '.'), 'a');
assert.equal(libUtil.join('a//', ''), 'a');
assert.equal(libUtil.join('a//', '.'), 'a');
assert.equal(libUtil.join('/a', ''), '/a');
assert.equal(libUtil.join('/a', '.'), '/a');
assert.equal(libUtil.join('', ''), '.');
assert.equal(libUtil.join('.', ''), '.');
assert.equal(libUtil.join('.', ''), '.');
assert.equal(libUtil.join('.', '.'), '.');
assert.equal(libUtil.join('..', ''), '..');
assert.equal(libUtil.join('..', '.'), '..');
assert.equal(libUtil.join('http://foo.org/a', ''), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org/a', '.'), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org/a/', ''), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org/a/', '.'), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org/a//', ''), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org/a//', '.'), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org', ''), 'http://foo.org/');
assert.equal(libUtil.join('http://foo.org', '.'), 'http://foo.org/');
assert.equal(libUtil.join('http://foo.org/', ''), 'http://foo.org/');
assert.equal(libUtil.join('http://foo.org/', '.'), 'http://foo.org/');
assert.equal(libUtil.join('http://foo.org//', ''), 'http://foo.org/');
assert.equal(libUtil.join('http://foo.org//', '.'), 'http://foo.org/');
assert.equal(libUtil.join('//www.example.com', ''), '//www.example.com/');
assert.equal(libUtil.join('//www.example.com', '.'), '//www.example.com/');
assert.equal(libUtil.join('http://foo.org/a', 'b'), 'http://foo.org/a/b');
assert.equal(libUtil.join('http://foo.org/a/', 'b'), 'http://foo.org/a/b');
assert.equal(libUtil.join('http://foo.org/a//', 'b'), 'http://foo.org/a/b');
assert.equal(libUtil.join('http://foo.org/a', 'b/'), 'http://foo.org/a/b/');
assert.equal(libUtil.join('http://foo.org/a', 'b//'), 'http://foo.org/a/b/');
assert.equal(libUtil.join('http://foo.org/a/', '/b'), 'http://foo.org/b');
assert.equal(libUtil.join('http://foo.org/a//', '//b'), 'http://b');
assert.equal(libUtil.join('http://foo.org/a', '..'), 'http://foo.org/');
assert.equal(libUtil.join('http://foo.org/a', '../b'), 'http://foo.org/b');
assert.equal(libUtil.join('http://foo.org/a/b', '../c'), 'http://foo.org/a/c');
assert.equal(libUtil.join('http://foo.org/a', '.'), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org/a', './b'), 'http://foo.org/a/b');
assert.equal(libUtil.join('http://foo.org/a/b', './c'), 'http://foo.org/a/b/c');
assert.equal(libUtil.join('http://foo.org/a', 'http://www.example.com'), 'http://www.example.com');
assert.equal(libUtil.join('http://foo.org/a', 'data:foo,bar'), 'data:foo,bar');
assert.equal(libUtil.join('http://foo.org', 'a'), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org/', 'a'), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org//', 'a'), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org', '/a'), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org/', '/a'), 'http://foo.org/a');
assert.equal(libUtil.join('http://foo.org//', '/a'), 'http://foo.org/a');
assert.equal(libUtil.join('http://', 'www.example.com'), 'http://www.example.com');
assert.equal(libUtil.join('file:///', 'www.example.com'), 'file:///www.example.com');
assert.equal(libUtil.join('http://', 'ftp://example.com'), 'ftp://example.com');
assert.equal(libUtil.join('http://www.example.com', '//foo.org/bar'), 'http://foo.org/bar');
assert.equal(libUtil.join('//www.example.com', '//foo.org/bar'), '//foo.org/bar');
};
// TODO Issue #128: Define and test this function properly.
exports['test relative()'] = function (assert) {
assert.equal(libUtil.relative('/the/root', '/the/root/one.js'), 'one.js');
assert.equal(libUtil.relative('http://the/root', 'http://the/root/one.js'), 'one.js');
assert.equal(libUtil.relative('/the/root', '/the/rootone.js'), '../rootone.js');
assert.equal(libUtil.relative('http://the/root', 'http://the/rootone.js'), '../rootone.js');
assert.equal(libUtil.relative('/the/root', '/therootone.js'), '/therootone.js');
assert.equal(libUtil.relative('http://the/root', '/therootone.js'), '/therootone.js');
assert.equal(libUtil.relative('', '/the/root/one.js'), '/the/root/one.js');
assert.equal(libUtil.relative('.', '/the/root/one.js'), '/the/root/one.js');
assert.equal(libUtil.relative('', 'the/root/one.js'), 'the/root/one.js');
assert.equal(libUtil.relative('.', 'the/root/one.js'), 'the/root/one.js');
assert.equal(libUtil.relative('/', '/the/root/one.js'), 'the/root/one.js');
assert.equal(libUtil.relative('/', 'the/root/one.js'), 'the/root/one.js');
};
}
/***/ },
/* 1 */
/***/ function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
{
/**
* This is a helper function for getting values from parameter/options
* objects.
*
* @param args The object we are extracting values from
* @param name The name of the property we are getting.
* @param defaultValue An optional value to return if the property is missing
* from the object. If this is not specified and the property is missing, an
* error will be thrown.
*/
function getArg(aArgs, aName, aDefaultValue) {
if (aName in aArgs) {
return aArgs[aName];
} else if (arguments.length === 3) {
return aDefaultValue;
} else {
throw new Error('"' + aName + '" is a required argument.');
}
}
exports.getArg = getArg;
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
var match = aUrl.match(urlRegexp);
if (!match) {
return null;
}
return {
scheme: match[1],
auth: match[2],
host: match[3],
port: match[4],
path: match[5]
};
}
exports.urlParse = urlParse;
function urlGenerate(aParsedUrl) {
var url = '';
if (aParsedUrl.scheme) {
url += aParsedUrl.scheme + ':';
}
url += '//';
if (aParsedUrl.auth) {
url += aParsedUrl.auth + '@';
}
if (aParsedUrl.host) {
url += aParsedUrl.host;
}
if (aParsedUrl.port) {
url += ":" + aParsedUrl.port
}
if (aParsedUrl.path) {
url += aParsedUrl.path;
}
return url;
}
exports.urlGenerate = urlGenerate;
/**
* Normalizes a path, or the path portion of a URL:
*
* - Replaces consequtive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
* Based on code in the Node.js 'path' core module.
*
* @param aPath The path or url to normalize.
*/
function normalize(aPath) {
var path = aPath;
var url = urlParse(aPath);
if (url) {
if (!url.path) {
return aPath;
}
path = url.path;
}
var isAbsolute = exports.isAbsolute(path);
var parts = path.split(/\/+/);
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
part = parts[i];
if (part === '.') {
parts.splice(i, 1);
} else if (part === '..') {
up++;
} else if (up > 0) {
if (part === '') {
// The first part is blank if the path is absolute. Trying to go
// above the root is a no-op. Therefore we can remove all '..' parts
// directly after the root.
parts.splice(i + 1, up);
up = 0;
} else {
parts.splice(i, 2);
up--;
}
}
}
path = parts.join('/');
if (path === '') {
path = isAbsolute ? '/' : '.';
}
if (url) {
url.path = path;
return urlGenerate(url);
}
return path;
}
exports.normalize = normalize;
/**
* Joins two paths/URLs.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be joined with the root.
*
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
* first.
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
* is updated with the result and aRoot is returned. Otherwise the result
* is returned.
* - If aPath is absolute, the result is aPath.
* - Otherwise the two paths are joined with a slash.
* - Joining for example 'http://' and 'www.example.com' is also supported.
*/
function join(aRoot, aPath) {
if (aRoot === "") {
aRoot = ".";
}
if (aPath === "") {
aPath = ".";
}
var aPathUrl = urlParse(aPath);
var aRootUrl = urlParse(aRoot);
if (aRootUrl) {
aRoot = aRootUrl.path || '/';
}
// `join(foo, '//www.example.org')`
if (aPathUrl && !aPathUrl.scheme) {
if (aRootUrl) {
aPathUrl.scheme = aRootUrl.scheme;
}
return urlGenerate(aPathUrl);
}
if (aPathUrl || aPath.match(dataUrlRegexp)) {
return aPath;
}
// `join('http://', 'www.example.com')`
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
aRootUrl.host = aPath;
return urlGenerate(aRootUrl);
}
var joined = aPath.charAt(0) === '/'
? aPath
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
if (aRootUrl) {
aRootUrl.path = joined;
return urlGenerate(aRootUrl);
}
return joined;
}
exports.join = join;
exports.isAbsolute = function (aPath) {
return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
};
/**
* Make a path relative to a URL or another path.
*
* @param aRoot The root path or URL.
* @param aPath The path or URL to be made relative to aRoot.
*/
function relative(aRoot, aPath) {
if (aRoot === "") {
aRoot = ".";
}
aRoot = aRoot.replace(/\/$/, '');
// It is possible for the path to be above the root. In this case, simply
// checking whether the root is a prefix of the path won't work. Instead, we
// need to remove components from the root one by one, until either we find
// a prefix that fits, or we run out of components to remove.
var level = 0;
while (aPath.indexOf(aRoot + '/') !== 0) {
var index = aRoot.lastIndexOf("/");
if (index < 0) {
return aPath;
}
// If the only part of the root that is left is the scheme (i.e. http://,
// file:///, etc.), one or more slashes (/), or simply nothing at all, we
// have exhausted all components, so the path is not relative to the root.
aRoot = aRoot.slice(0, index);
if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
return aPath;
}
++level;
}
// Make sure we add a "../" for each component we removed from the root.
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
}
exports.relative = relative;
/**
* Because behavior goes wacky when you set `__proto__` on objects, we
* have to prefix all the strings in our set with an arbitrary character.
*
* See https://github.com/mozilla/source-map/pull/31 and
* https://github.com/mozilla/source-map/issues/30
*
* @param String aStr
*/
function toSetString(aStr) {
return '$' + aStr;
}
exports.toSetString = toSetString;
function fromSetString(aStr) {
return aStr.substr(1);
}
exports.fromSetString = fromSetString;
/**
* Comparator between two mappings where the original positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same original source/line/column, but different generated
* line and column the same. Useful when searching for a mapping with a
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
var cmp = mappingA.source - mappingB.source;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0 || onlyCompareOriginal) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
return mappingA.name - mappingB.name;
}
exports.compareByOriginalPositions = compareByOriginalPositions;
/**
* Comparator between two mappings with deflated source and name indices where
* the generated positions are compared.
*
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
* mappings with the same generated line and column, but different
* source/name/original line and column the same. Useful when searching for a
* mapping with a stubbed out mapping.
*/
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
var cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0 || onlyCompareGenerated) {
return cmp;
}
cmp = mappingA.source - mappingB.source;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0) {
return cmp;
}
return mappingA.name - mappingB.name;
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
function strcmp(aStr1, aStr2) {
if (aStr1 === aStr2) {
return 0;
}
if (aStr1 > aStr2) {
return 1;
}
return -1;
}
/**
* Comparator between two mappings with inflated source and name strings where
* the generated positions are compared.
*/
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
var cmp = mappingA.generatedLine - mappingB.generatedLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
if (cmp !== 0) {
return cmp;
}
cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalLine - mappingB.originalLine;
if (cmp !== 0) {
return cmp;
}
cmp = mappingA.originalColumn - mappingB.originalColumn;
if (cmp !== 0) {
return cmp;
}
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
}
/***/ }
/******/ ]);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgYWVhNDgxM2ZiZGRjOWE3MDI3MTgiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXV0aWwuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7O0FDdENBLGlCQUFnQixvQkFBb0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUN0TkEsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlEQUFnRCxRQUFRO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJ0ZXN0X3V0aWwuanMiLCJzb3VyY2VzQ