+ [loader] add weex-loader for webpack
diff --git a/weex-loader/.gitignore b/weex-loader/.gitignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/weex-loader/.gitignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/weex-loader/.npmignore b/weex-loader/.npmignore
new file mode 100644
index 0000000..79e6ea4
--- /dev/null
+++ b/weex-loader/.npmignore
@@ -0,0 +1,2 @@
+node_modules
+test
\ No newline at end of file
diff --git a/weex-loader/README.md b/weex-loader/README.md
index 3fc549b..2b6b7d7 100644
--- a/weex-loader/README.md
+++ b/weex-loader/README.md
@@ -47,6 +47,12 @@
 loader.useStyler(styler);
 loader.useTemplater(templater);
 
+/* The banner plugin is required, please just copy to use it */
+var banner = 'var __weex_define__ = define, __weex_bootstrap__ = bootstrap;';
+var bannerPlugin = new webpack.BannerPlugin(banner, {
+  raw: true
+});
+
 module.exports = {
   entry: './test/main.we?entry=true',
   output: {
@@ -60,7 +66,8 @@
         loader: 'weex'
       }
     ]
-  }
+  },
+  plugins: [bannerPlugin]
 }
 ```
 
@@ -129,7 +136,7 @@
 
 ### How to require a CommonJS module
 
-0. first, require a `path/to/module.js` in `script` like `var _ = require('lodash')`. 
+0. first, require a `path/to/module.js` in `script` like `var _ = require('loadash')`. 
 1. then use it in `script`.
 
 ### How to embed a composed component
diff --git a/weex-loader/index.js b/weex-loader/index.js
new file mode 100644
index 0000000..db0e020
--- /dev/null
+++ b/weex-loader/index.js
@@ -0,0 +1,260 @@
+'use strict';
+
+var path = require('path');
+var fs = require('fs');
+var md5 = require('md5');
+var loaderUtils = require('loader-utils');
+var blocker = require('weex-transformer/lib/blocker');
+
+var pkg = require('./package.json');
+var transformerVersion = pkg.dependencies['weex-transformer'].match(/\d+(?:\.\d+){0,2}/)[0];
+
+var templater;
+var styler;
+var scripter;
+
+var MODULE_EXPORTS_REG = /module\.exports/g;
+var REQUIRE_REG = /require\((["'])(\@weex\-module\/[^\)\1]+)\1\)/g;
+
+function parseScript(loader, params, source, config, data) {
+    if (!scripter) {
+        return Promise.reject('please use a script parser. ex. weex-scripter');
+    }
+
+    var target = scripter.fix(source);
+    var name = params.resourceQuery.name || 
+                    path.basename(params.resourcePath).replace(/\..*$/, '');
+
+    if (params.resourceQuery.entry === true) {
+        name = md5(source);
+    }
+
+    target = target.replace(MODULE_EXPORTS_REG, '__weex_module__.exports')
+                .replace(REQUIRE_REG, '__weex_require__($1$2$1)');
+
+    target = ';__weex_define__("@weex-component/' + name + '", [], ' + 
+                'function(__weex_require__, __weex_exports__, __weex_module__)' + 
+                '{\n' + target + '\n})';
+
+    if (params.resourceQuery.entry === true) {
+        target += '\n;__weex_bootstrap__("@weex-component/' + name + '", ' + 
+                    String(config) + ', ' + 
+                    String(data) + ')';
+    }
+
+    return Promise.resolve(target);
+}
+
+function logWarning(loader, log) {
+    if (log && log instanceof Array) {
+        log.forEach(function(l) {
+            loader.emitWarning(l.reason + '\t@' + l.line + ':' + l.column)
+        });
+    }
+}
+
+function parseStyle(loader, params, source) {
+    return new Promise(function(resolve, reject) {
+        if (!styler) {
+            return reject('please use a style parser. ex. weex-styler');
+        }
+
+        styler.parse(source, function(err, obj) {
+            if (err) {
+                reject(err);
+            } else {
+                logWarning(loader, obj.log);
+                var target = JSON.stringify(obj.jsonStyle, null, '  ');
+                resolve(target);
+            }
+        });
+    });
+}
+
+var FUNC_START = '#####FUN_S#####';
+var FUNC_START_REG = new RegExp('["\']' + FUNC_START, 'g');
+var FUNC_END = '#####FUN_E#####';
+var FUNC_END_REG = new RegExp(FUNC_END + '["\']', 'g');
+function stringifyFunction(key, value) {
+    if (typeof value === 'function') {
+      return  FUNC_START + value.toString() + '#####FUN_E#####';
+    }
+    return value;
+}
+
+function parseTemplate(loader, params, source, deps) {
+    return new Promise(function(resolve, reject) {
+        if (!templater) {
+            return reject('please use a template parser. ex. weex-styler');
+        }
+
+        templater.parse(source, function(err, obj) {
+            if (err) {
+                reject(err);
+            } else {
+                logWarning(loader, obj.log);
+
+                if (deps && obj.deps) {
+                    var context = path.dirname(params.resourcePath);
+                    obj.deps.map(function(dep) {
+                        var filename = './' + dep + '.we';
+                        var filepath = path.resolve(context, filename);
+                        if (fs.existsSync(filepath)) {
+                            return filepath;
+                        }
+                    }).forEach(function(dep) {
+                        if (dep) {
+                            deps.push(dep);
+                        }
+                    });
+                }
+
+                var target = JSON.stringify(obj.jsonTemplate, stringifyFunction, '  ');
+                target = target.replace(FUNC_START_REG, '')
+                        .replace(FUNC_END_REG, '');
+
+                resolve(target);
+            }
+        });
+    });
+}
+
+function parseWeexFile(loader, params, source) {
+    var results;
+    var deps = [];
+
+    return new Promise(function(resolve, reject) {
+        blocker.format(source, function(err, ret) {
+            if (err) {
+                reject(err);
+            } else {
+                results = ret;
+                resolve();
+            }
+        });
+    }).then(function() {
+        var promises = [Promise.resolve(), Promise.resolve()];
+        var content;
+
+        if (results.template) {
+            content = results.template.content;
+            promises[0] = parseTemplate(loader, params, content, deps);
+        }
+        if (results.styles) {
+            content = results.styles.reduce(function(pre, cur) {
+                return pre + '\n' + cur.content;
+            }, '');
+            promises[1] = parseStyle(loader, params, content);
+        }
+
+        return Promise.all(promises);
+    }).then(function(ret) {
+        var template = ret[0];
+        var style = ret[1];
+
+        var content = '';
+        var config = {};
+        var data;
+
+        if (results.scripts) {
+            content += results.scripts.reduce(function(pre, cur) {
+                return pre + '\n;' + cur.content;
+            }, '');
+        }
+
+        var requireContent = '';
+        if (deps.length) {
+            requireContent += deps.map(function(dep) {
+                if (!content.match(new RegExp('require\\(["\']./' + path.basename(dep) + '["\']\\)', 'g'))) {
+                    return 'require("' + dep + '");\n';
+                } else {
+                    return '';
+                }
+            });
+
+            content = requireContent + '\n' + content;
+        }
+
+        if (template) {
+            content += '\n;module.exports.template=' + template;
+        }
+
+        if (style) {
+            content += '\n;module.exports.style=' + style;
+        }
+
+        if (results.config) {
+            config = JSON.parse(results.config.content);
+        }
+        config.transformerVersion = transformerVersion;
+        config = JSON.stringify(config);
+
+        if (results.data) {
+            data = results.data.content;
+        }
+
+        return parseScript(loader, params, content, config, data);
+    });
+}
+
+function partedLoader(type, loader, params, source) {
+    var promise;
+    switch(type) {
+        case 'script':
+            var config = JSON.stringify({
+                transformerVersion: transformerVersion
+            });
+            promise = parseScript(loader, params, source, config);
+            break;
+        case 'style':
+            promise = parseStyle(loader, params, source);
+            break;
+        case 'tpl':
+            promise = parseTemplate(loader, params, source);
+            break;
+        case 'we':
+        default:
+            promise = parseWeexFile(loader, params, source);
+            break;
+    }
+    return promise;
+}
+
+function loader(source) {
+    var self = this;
+    this.cacheable && this.cacheable();
+
+    var callback = this.async();
+    var params = {
+        loaderQuery: loaderUtils.parseQuery(this.query),
+        resourceQuery: loaderUtils.parseQuery(this.resourceQuery),
+        resourcePath: this.resourcePath
+    };
+    var type = params.loaderQuery.type || 'we';
+    var promise = partedLoader(type, this, params, source);
+
+    promise.then(function(result) {
+        if (type === 'style' || type === 'tpl' || type === 'template') {
+            result = 'module.exports=' + result;
+        }
+        // console.log('\n[' + type + ', ' + params.resourcePath + ']\n', source, '\n=========>\n', result + '\n');
+        callback(null, result);
+    }).catch(function(err) {
+        self.emitError(err.toString());
+        callback(err.toString(), '');
+    });
+}
+
+loader.useScripter = function(module) {
+    scripter = module;
+}
+
+loader.useStyler = function(module) {
+    styler = module;
+}
+
+loader.useTemplater = function(module) {
+    templater = module;
+}
+
+module.exports = loader;
\ No newline at end of file
diff --git a/weex-loader/package.json b/weex-loader/package.json
new file mode 100644
index 0000000..38d82bf
--- /dev/null
+++ b/weex-loader/package.json
@@ -0,0 +1,48 @@
+{
+  "name": "weex-loader",
+  "version": "0.1.0",
+  "description": "a webpack loader for weex",
+  "main": "index.js",
+  "author": "terrykingcha <terrykingcha@gmail.com>",
+  "repository": {
+    "type": "git",
+    "url": "git@github.com:alibaba/weex_toolchain.git"
+  },
+  "licenses": "MIT",
+  "keywords": [
+    "weex",
+    "loader",
+    "webpack",
+    "transformer"
+  ],
+  "scripts": {
+    "test:build": "webpack --config webpack.config.js",
+    "test:transform": "transformer test/expect/*.we -o test/expect",
+    "test:mocha": "mocha --compilers js:babel-core/register test/test.js",
+    "test": "npm run test:build && npm run test:transform && npm run test:mocha",
+    "serve": "serve ./test -p 12581"
+  },
+  "peerDependencies": {
+    "weex-scripter": "^0.1.4",
+    "weex-styler": "^0.0.17",
+    "weex-templater": "~0.2.0"
+  },
+  "devDependencies": {
+    "babel-core": "^6.7.6",
+    "babel-loader": "^6.2.4",
+    "babel-preset-es2015": "^6.6.0",
+    "chai": "^3.5.0",
+    "less": "^2.6.1",
+    "less-loader": "^2.2.3",
+    "mocha": "^2.4.5",
+    "serve": "^1.4.0",
+    "sinon": "^1.17.3",
+    "sinon-chai": "^2.8.0",
+    "webpack": "~1.13.0"
+  },
+  "dependencies": {
+    "loader-utils": "~0.2.14",
+    "md5": "^2.1.0",
+    "weex-transformer": "^0.3.0"
+  }
+}
diff --git a/weex-loader/test/a.js b/weex-loader/test/a.js
new file mode 100644
index 0000000..344bccb
--- /dev/null
+++ b/weex-loader/test/a.js
@@ -0,0 +1,13 @@
+require('./b?name=goto');
+require('./expect/copyright.we?name=copyright');
+
+var c = require('./lib/c');
+
+module.exports = {
+    data: {
+        text: 'Hello ' + c.name
+    }
+}
+
+module.exports.style = require('./a.less');
+module.exports.template = require('./a.tpl');
\ No newline at end of file
diff --git a/weex-loader/test/a.less b/weex-loader/test/a.less
new file mode 100644
index 0000000..331de73
--- /dev/null
+++ b/weex-loader/test/a.less
@@ -0,0 +1,10 @@
+@padding: 20px;
+
+.h1 {
+    font-size: 60px;
+    color: red;
+    padding-top: @padding;
+    padding-bottom: @padding;
+    padding-left: @padding;
+    padding-right: @padding;
+}
\ No newline at end of file
diff --git a/weex-loader/test/a.tpl b/weex-loader/test/a.tpl
new file mode 100644
index 0000000..52d1a04
--- /dev/null
+++ b/weex-loader/test/a.tpl
@@ -0,0 +1,5 @@
+<container>
+    <text class="h1">{{text}}</text>
+    <goto></goto>
+    <copyright></copyright>
+</container>
\ No newline at end of file
diff --git a/weex-loader/test/actual/a.js b/weex-loader/test/actual/a.js
new file mode 100644
index 0000000..175e3e2
--- /dev/null
+++ b/weex-loader/test/actual/a.js
@@ -0,0 +1,256 @@
+var __weex_define__ = define, __weex_bootstrap__ = bootstrap;
+/******/ (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__) {
+
+	;__weex_define__("@weex-component/48c34d39ea9ced4ad5f95df361368f61", [], function(__weex_require__, __weex_exports__, __weex_module__){
+	'use strict';
+
+	__webpack_require__(1);
+	__webpack_require__(3);
+
+	var c = __webpack_require__(6);
+
+	__weex_module__.exports = {
+	    data: function () {return {
+	        text: 'Hello ' + c.name
+	    }}
+	};
+
+	__weex_module__.exports.style = __webpack_require__(7);
+	__weex_module__.exports.template = __webpack_require__(8);
+	})
+	;__weex_bootstrap__("@weex-component/48c34d39ea9ced4ad5f95df361368f61", {"transformerVersion":"0.3.0"}, undefined)
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+	;__weex_define__("@weex-component/goto", [], function(__weex_require__, __weex_exports__, __weex_module__){
+	'use strict';
+
+	var _b = __webpack_require__(2);
+
+	var _b2 = _interopRequireDefault(_b);
+
+	var _event = __weex_require__('@weex-module/event');
+
+	var event = _interopRequireWildcard(_event);
+
+	function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+
+	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+	__weex_module__.exports = {
+	    data: function () {return {
+	        text: '',
+	        paddingLeft: 20
+	    }},
+	    template: _b2.default,
+	    created: function created() {
+	        this.text = 'Yes It is! Go Weex >>>';
+	    },
+
+	    methods: {
+	        clicked: function clicked() {
+	            event.openURL('https://github.com/alibaba/weex_toolchain');
+	        }
+	    }
+	};
+	})
+
+/***/ },
+/* 2 */
+/***/ function(module, exports) {
+
+	module.exports={
+	  "type": "container",
+	  "children": [
+	    {
+	      "type": "text",
+	      "events": {
+	        "click": "clicked"
+	      },
+	      "style": {
+	        "textDecoration": "underline",
+	        "paddingLeft": function () {return this.paddingLeft}
+	      },
+	      "attr": {
+	        "value": function () {return this.text}
+	      }
+	    }
+	  ]
+	}
+
+/***/ },
+/* 3 */
+/***/ function(module, exports, __webpack_require__) {
+
+	;__weex_define__("@weex-component/copyright", [], function(__weex_require__, __weex_exports__, __weex_module__){
+	__webpack_require__(4);
+
+
+	;
+	    __weex_module__.exports = {
+	        data: function () {return {
+	            className: ''
+	        }},
+	        created: function (argument) {
+	            this.className = 'copyright';
+	        }
+	    }
+
+	;__weex_module__.exports.template={
+	  "type": "container",
+	  "children": [
+	    {
+	      "type": "text",
+	      "classList": function () {return [this.className]},
+	      "attr": {
+	        "value": "Copy right @ 2016 Weex"
+	      }
+	    },
+	    {
+	      "type": "company"
+	    }
+	  ]
+	}
+	;__weex_module__.exports.style={
+	  "copyright": {
+	    "textAlign": "center",
+	    "paddingTop": 20,
+	    "paddingBottom": 20,
+	    "color": "#666666",
+	    "fontSize": 26
+	  }
+	}
+	})
+
+/***/ },
+/* 4 */
+/***/ function(module, exports, __webpack_require__) {
+
+	;__weex_define__("@weex-component/company", [], function(__weex_require__, __weex_exports__, __weex_module__){
+
+	;
+	var d = __webpack_require__(5);
+	__weex_module__.exports = {
+	    data: function () {return {
+	        name: d.name
+	    }}
+	}
+
+	;__weex_module__.exports.template={
+	  "type": "container",
+	  "children": [
+	    {
+	      "type": "text",
+	      "style": {
+	        "textAlign": "center",
+	        "fontSize": 18,
+	        "color": "#CCCCCC"
+	      },
+	      "attr": {
+	        "value": function () {return this.name}
+	      }
+	    }
+	  ]
+	}
+	})
+
+/***/ },
+/* 5 */
+/***/ function(module, exports) {
+
+	exports.name = 'Alibaba Group';
+
+/***/ },
+/* 6 */
+/***/ function(module, exports) {
+
+	exports.name = 'Weex-Loader';
+
+/***/ },
+/* 7 */
+/***/ function(module, exports) {
+
+	module.exports={
+	  "h1": {
+	    "fontSize": 60,
+	    "color": "#FF0000",
+	    "paddingTop": 20,
+	    "paddingBottom": 20,
+	    "paddingLeft": 20,
+	    "paddingRight": 20
+	  }
+	}
+
+/***/ },
+/* 8 */
+/***/ function(module, exports) {
+
+	module.exports={
+	  "type": "container",
+	  "children": [
+	    {
+	      "type": "text",
+	      "classList": [
+	        "h1"
+	      ],
+	      "attr": {
+	        "value": function () {return this.text}
+	      }
+	    },
+	    {
+	      "type": "goto"
+	    },
+	    {
+	      "type": "copyright"
+	    }
+	  ]
+	}
+
+/***/ }
+/******/ ]);
\ No newline at end of file
diff --git a/weex-loader/test/b.js b/weex-loader/test/b.js
new file mode 100644
index 0000000..ab5c28e
--- /dev/null
+++ b/weex-loader/test/b.js
@@ -0,0 +1,18 @@
+import template from './b.tpl';
+import * as event from '@weex-module/event';
+
+module.exports = {
+    data: {
+        text: '',
+        paddingLeft: 20
+    },
+    template,
+    created() {
+        this.text = 'Yes It is! Go Weex >>>';
+    },
+    methods: {
+        clicked: function() {
+            event.openURL('https://github.com/alibaba/weex_toolchain');
+        }
+    }
+};
\ No newline at end of file
diff --git a/weex-loader/test/b.tpl b/weex-loader/test/b.tpl
new file mode 100644
index 0000000..3fb7d9b
--- /dev/null
+++ b/weex-loader/test/b.tpl
@@ -0,0 +1,3 @@
+<container>
+    <text onclick="clicked" style="text-decoration: underline; padding-left: {{paddingLeft}}">{{text}}</text>
+</container>
\ No newline at end of file
diff --git a/weex-loader/test/expect/a.js b/weex-loader/test/expect/a.js
new file mode 100644
index 0000000..13b6c5e
--- /dev/null
+++ b/weex-loader/test/expect/a.js
@@ -0,0 +1,175 @@
+browserifyRequire=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof browserifyRequire=="function"&&browserifyRequire;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 browserifyRequire=="function"&&browserifyRequire;for(var o=0;o<r.length;o++)s(r[o]);return s})({"2f45f2510f12e10f1ea5a8ee68e880cd":[function(require,module,exports){
+exports.name = 'Alibaba Group';
+},{}],"4302c316e5980c159f273a3b5da112b5":[function(require,module,exports){
+exports.name = 'Weex-Loader';
+},{}]},{},[]);
+
+
+define('@weex-component/company', function (require, exports, module) {
+
+;
+var d = browserifyRequire("2f45f2510f12e10f1ea5a8ee68e880cd");
+module.exports = {
+    data: function () {return {
+        name: d.name
+    }}
+}
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+  "type": "container",
+  "children": [
+    {
+      "type": "text",
+      "style": {
+        "textAlign": "center",
+        "fontSize": 18,
+        "color": "#CCCCCC"
+      },
+      "attr": {
+        "value": function () {return this.name}
+      }
+    }
+  ]
+}
+
+;})
+
+// module
+
+define('@weex-component/copyright', function (require, exports, module) {
+
+;
+    module.exports = {
+        data: function () {return {
+            className: ''
+        }},
+        created: function (argument) {
+            this.className = 'copyright';
+        }
+    }
+
+
+;module.exports.style = {
+  "copyright": {
+    "textAlign": "center",
+    "paddingTop": 20,
+    "paddingBottom": 20,
+    "color": "#666666",
+    "fontSize": 26
+  }
+}
+
+;module.exports.template = {
+  "type": "container",
+  "children": [
+    {
+      "type": "text",
+      "classList": function () {return [this.className]},
+      "attr": {
+        "value": "Copy right @ 2016 Weex"
+      }
+    },
+    {
+      "type": "company"
+    }
+  ]
+}
+
+;})
+
+// module
+
+define('@weex-component/goto', function (require, exports, module) {
+
+;
+    module.exports = {
+        data: function () {return {
+            text: '',
+            paddingLeft: 20
+        }},
+        created: function() {
+            this.text = 'Yes It is! Go Weex >>>';
+        },
+        methods: {
+            clicked: function() {
+                this.$openURL('http://github.com/alibaba/weex');
+            }
+        }
+    }
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+  "type": "container",
+  "children": [
+    {
+      "type": "text",
+      "events": {
+        "click": "clicked"
+      },
+      "style": {
+        "textDecoration": "underline",
+        "paddingLeft": function () {return this.paddingLeft}
+      },
+      "attr": {
+        "value": function () {return this.text}
+      }
+    }
+  ]
+}
+
+;})
+
+// module
+
+define('@weex-component/a', function (require, exports, module) {
+
+;
+var c = browserifyRequire("4302c316e5980c159f273a3b5da112b5")
+module.exports = {
+    data: function () {return {
+        text: 'Hello ' + c.name
+    }}
+}
+
+
+;module.exports.style = {
+  "h1": {
+    "fontSize": 60,
+    "color": "#FF0000",
+    "paddingTop": 20,
+    "paddingBottom": 20,
+    "paddingLeft": 20,
+    "paddingRight": 20
+  }
+}
+
+;module.exports.template = {
+  "type": "container",
+  "children": [
+    {
+      "type": "text",
+      "classList": [
+        "h1"
+      ],
+      "attr": {
+        "value": function () {return this.text}
+      }
+    },
+    {
+      "type": "goto"
+    },
+    {
+      "type": "copyright"
+    }
+  ]
+}
+
+;})
+
+// require module
+bootstrap('@weex-component/a', {"transformerVersion":"0.3.0"})
\ No newline at end of file
diff --git a/weex-loader/test/expect/a.we b/weex-loader/test/expect/a.we
new file mode 100644
index 0000000..2ea3b36
--- /dev/null
+++ b/weex-loader/test/expect/a.we
@@ -0,0 +1,27 @@
+<template>
+    <container>
+        <text class="h1">{{text}}</text>
+        <goto></goto>
+        <copyright></copyright>
+    </container>
+</template>
+
+<style>
+.h1 {
+    font-size: 60px;
+    color: red;
+    padding-top: 20px;
+    padding-bottom: 20px;
+    padding-left: 20px;
+    padding-right: 20px;
+}
+</style>
+
+<script>
+var c = require('../lib/c')
+module.exports = {
+    data: {
+        text: 'Hello ' + c.name
+    }
+}
+</script>
\ No newline at end of file
diff --git a/weex-loader/test/expect/company.js b/weex-loader/test/expect/company.js
new file mode 100644
index 0000000..9e14be8
--- /dev/null
+++ b/weex-loader/test/expect/company.js
@@ -0,0 +1,39 @@
+browserifyRequire=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof browserifyRequire=="function"&&browserifyRequire;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 browserifyRequire=="function"&&browserifyRequire;for(var o=0;o<r.length;o++)s(r[o]);return s})({"2f45f2510f12e10f1ea5a8ee68e880cd":[function(require,module,exports){
+exports.name = 'Alibaba Group';
+},{}]},{},[]);
+
+
+define('@weex-component/company', function (require, exports, module) {
+
+;
+var d = browserifyRequire("2f45f2510f12e10f1ea5a8ee68e880cd");
+module.exports = {
+    data: function () {return {
+        name: d.name
+    }}
+}
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+  "type": "container",
+  "children": [
+    {
+      "type": "text",
+      "style": {
+        "textAlign": "center",
+        "fontSize": 18,
+        "color": "#CCCCCC"
+      },
+      "attr": {
+        "value": function () {return this.name}
+      }
+    }
+  ]
+}
+
+;})
+
+// require module
+bootstrap('@weex-component/company', {"transformerVersion":"0.3.0"})
\ No newline at end of file
diff --git a/weex-loader/test/expect/company.we b/weex-loader/test/expect/company.we
new file mode 100644
index 0000000..743920c
--- /dev/null
+++ b/weex-loader/test/expect/company.we
@@ -0,0 +1,14 @@
+<template>
+    <container>
+        <text style="text-align: center; font-size: 18; color: #CCCCCC;">{{name}}</text>
+    </container>
+</template>
+
+<script>
+var d = require('../lib/d');
+module.exports = {
+    data: {
+        name: d.name
+    }
+}
+</script>
\ No newline at end of file
diff --git a/weex-loader/test/expect/copyright.js b/weex-loader/test/expect/copyright.js
new file mode 100644
index 0000000..a7b886c
--- /dev/null
+++ b/weex-loader/test/expect/copyright.js
@@ -0,0 +1,82 @@
+browserifyRequire=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof browserifyRequire=="function"&&browserifyRequire;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 browserifyRequire=="function"&&browserifyRequire;for(var o=0;o<r.length;o++)s(r[o]);return s})({"2f45f2510f12e10f1ea5a8ee68e880cd":[function(require,module,exports){
+exports.name = 'Alibaba Group';
+},{}]},{},[]);
+
+
+define('@weex-component/company', function (require, exports, module) {
+
+;
+var d = browserifyRequire("2f45f2510f12e10f1ea5a8ee68e880cd");
+module.exports = {
+    data: function () {return {
+        name: d.name
+    }}
+}
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+  "type": "container",
+  "children": [
+    {
+      "type": "text",
+      "style": {
+        "textAlign": "center",
+        "fontSize": 18,
+        "color": "#CCCCCC"
+      },
+      "attr": {
+        "value": function () {return this.name}
+      }
+    }
+  ]
+}
+
+;})
+
+// module
+
+define('@weex-component/copyright', function (require, exports, module) {
+
+;
+    module.exports = {
+        data: function () {return {
+            className: ''
+        }},
+        created: function (argument) {
+            this.className = 'copyright';
+        }
+    }
+
+
+;module.exports.style = {
+  "copyright": {
+    "textAlign": "center",
+    "paddingTop": 20,
+    "paddingBottom": 20,
+    "color": "#666666",
+    "fontSize": 26
+  }
+}
+
+;module.exports.template = {
+  "type": "container",
+  "children": [
+    {
+      "type": "text",
+      "classList": function () {return [this.className]},
+      "attr": {
+        "value": "Copy right @ 2016 Weex"
+      }
+    },
+    {
+      "type": "company"
+    }
+  ]
+}
+
+;})
+
+// require module
+bootstrap('@weex-component/copyright', {"transformerVersion":"0.3.0"})
\ No newline at end of file
diff --git a/weex-loader/test/expect/copyright.we b/weex-loader/test/expect/copyright.we
new file mode 100644
index 0000000..2525348
--- /dev/null
+++ b/weex-loader/test/expect/copyright.we
@@ -0,0 +1,27 @@
+<template>
+    <container>
+        <text class="{{className}}">Copy right @ 2016 Weex</text>
+        <company></company>
+    </container>
+</template>
+
+<style>
+    .copyright {
+        text-align: center;
+        padding-top: 20;
+        padding-bottom: 20;
+        color: #666;
+        font-size: 26;
+    }
+</style>
+
+<script>
+    module.exports = {
+        data: {
+            className: ''
+        },
+        created: function (argument) {
+            this.className = 'copyright';
+        }
+    }
+</script>
\ No newline at end of file
diff --git a/weex-loader/test/expect/goto.js b/weex-loader/test/expect/goto.js
new file mode 100644
index 0000000..d1a40f6
--- /dev/null
+++ b/weex-loader/test/expect/goto.js
@@ -0,0 +1,44 @@
+define('@weex-component/goto', function (require, exports, module) {
+
+;
+    module.exports = {
+        data: function () {return {
+            text: '',
+            paddingLeft: 20
+        }},
+        created: function() {
+            this.text = 'Yes It is! Go Weex >>>';
+        },
+        methods: {
+            clicked: function() {
+                this.$openURL('http://github.com/alibaba/weex');
+            }
+        }
+    }
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+  "type": "container",
+  "children": [
+    {
+      "type": "text",
+      "events": {
+        "click": "clicked"
+      },
+      "style": {
+        "textDecoration": "underline",
+        "paddingLeft": function () {return this.paddingLeft}
+      },
+      "attr": {
+        "value": function () {return this.text}
+      }
+    }
+  ]
+}
+
+;})
+
+// require module
+bootstrap('@weex-component/goto', {"transformerVersion":"0.3.0"})
\ No newline at end of file
diff --git a/weex-loader/test/expect/goto.we b/weex-loader/test/expect/goto.we
new file mode 100644
index 0000000..b4c2b52
--- /dev/null
+++ b/weex-loader/test/expect/goto.we
@@ -0,0 +1,22 @@
+<template>
+    <container>
+        <text onclick="clicked" style="text-decoration: underline; padding-left: {{paddingLeft}}">{{text}}</text>
+    </container>
+</template>
+
+<script>
+    module.exports = {
+        data: {
+            text: '',
+            paddingLeft: 20
+        },
+        created: function() {
+            this.text = 'Yes It is! Go Weex >>>';
+        },
+        methods: {
+            clicked: function() {
+                this.$openURL('http://github.com/alibaba/weex');
+            }
+        }
+    }
+</script>
\ No newline at end of file
diff --git a/weex-loader/test/index.html b/weex-loader/test/index.html
new file mode 100644
index 0000000..3faf460
--- /dev/null
+++ b/weex-loader/test/index.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Weex Loader Demo</title>
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<meta name="apple-mobile-web-app-status-bar-style" content="black" />
+<meta name="apple-touch-fullscreen" content="yes" />
+<meta name="format-detection" content="telephone=no, email=no" />
+<!--flexible-->
+<script>
+!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("The page size will be adapted by the <meta> info.");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=(a.navigator.appVersion.match(/android/gi),a.navigator.appVersion.match(/iphone/gi)),q=a.devicePixelRatio;i=p?q>=3&&(!i||i>=3)?3:q>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var r=e.createElement("div");r.appendChild(g),e.write(r.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));
+</script>
+<style>
+  body > h1 {
+    background-color: #666;
+    color: #EFEFEF;
+    padding: 10px;
+  }
+</style>
+</head>
+<body>
+<h1>[Test Case Actual]</h1>
+<div id="test_actual"></div>
+<br /><br /><br /><br /><br /><br />
+<h1>[Test Case Expect]</h1>
+<div id="test_expect"></div>
+<!-- jsframework -->
+<script src="./lib/jsfm.js"></script>
+<!-- h5render -->
+<script src="./lib/h5render.js"></script>
+<!-- entry -->
+<script>
+/**
+ * init weex instance depending on the url params.
+ * There are three ways to load weex bundles, depends on the
+ * parameter 'loader' in the url:
+ *
+ *   + xhr:   use XMLHttpRequest. Parameter 'page' should be
+ *   the bundle's url.
+ *   + jsonp: use jsonp. Parameter 'page' should be the request
+ *   url and jsonpCallback should be specified during calling
+ *   weex.init.
+ *   + source: use the transformed code itself. 'page' should
+ *   be the transformed weex bundle.
+ *
+ * @param {String}  bundle  It has different meaning depends on
+ *   the type of loader.
+ */
+(function () {
+  window.weex.init({
+    appId: 'actual/a.js',
+    loader: 'xhr',
+    source: './actual/a.js',
+    rootId: 'test_actual'
+  });
+
+  window.weex.init({
+    appId: 'expect/a.js',
+    loader: 'xhr',
+    source: './expect/a.js',
+    rootId: 'test_expect'
+  });
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/weex-loader/test/lib/c.js b/weex-loader/test/lib/c.js
new file mode 100644
index 0000000..1bdb562
--- /dev/null
+++ b/weex-loader/test/lib/c.js
@@ -0,0 +1 @@
+exports.name = 'Weex-Loader';
\ No newline at end of file
diff --git a/weex-loader/test/lib/d.js b/weex-loader/test/lib/d.js
new file mode 100644
index 0000000..a0a2f94
--- /dev/null
+++ b/weex-loader/test/lib/d.js
@@ -0,0 +1 @@
+exports.name = 'Alibaba Group';
\ No newline at end of file
diff --git a/weex-loader/test/lib/h5render.js b/weex-loader/test/lib/h5render.js
new file mode 100644
index 0000000..90cac01
--- /dev/null
+++ b/weex-loader/test/lib/h5render.js
@@ -0,0 +1,6965 @@
+(this.nativeLog || function(s) {console.log(s)})('START WEEX HTML5: 0.2.6');
+/******/ (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__) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict'
+  
+  __webpack_require__(1)
+  
+  var config = __webpack_require__(5)
+  var Loader = __webpack_require__(6)
+  var utils = __webpack_require__(7)
+  var protocol = __webpack_require__(8)
+  var ComponentManager = __webpack_require__(9)
+  var Component = __webpack_require__(16)
+  var Sender = __webpack_require__(19)
+  var receiver = __webpack_require__(20)
+  
+  // Components and apis.
+  var components = __webpack_require__(21)
+  var api = __webpack_require__(66)
+  __webpack_require__(96)
+  
+  var WEAPP_STYLE_ID = 'weapp-style'
+  
+  var DEFAULT_DESIGN_WIDTH = 750
+  var DEFAULT_ROOT_ID = 'weex'
+  var DEFAULT_JSON_CALLBACK_NAME = 'weexJsonpCallback'
+  
+  // config.scale = window.innerWidth / DEFAULT_DESIGN_WIDTH
+  
+  window.WXEnvironment = {
+    weexVersion: config.weexVersion,
+    appName: lib.env.aliapp ? lib.env.aliapp.appname : null,
+    appVersion: lib.env.aliapp ? lib.env.aliapp.version.val : null,
+    platform: lib.env.os ? lib.env.os.name : null,
+    osVersion: lib.env.os ? lib.env.os.version.val : null,
+    deviceHeight: window.innerHeight / config.scale
+  }
+  
+  var _instanceMap = {}
+  
+  function Weex(options) {
+  
+    if (!(this instanceof Weex)) {
+      return new Weex(options)
+    }
+  
+    // Width of the root container. Default is window.innerWidth.
+    this.width = options.width || window.innerWidth
+    this.bundleUrl = options.bundleUrl || location.href
+    this.instanceId = options.appId
+    this.rootId = options.rootId || (DEFAULT_ROOT_ID + utils.getRandom(10))
+    this.designWidth = options.designWidth || DEFAULT_DESIGN_WIDTH
+    this.jsonpCallback = options.jsonpCallback || DEFAULT_JSON_CALLBACK_NAME
+    this.source = options.source
+    this.loader = options.loader
+  
+    this.data = options.data
+  
+    this.initScale()
+    this.initComponentManager()
+    this.initBridge()
+    Weex.addInstance(this)
+  
+    protocol.injectWeexInstance(this)
+  
+    this.loadBundle(function (err, appCode) {
+      if (!err) {
+        this.createApp(config, appCode)
+      } else {
+        console.error('load bundle err:', err)
+      }
+    }.bind(this))
+  
+  }
+  
+  Weex.init = function (options) {
+    if (utils.isArray(options)) {
+      options.forEach(function (config) {
+        new Weex(config)
+      })
+    } else if (
+        Object.prototype.toString.call(options).slice(8, -1) === 'Object'
+      ) {
+      new Weex(options)
+    }
+  }
+  
+  Weex.addInstance = function (instance) {
+    _instanceMap[instance.instanceId] = instance
+  }
+  
+  Weex.getInstance = function (instanceId) {
+    return _instanceMap[instanceId]
+  }
+  
+  Weex.prototype = {
+  
+    initBridge: function () {
+      receiver.init(this)
+      this.sender = new Sender(this)
+    },
+  
+    loadBundle: function (cb) {
+      Loader.load({
+        jsonpCallback: this.jsonpCallback,
+        source: this.source,
+        loader: this.loader
+      }, cb)
+    },
+  
+    createApp: function (config, appCode) {
+      var root = document.querySelector('#' + this.rootId)
+      if (!root) {
+        root = document.createElement('div')
+        root.id = this.rootId
+        document.body.appendChild(root)
+      }
+  
+      var promise = window.createInstance(
+        this.instanceId
+        , appCode
+        , {
+          bundleUrl: this.bundleUrl,
+          debug: config.debug
+        }
+        , this.data
+      )
+  
+      if (Promise && promise instanceof Promise) {
+        promise.then(function () {
+          // Weex._instances[this.instanceId] = this.root
+        }.bind(this)).catch(function (err) {
+          if (err && config.debug) {
+            console.error(err)
+          }
+        })
+      }
+  
+      // Do not destroy instance here, because in most browser
+      // press back button to back to this page will not refresh
+      // the window and the instance will not be recreated then.
+      // window.addEventListener('beforeunload', function (e) {
+      // })
+  
+    },
+  
+    initScale: function () {
+      this.scale = this.width / this.designWidth
+    },
+  
+    initComponentManager: function () {
+      this._componentManager = new ComponentManager(this)
+    },
+  
+    getComponentManager: function () {
+      return this._componentManager
+    }
+  }
+  
+  Weex.appendStyle = function (css) {
+    utils.appendStyle(css, WEAPP_STYLE_ID)
+  },
+  
+  // Register a new component with the specified name.
+  Weex.registerComponent = function (name, comp) {
+    ComponentManager.registerComponent(name, comp)
+  },
+  
+  // Register a new api module.
+  // If the module already exists, just add methods from the
+  // new module to the old one.
+  Weex.registerApiModule = function (name, module, meta) {
+    if (!protocol.apiModule[name]) {
+      protocol.apiModule[name] = module
+    } else {
+      for (var key in module) {
+        if (module.hasOwnProperty(key)) {
+          protocol.apiModule[name][key] = module[key]
+        }
+      }
+    }
+    // register API module's meta info to jsframework
+    if (meta) {
+      protocol.setApiModuleMeta(meta)
+      window.registerModules(protocol.getApiModuleMeta(name), true)
+    }
+  },
+  
+  // Register a new api method for the specified module.
+  // opts:
+  //  - args: type of arguments the API method takes such
+  //    as ['string', 'function']
+  Weex.registerApi = function (moduleName, name, method, args) {
+    if (typeof method !== 'function') {
+      return
+    }
+    if (!protocol.apiModule[moduleName]) {
+      protocol.apiModule[moduleName] = {}
+      protocol._meta[moduleName] = []
+    }
+    protocol.apiModule[moduleName][name] = method
+    if (!args) {
+      return
+    }
+    // register API meta info to jsframework
+    protocol.setApiMeta(moduleName, {
+      name: name,
+      args: args
+    })
+    window.registerModules(protocol.getApiModuleMeta(moduleName, meta), true)
+  },
+  
+  // Register a new weex-bundle-loader.
+  Weex.registerLoader = function (name, loaderFunc) {
+    Loader.registerLoader(name, loaderFunc)
+  }
+  
+  // To install components and plugins.
+  Weex.install = function (mod) {
+    mod.init(Weex)
+  }
+  
+  Weex.stopTheWorld = function () {
+    for (var instanceId in _instanceMap) {
+      if (_instanceMap.hasOwnProperty(instanceId)) {
+        window.destroyInstance(instanceId)
+      }
+    }
+  }
+  
+  (function startRefreshController() {
+    if (location.search.indexOf('hot-reload_controller') === -1)  {
+      return
+    }
+    if (!window.WebSocket) {
+      console.info('auto refresh need WebSocket support')
+      return
+    }
+    var host = location.hostname
+    var port = 8082
+    var client = new WebSocket('ws://' + host + ':' + port + '/',
+      'echo-protocol'
+    )
+    client.onerror = function () {
+      console.log('refresh controller websocket connection error')
+    }
+    client.onmessage = function (e) {
+      console.log('Received: \'' + e.data + '\'')
+      if (e.data  === 'refresh') {
+        location.reload()
+      }
+    }
+  }())
+  
+  // Weex.install(require('weex-components'))
+  Weex.install(components)
+  Weex.install(api)
+  
+  Weex.Component = Component
+  Weex.ComponentManager = ComponentManager
+  Weex.utils = utils
+  Weex.config = config
+  
+  global.weex = Weex
+  module.exports = Weex
+  
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(2);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./base.scss", function() {
+        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./base.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 2 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, "* {\n  margin: 0;\n  padding: 0;\n  text-size-adjust: none; }\n\nul, ol {\n  list-style: none; }\n", "", {"version":3,"sources":["/./src/src/styles/base.scss"],"names":[],"mappings":"AAAA;EACE,UAAS;EACT,WAAU;EACV,uBACD,EAAC;;AACF;EACE,iBACD,EAAC","file":"base.scss","sourcesContent":["* {\n  margin:0;\n  padding:0;\n  text-size-adjust:none\n}\nul,ol {\n  list-style:none\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 3 */
+/***/ function(module, exports) {
+
+  /*
+    MIT License http://www.opensource.org/licenses/mit-license.php
+    Author Tobias Koppers @sokra
+  */
+  // css base code, injected by the css-loader
+  module.exports = function() {
+    var list = [];
+  
+    // return the list of modules as css string
+    list.toString = function toString() {
+      var result = [];
+      for(var i = 0; i < this.length; i++) {
+        var item = this[i];
+        if(item[2]) {
+          result.push("@media " + item[2] + "{" + item[1] + "}");
+        } else {
+          result.push(item[1]);
+        }
+      }
+      return result.join("");
+    };
+  
+    // import a list of modules into the list
+    list.i = function(modules, mediaQuery) {
+      if(typeof modules === "string")
+        modules = [[null, modules, ""]];
+      var alreadyImportedModules = {};
+      for(var i = 0; i < this.length; i++) {
+        var id = this[i][0];
+        if(typeof id === "number")
+          alreadyImportedModules[id] = true;
+      }
+      for(i = 0; i < modules.length; i++) {
+        var item = modules[i];
+        // skip already imported module
+        // this implementation is not 100% perfect for weird media query combinations
+        //  when a module is imported multiple times with different media queries.
+        //  I hope this will never occur (Hey this way we have smaller bundles)
+        if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
+          if(mediaQuery && !item[2]) {
+            item[2] = mediaQuery;
+          } else if(mediaQuery) {
+            item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
+          }
+          list.push(item);
+        }
+      }
+    };
+    return list;
+  };
+
+
+/***/ },
+/* 4 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /*
+    MIT License http://www.opensource.org/licenses/mit-license.php
+    Author Tobias Koppers @sokra
+  */
+  var stylesInDom = {},
+    memoize = function(fn) {
+      var memo;
+      return function () {
+        if (typeof memo === "undefined") memo = fn.apply(this, arguments);
+        return memo;
+      };
+    },
+    isOldIE = memoize(function() {
+      return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
+    }),
+    getHeadElement = memoize(function () {
+      return document.head || document.getElementsByTagName("head")[0];
+    }),
+    singletonElement = null,
+    singletonCounter = 0,
+    styleElementsInsertedAtTop = [];
+  
+  module.exports = function(list, options) {
+    if(false) {
+      if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
+    }
+  
+    options = options || {};
+    // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
+    // tags it will allow on a page
+    if (typeof options.singleton === "undefined") options.singleton = isOldIE();
+  
+    // By default, add <style> tags to the bottom of <head>.
+    if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
+  
+    var styles = listToStyles(list);
+    addStylesToDom(styles, options);
+  
+    return function update(newList) {
+      var mayRemove = [];
+      for(var i = 0; i < styles.length; i++) {
+        var item = styles[i];
+        var domStyle = stylesInDom[item.id];
+        domStyle.refs--;
+        mayRemove.push(domStyle);
+      }
+      if(newList) {
+        var newStyles = listToStyles(newList);
+        addStylesToDom(newStyles, options);
+      }
+      for(var i = 0; i < mayRemove.length; i++) {
+        var domStyle = mayRemove[i];
+        if(domStyle.refs === 0) {
+          for(var j = 0; j < domStyle.parts.length; j++)
+            domStyle.parts[j]();
+          delete stylesInDom[domStyle.id];
+        }
+      }
+    };
+  }
+  
+  function addStylesToDom(styles, options) {
+    for(var i = 0; i < styles.length; i++) {
+      var item = styles[i];
+      var domStyle = stylesInDom[item.id];
+      if(domStyle) {
+        domStyle.refs++;
+        for(var j = 0; j < domStyle.parts.length; j++) {
+          domStyle.parts[j](item.parts[j]);
+        }
+        for(; j < item.parts.length; j++) {
+          domStyle.parts.push(addStyle(item.parts[j], options));
+        }
+      } else {
+        var parts = [];
+        for(var j = 0; j < item.parts.length; j++) {
+          parts.push(addStyle(item.parts[j], options));
+        }
+        stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
+      }
+    }
+  }
+  
+  function listToStyles(list) {
+    var styles = [];
+    var newStyles = {};
+    for(var i = 0; i < list.length; i++) {
+      var item = list[i];
+      var id = item[0];
+      var css = item[1];
+      var media = item[2];
+      var sourceMap = item[3];
+      var part = {css: css, media: media, sourceMap: sourceMap};
+      if(!newStyles[id])
+        styles.push(newStyles[id] = {id: id, parts: [part]});
+      else
+        newStyles[id].parts.push(part);
+    }
+    return styles;
+  }
+  
+  function insertStyleElement(options, styleElement) {
+    var head = getHeadElement();
+    var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
+    if (options.insertAt === "top") {
+      if(!lastStyleElementInsertedAtTop) {
+        head.insertBefore(styleElement, head.firstChild);
+      } else if(lastStyleElementInsertedAtTop.nextSibling) {
+        head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
+      } else {
+        head.appendChild(styleElement);
+      }
+      styleElementsInsertedAtTop.push(styleElement);
+    } else if (options.insertAt === "bottom") {
+      head.appendChild(styleElement);
+    } else {
+      throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
+    }
+  }
+  
+  function removeStyleElement(styleElement) {
+    styleElement.parentNode.removeChild(styleElement);
+    var idx = styleElementsInsertedAtTop.indexOf(styleElement);
+    if(idx >= 0) {
+      styleElementsInsertedAtTop.splice(idx, 1);
+    }
+  }
+  
+  function createStyleElement(options) {
+    var styleElement = document.createElement("style");
+    styleElement.type = "text/css";
+    insertStyleElement(options, styleElement);
+    return styleElement;
+  }
+  
+  function createLinkElement(options) {
+    var linkElement = document.createElement("link");
+    linkElement.rel = "stylesheet";
+    insertStyleElement(options, linkElement);
+    return linkElement;
+  }
+  
+  function addStyle(obj, options) {
+    var styleElement, update, remove;
+  
+    if (options.singleton) {
+      var styleIndex = singletonCounter++;
+      styleElement = singletonElement || (singletonElement = createStyleElement(options));
+      update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
+      remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
+    } else if(obj.sourceMap &&
+      typeof URL === "function" &&
+      typeof URL.createObjectURL === "function" &&
+      typeof URL.revokeObjectURL === "function" &&
+      typeof Blob === "function" &&
+      typeof btoa === "function") {
+      styleElement = createLinkElement(options);
+      update = updateLink.bind(null, styleElement);
+      remove = function() {
+        removeStyleElement(styleElement);
+        if(styleElement.href)
+          URL.revokeObjectURL(styleElement.href);
+      };
+    } else {
+      styleElement = createStyleElement(options);
+      update = applyToTag.bind(null, styleElement);
+      remove = function() {
+        removeStyleElement(styleElement);
+      };
+    }
+  
+    update(obj);
+  
+    return function updateStyle(newObj) {
+      if(newObj) {
+        if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
+          return;
+        update(obj = newObj);
+      } else {
+        remove();
+      }
+    };
+  }
+  
+  var replaceText = (function () {
+    var textStore = [];
+  
+    return function (index, replacement) {
+      textStore[index] = replacement;
+      return textStore.filter(Boolean).join('\n');
+    };
+  })();
+  
+  function applyToSingletonTag(styleElement, index, remove, obj) {
+    var css = remove ? "" : obj.css;
+  
+    if (styleElement.styleSheet) {
+      styleElement.styleSheet.cssText = replaceText(index, css);
+    } else {
+      var cssNode = document.createTextNode(css);
+      var childNodes = styleElement.childNodes;
+      if (childNodes[index]) styleElement.removeChild(childNodes[index]);
+      if (childNodes.length) {
+        styleElement.insertBefore(cssNode, childNodes[index]);
+      } else {
+        styleElement.appendChild(cssNode);
+      }
+    }
+  }
+  
+  function applyToTag(styleElement, obj) {
+    var css = obj.css;
+    var media = obj.media;
+  
+    if(media) {
+      styleElement.setAttribute("media", media)
+    }
+  
+    if(styleElement.styleSheet) {
+      styleElement.styleSheet.cssText = css;
+    } else {
+      while(styleElement.firstChild) {
+        styleElement.removeChild(styleElement.firstChild);
+      }
+      styleElement.appendChild(document.createTextNode(css));
+    }
+  }
+  
+  function updateLink(linkElement, obj) {
+    var css = obj.css;
+    var sourceMap = obj.sourceMap;
+  
+    if(sourceMap) {
+      // http://stackoverflow.com/a/26603875
+      css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
+    }
+  
+    var blob = new Blob([css], { type: "text/css" });
+  
+    var oldSrc = linkElement.href;
+  
+    linkElement.href = URL.createObjectURL(blob);
+  
+    if(oldSrc)
+      URL.revokeObjectURL(oldSrc);
+  }
+
+
+/***/ },
+/* 5 */
+/***/ function(module, exports) {
+
+  'use strict'
+  
+  var config = {
+  
+    weexVersion: '1.4.0',
+  
+    debug: true
+  
+  }
+  
+  module.exports = config
+
+/***/ },
+/* 6 */
+/***/ function(module, exports) {
+
+  'use strict'
+  
+  function loadByXHR(config, callback) {
+    if (!config.source) {
+      callback(new Error('xhr loader: missing config.source.'))
+    }
+    var xhr = new XMLHttpRequest()
+    xhr.open('GET', config.source)
+    xhr.onload = function () {
+      callback(null, this.responseText)
+    }
+    xhr.onerror = function (error) {
+      callback(error)
+    }
+    xhr.send()
+  }
+  
+  function loadByJsonp(config, callback) {
+    if (!config.source) {
+      callback(new Error('jsonp loader: missing config.source.'))
+    }
+    var callbackName = config.jsonpCallback || 'weexJsonpCallback'
+    window[callbackName] = function (code) {
+      if (code) {
+        callback(null, code)
+      } else {
+        callback(new Error('load by jsonp error'))
+      }
+    }
+    var script = document.createElement('script')
+    script.src = decodeURIComponent(config.source)
+    script.type = 'text/javascript'
+    document.body.appendChild(script)
+  }
+  
+  function loadBySourceCode(config, callback) {
+    // src is the jsbundle.
+    // no need to fetch from anywhere.
+    if (config.source) {
+      callback(null, config.source)
+    } else {
+      callback(new Error('source code laoder: missing config.source.'))
+    }
+  }
+  
+  var callbackMap = {
+    xhr: loadByXHR,
+    jsonp: loadByJsonp,
+    source: loadBySourceCode
+  }
+  
+  function load(options, callback) {
+    var loadFn = callbackMap[options.loader]
+    loadFn(options, callback)
+  }
+  
+  function registerLoader(name, loaderFunc) {
+    if (typeof loaderFunc === 'function') {
+      callbackMap[name] = loaderFunc
+    }
+  }
+  
+  module.exports = {
+    load: load,
+    registerLoader: registerLoader
+  }
+
+
+/***/ },
+/* 7 */
+/***/ function(module, exports) {
+
+  'use strict'
+  
+  var WEAPP_STYLE_ID = 'weapp-style'
+  
+  var _isWebpSupported = false
+  
+  ; (function isSupportWebp() {
+    try {
+      var webP = new Image()
+      webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdA'
+                + 'SoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA'
+      webP.onload = function () {
+        if (webP.height === 2) {
+          _isWebpSupported = true
+        }
+      }
+    } catch (e) {
+      // do nothing.
+    }
+  })()
+  
+  function extend(to, from) {
+    for (var key in from) {
+      to[key] = from[key]
+    }
+    return to
+  }
+  
+  function isArray(arr) {
+    return Array.isArray
+      ? Array.isArray(arr)
+      : (Object.prototype.toString.call(arr) === '[object Array]')
+  }
+  
+  function appendStyle(css, styleId, replace) {
+    var style = document.getElementById(styleId)
+    if (style && replace) {
+      style.parentNode.removeChild(style)
+      style = null
+    }
+    if (!style) {
+      style = document.createElement('style')
+      style.type = 'text/css'
+      styleId && (style.id = styleId)
+      document.getElementsByTagName('head')[0].appendChild(style)
+    }
+    style.appendChild(document.createTextNode(css))
+  }
+  
+  function getUniqueFromArray(arr) {
+    if (!isArray(arr)) {
+      return []
+    }
+    var res = []
+    var unique = {}
+    var val
+    for (var i = 0, l = arr.length; i < l; i++) {
+      val = arr[i]
+      if (unique[val]) {
+        continue
+      }
+      unique[val] = true
+      res.push(val)
+    }
+    return res
+  }
+  
+  function transitionize(element, props) {
+    var transitions = []
+    for (var key in props) {
+      transitions.push(key + ' ' + props[key])
+    }
+    element.style.transition = transitions.join(', ')
+    element.style.webkitTransition = transitions.join(', ')
+  }
+  
+  function detectWebp() {
+    return _isWebpSupported
+  }
+  
+  function getRandom(num) {
+    var _defaultNum = 10
+    if (typeof num !== 'number' || num <= 0) {
+      num = _defaultNum
+    }
+    var _max = Math.pow(10, num)
+    return Math.floor(Date.now() + Math.random() * _max) % _max
+  }
+  
+  module.exports = {
+    extend: extend,
+    isArray: isArray,
+    appendStyle: appendStyle,
+    getUniqueFromArray: getUniqueFromArray,
+    transitionize: transitionize,
+    detectWebp: detectWebp,
+    getRandom: getRandom
+  }
+
+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var extend = __webpack_require__(7).extend
+  var isArray = __webpack_require__(7).isArray
+  var ComponentManager = __webpack_require__(9)
+  
+  // for jsframework to register modules.
+  var _registerModules = function (config) {
+    if (isArray(config)) {
+      for (var i = 0, l = config.length; i < l; i++) {
+        window.registerModules(config[i])
+      }
+    } else {
+      window.registerModules(config)
+    }
+  }
+  
+  var protocol = {
+  
+    // weex instances
+    _instances: [],
+  
+    // api meta info
+    _meta: [],
+  
+    apiModule: {},
+  
+    injectWeexInstance: function (instance) {
+      this._instances[instance.instanceId] = instance
+    },
+  
+    getWeexInstance: function (instanceId) {
+      return this._instances[instanceId]
+    },
+  
+    // get the api method meta info array for the module.
+    getApiModuleMeta: function (moduleName) {
+      var metaObj = {}
+      metaObj[moduleName] = this._meta[moduleName]
+      return metaObj
+    },
+  
+    // Set meta info for a api module.
+    // If there is a same named api, just replace it.
+    // opts:
+    // - metaObj: meta object like
+    // {
+    //    dom: [{
+    //      name: 'addElement',
+    //      args: ['string', 'object']
+    //    }]
+    // }
+    setApiModuleMeta: function (metaObj) {
+      var moduleName
+      for (var k in metaObj) {
+        if (metaObj.hasOwnProperty(k)) {
+          moduleName = k
+        }
+      }
+      var metaArray = this._meta[moduleName]
+      if (!metaArray) {
+        this._meta[moduleName] = metaObj[moduleName]
+      } else {
+        var nameObj = {}
+        metaObj[moduleName].forEach(function (api) {
+          nameObj[api.name] = api
+        })
+        metaArray.forEach(function (api, i) {
+          if (nameObj[api.name]) {
+            metaArray[i] = nameObj[api.name]
+            delete nameObj[api.name]
+          }
+        })
+        for (var k in metaObj) {
+          if (metaObj.hasOwnProperty(k)) {
+            metaArray.push(metaObj[k])
+          }
+        }
+      }
+      this._meta[moduleName] = metaObj[moduleName]
+    },
+  
+    // Set meta info for a single api.
+    // opts:
+    //  - moduleName: api module name.
+    //  - meta: a meta object like:
+    //  {
+    //    name: 'addElement',
+    //    args: ['string', 'object']
+    //  }
+    setApiMeta: function (moduleName, meta) {
+      var metaArray = this._meta[moduleName]
+      if (!metaArray) {
+        this._meta[moduleName] = [meta]
+      } else {
+        var metaIdx = -1
+        metaArray.forEach(function (api, i) {
+          if (meta.name === name) {
+            metaIdx = i
+          }
+        })
+        if (metaIdx !== -1) {
+          metaArray[metaIdx] = meta
+        } else {
+          metaArray.push(meta)
+        }
+      }
+    }
+  }
+  
+  _registerModules([{
+    modal: [{
+      name: 'toast',
+      args: ['object', 'function']
+    }, {
+      name: 'alert',
+      args: ['object', 'function']
+    }, {
+      name: 'confirm',
+      args: ['object', 'function']
+    }, {
+      name: 'prompt',
+      args: ['object', 'function']
+    }]
+  }, {
+    animation: [{
+      name: 'transition',
+      args: ['string', 'object', 'function']
+    }]
+  }])
+  
+  module.exports = protocol
+
+
+/***/ },
+/* 9 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var config = __webpack_require__(5)
+  var FrameUpdater = __webpack_require__(10)
+  var AppearWatcher = __webpack_require__(11)
+  var utils = __webpack_require__(7)
+  var LazyLoad = __webpack_require__(12)
+  var animation = __webpack_require__(15)
+  
+  var RENDERING_INDENT = 800
+  
+  var _instanceMap = {}
+  var typeMap = {}
+  var scrollableTypes = ['scroller', 'list']
+  
+  function ComponentManager(instance) {
+    this.instanceId = instance.instanceId
+    this.weexInstance = instance
+    this.componentMap = {}
+    _instanceMap[this.instanceId] = this
+  }
+  
+  ComponentManager.getInstance = function (instanceId) {
+    return _instanceMap[instanceId]
+  }
+  
+  ComponentManager.getWeexInstance = function (instanceId) {
+    return _instanceMap[instanceId].weexInstance
+  }
+  
+  ComponentManager.registerComponent = function (type, definition) {
+    typeMap[type] = definition
+  }
+  
+  ComponentManager.getScrollableTypes = function () {
+    return scrollableTypes
+  }
+  
+  ComponentManager.prototype = {
+  
+    // Fire a event 'renderbegin'/'renderend' on body element.
+    rendering: function () {
+      function _renderingEnd() {
+        // get weex instance root
+        window.dispatchEvent(new Event('renderend'))
+        this._renderingTimer = null
+      }
+      if (this._renderingTimer) {
+        clearTimeout(this._renderingTimer)
+        this._renderingTimer = setTimeout(
+          _renderingEnd.bind(this),
+          RENDERING_INDENT
+        )
+      } else {
+        window.dispatchEvent(new Event('renderbegin'))
+        this._renderingTimer = setTimeout(
+          _renderingEnd.bind(this),
+          RENDERING_INDENT
+        )
+      }
+    },
+  
+    getElementByRef: function (ref) {
+      return this.componentMap[ref]
+    },
+  
+    removeElementByRef: function (ref) {
+      var cmp
+      var self = this
+      if (!ref || !(cmp = this.componentMap[ref])) {
+        return
+      }
+      // remove from this.componentMap cursively
+      (function _removeCursively(_ref) {
+        var child = self.componentMap[_ref]
+        var listeners = child._listeners
+        var children = child.data.children
+        if (children && children.length) {
+          for (var i = 0, l = children.length; i < l; i++) {
+            _removeCursively(children[i].ref)
+          }
+        }
+        // remove events from _ref component
+        if (listeners) {
+          for (var type in listeners) {
+            child.node.removeEventListener(type, listeners[type])
+          }
+        }
+        delete child._listeners
+        delete child.node._listeners
+        // remove _ref component
+        delete self.componentMap[_ref]
+      })(ref)
+  
+    },
+  
+    createElement: function (data, nodeType) {
+      var ComponentType = typeMap[data.type]
+      if (!ComponentType) {
+        ComponentType = typeMap['container']
+      }
+  
+      var ref = data.ref
+      var component = new ComponentType(data, nodeType)
+  
+      this.componentMap[ref] = component
+      component.node.setAttribute('data-ref', ref)
+  
+      return component
+    },
+  
+    /**
+     * createBody: generate root component
+     * @param  {object} element
+     */
+    createBody: function (element) {
+  
+      // TODO: creatbody on document.body
+      // no need to create a extra div
+      var root, body, nodeType
+      if (this.componentMap['_root']) {
+        return
+      }
+  
+      nodeType = element.type
+      element.type = 'root'
+      element.rootId = this.weexInstance.rootId
+      element.ref = '_root'
+  
+      var root = this.createElement(element, nodeType)
+      body = document.querySelector('#' + this.weexInstance.rootId)
+            || document.body
+      body.appendChild(root.node)
+      root._appended = true
+    },
+  
+    appendChild: function (parentRef, data) {
+      var parent = this.componentMap[parentRef]
+  
+      if (this.componentMap[data.ref] || !parent) {
+        return
+      }
+  
+      if (parentRef === '_root' && !parent) {
+        parent = this.createElement({
+          type: 'root',
+          rootId: this.weexInstance.rootId,
+          ref: '_root'
+        })
+        parent._appended = true
+      }
+  
+      var child = parent.appendChild(data)
+  
+      // In some parent component the implementation of method
+      // appendChild didn't return the component at all, therefor
+      // child maybe a undefined object.
+      if (child) {
+        child.parentRef = parentRef
+      }
+  
+      if (child && parent._appended) {
+        this.handleAppend(child)
+      }
+    },
+  
+    appendChildren: function (ref, elements) {
+      for (var i = 0; i < elements.length; i++) {
+        this.appendChild(ref, elements[i])
+      }
+    },
+  
+    removeElement: function (ref) {
+      var component = this.componentMap[ref]
+  
+      // fire event for rendering dom on body elment.
+      this.rendering()
+  
+      if (component && component.parentRef) {
+        var parent = this.componentMap[component.parentRef]
+        component.onRemove && component.onRemove()
+        parent.removeChild(component)
+      } else {
+        console.warn('ref: ', ref)
+      }
+    },
+  
+    moveElement: function (ref, parentRef, index) {
+      var component = this.componentMap[ref]
+      var newParent = this.componentMap[parentRef]
+      var oldParentRef = component.parentRef
+      var children, before, i, l
+      if (!component || !newParent) {
+        console.warn('ref: ', ref)
+        return
+      }
+  
+      // fire event for rendering dom on body elment.
+      this.rendering()
+  
+      // remove from oldParent.data.children
+      if (oldParentRef && this.componentMap[oldParentRef]) {
+        children = this.componentMap[oldParentRef].data.children
+        if (children && children.length) {
+          for (i = 0, l = children.length; i < l; i++) {
+            if (children[i].ref === ref) {
+              break
+            }
+          }
+          if (l > i) {
+            children.splice(i, 1)
+          }
+        }
+      }
+  
+      if (index < -1) {
+        index = -1
+        console.warn('index cannot be less than -1.')
+      }
+  
+      children = newParent.data.children
+      if (children
+          && children.length
+          && index !== -1
+          && index < children.length) {
+        before = this.componentMap[newParent.data.children[index].ref]
+        newParent.insertBefore(component, before)
+      } else {  // append
+        newParent.insertBefore(component)
+      }
+  
+      component.onMove && component.onMove(parentRef, index)
+  
+    },
+  
+    insertBefore: function (ref, data) {
+      var child, before, parent
+      before = this.componentMap[ref]
+      child = this.componentMap[data.ref]
+      before && (parent = this.componentMap[before.parentRef])
+      if (child || !parent || !before) {
+        return
+      }
+  
+      child = this.createElement(data)
+      if (child) {
+        child.parentRef = before.parentRef
+        parent.insertBefore(child, before)
+      } else {
+        return
+      }
+  
+      if (this.componentMap[before.parentRef]._appended) {
+        this.handleAppend(child)
+      }
+    },
+  
+    /**
+     * addElement
+     * If index is larget than any child's index, the
+     * element will be appended behind.
+     * @param {string} parentRef
+     * @param {obj} element (data of the component)
+     * @param {number} index
+     */
+    addElement: function (parentRef, element, index) {
+      var parent, children, before
+  
+      // fire event for rendering dom on body elment.
+      this.rendering()
+  
+      parent = this.componentMap[parentRef]
+      if (!parent) {
+        return
+      }
+      children = parent.data.children
+      // -1 means append as the last.
+      if (index < -1) {
+        index = -1
+        console.warn('index cannot be less than -1.')
+      }
+      if (children && children.length
+          && children.length > index
+          && index !== -1) {
+        this.insertBefore(children[index].ref, element)
+      } else {
+        this.appendChild(parentRef, element)
+      }
+    },
+  
+    clearChildren: function (ref) {
+      var component = this.componentMap[ref]
+      if (component) {
+        component.node.innerHTML = ''
+        if (component.data) {
+          component.data.children = null
+        }
+      }
+    },
+  
+    addEvent: function (ref, type) {
+      var component
+      if (typeof ref === 'string' || typeof ref === 'number') {
+        component = this.componentMap[ref]
+      } else if (Object.prototype.toString.call(ref).slice(8, -1) === 'Object') {
+        component = ref
+        ref = component.data.ref
+      }
+      if (component && component.node) {
+        var sender = this.weexInstance.sender
+        var listener = sender.fireEvent.bind(sender, ref, type)
+        var listeners = component._listeners
+        component.node.addEventListener(type, listener, false, false)
+        if (!listeners) {
+          listeners = component._listeners = {}
+          component.node._listeners = {}
+        }
+        listeners[type] = listener
+        component.node._listeners[type] = listener
+      }
+    },
+  
+    removeEvent: function (ref, type) {
+      var component = this.componentMap[ref]
+      var listener = component._listeners[type]
+      if (component && listener) {
+        component.node.removeEventListener(type, listener)
+        component._listeners[type] = null
+        component.node._listeners[type] = null
+      }
+    },
+  
+    updateAttrs: function (ref, attr) {
+      var component = this.componentMap[ref]
+      if (component) {
+        component.updateAttrs(attr)
+        if (component.data.type === 'image' && attr.src) {
+          LazyLoad.startIfNeeded(component)
+        }
+      }
+    },
+  
+    updateStyle: function (ref, style) {
+      var component = this.componentMap[ref]
+      if (component) {
+        component.updateStyle(style)
+      }
+    },
+  
+    updateFullAttrs: function (ref, attr) {
+      var component = this.componentMap[ref]
+      if (component) {
+        component.clearAttr()
+        component.updateAttrs(attr)
+        if (component.data.type === 'image' && attr.src) {
+          LazyLoad.startIfNeeded(component)
+        }
+      }
+    },
+  
+    updateFullStyle: function (ref, style) {
+      var component = this.componentMap[ref]
+      if (component) {
+        component.clearStyle()
+        component.updateStyle(style)
+      }
+    },
+  
+    handleAppend: function (component) {
+      component._appended = true
+      component.onAppend && component.onAppend()
+  
+      // invoke onAppend on children recursively
+      var children = component.data.children
+      if (children) {
+        for (var i = 0; i < children.length; i++) {
+          var child = this.componentMap[children[i].ref]
+          if (child) {
+            this.handleAppend(child)
+          }
+        }
+      }
+  
+      // watch appear/disappear of the component if needed
+      AppearWatcher.watchIfNeeded(component)
+  
+      // do lazyload if needed
+      LazyLoad.startIfNeeded(component)
+    },
+  
+    transition: function (ref, config, callback) {
+      var component = this.componentMap[ref]
+      animation.transitionOnce(component, config, callback)
+    },
+  
+    renderFinish: function () {
+      FrameUpdater.pause()
+    }
+  }
+  
+  module.exports = ComponentManager
+
+
+/***/ },
+/* 10 */
+/***/ function(module, exports) {
+
+  'use strict'
+  
+  var raf = window.requestAnimationFrame ||
+            window.webkitRequestAnimationFrame ||
+            function (calllback) {
+              setTimeout(calllback, 16)
+            }
+  
+  var rafId
+  var observers = []
+  var paused = false
+  
+  var FrameUpdater = {
+    start: function () {
+      if (rafId) {
+        return
+      }
+  
+      rafId = raf(function runLoop() {
+        if (!paused) {
+          for (var i = 0; i < observers.length; i++) {
+            observers[i]()
+          }
+          raf(runLoop)
+        }
+      })
+    },
+  
+    isActive: function () {
+      return !paused
+    },
+  
+    pause: function () {
+      paused = true
+      rafId = undefined
+    },
+  
+    resume: function () {
+      paused = false
+      this.start()
+    },
+  
+    addUpdateObserver: function (observeMethod) {
+      observers.push(observeMethod)
+    }
+  }
+  
+  module.exports = FrameUpdater
+
+
+/***/ },
+/* 11 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var utils = __webpack_require__(7)
+  
+  var componentsInScroller = []
+  var componentsOutOfScroller = []
+  var listened = false
+  var direction = 'up'
+  var scrollY = 0
+  
+  var AppearWatcher = {
+    watchIfNeeded: function (component) {
+      if (needWatch(component)) {
+        if (component.isInScrollable()) {
+          componentsInScroller.push(component)
+        } else {
+          componentsOutOfScroller.push(component)
+        }
+        if (!listened) {
+          listened = true
+          // var handler = throttle(onScroll, 25)
+          var handler = throttle(onScroll, 100)
+          window.addEventListener('scroll', handler, false)
+        }
+      }
+    }
+  }
+  
+  function needWatch(component) {
+    var events = component.data.event
+    if (events
+        && (events.indexOf('appear') != -1
+          || events.indexOf('disappear') != -1)) {
+      return true
+    }
+    return false
+  }
+  
+  function onScroll(e) {
+    // If the scroll event is dispatched from a scrollable component
+    // implemented through scrollerjs, then the appear/disappear events
+    // should be treated specially by handleScrollerScroll.
+    if (e.originalType === 'scrolling') {
+      handleScrollerScroll()
+    } else {
+      handleWindowScroll()
+    }
+  }
+  
+  function handleScrollerScroll() {
+    var cmps = componentsInScroller
+    var len = cmps.length
+    for (var i = 0; i < len; i++) {
+      var component = cmps[i]
+      var appear = isComponentInScrollerAppear(component)
+      if (appear && !component._appear) {
+        component._appear = true
+        fireEvent(component, 'appear')
+      } else if (!appear && component._appear) {
+        component._appear = false
+        fireEvent(component, 'disappear')
+      }
+    }
+  }
+  
+  function handleWindowScroll() {
+    var y = window.scrollY
+    direction = y >= scrollY ? 'up' : 'down'
+    scrollY = y
+  
+    var len = componentsOutOfScroller.length
+    if (len === 0) {
+      return
+    }
+    for (var i = 0; i < len; i++) {
+      var component = componentsOutOfScroller[i]
+      var appear = isComponentInWindow(component)
+      if (appear && !component._appear) {
+        component._appear = true
+        fireEvent(component, 'appear')
+      } else if (!appear && component._appear) {
+        component._appear = false
+        fireEvent(component, 'disappear')
+      }
+    }
+  }
+  
+  function isComponentInScrollerAppear(component) {
+    var parentScroller = component._parentScroller
+    var cmpRect = component.node.getBoundingClientRect()
+    if (!isComponentInWindow(component)) {
+      return false
+    }
+    while (parentScroller) {
+      var parentRect = parentScroller.node.getBoundingClientRect()
+      if (!(cmpRect.right > parentRect.left
+          && cmpRect.left < parentRect.right
+          && cmpRect.bottom > parentRect.top
+          && cmpRect.top < parentRect.bottom)) {
+        return false
+      }
+      parentScroller = parentScroller._parentScroller
+    }
+    return true
+  }
+  
+  function isComponentInWindow(component) {
+    var rect = component.node.getBoundingClientRect()
+    return rect.right > 0 && rect.left < window.innerWidth &&
+           rect.bottom > 0 && rect.top < window.innerHeight
+  }
+  
+  function fireEvent(component, type) {
+    var evt = document.createEvent('HTMLEvents')
+    var data = { direction: direction }
+    evt.initEvent(type, false, false)
+    evt.data = data
+    utils.extend(evt, data)
+    component.node.dispatchEvent(evt)
+  }
+  
+  function throttle(func, wait) {
+    var context, args, result
+    var timeout = null
+    var previous = 0
+    var later = function () {
+      previous = Date.now()
+      timeout = null
+      result = func.apply(context, args)
+    }
+    return function () {
+      var now = Date.now()
+      var remaining = wait - (now - previous)
+      context = this
+      args = arguments
+      if (remaining <= 0) {
+        clearTimeout(timeout)
+        timeout = null
+        previous = now
+        result = func.apply(context, args)
+      } else if (!timeout) {
+        timeout = setTimeout(later, remaining)
+      }
+      return result
+    }
+  }
+  
+  module.exports = AppearWatcher
+
+/***/ },
+/* 12 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  __webpack_require__(13)
+  
+  var lazyloadTimer
+  
+  var LazyLoad = {
+    makeImageLazy: function (image, src) {
+      image.removeAttribute('img-src')
+      image.removeAttribute('i-lazy-src')
+      image.removeAttribute('src')
+      image.setAttribute('img-src', src)
+      // should replace 'src' with 'img-src'. but for now lib.img.fire is
+      // not working for the situation that the appear event has been
+      // already triggered.
+      // image.setAttribute('src', src)
+      // image.setAttribute('img-src', src)
+      this.fire()
+    },
+  
+    // we don't know when all image are appended
+    // just use setTimeout to do delay lazyload
+    //
+    // -- actually everytime we add a element or update styles,
+    // the component manager will call startIfNeed to fire
+    // lazyload once again in the handleAppend function. so there
+    // is no way that any image element can miss it. See source
+    // code in componentMangager.js.
+    startIfNeeded: function (component) {
+      var that = this
+      if (component.data.type === 'image') {
+        if (!lazyloadTimer) {
+          lazyloadTimer = setTimeout(function () {
+            that.fire()
+            clearTimeout(lazyloadTimer)
+            lazyloadTimer = null
+          }, 16)
+        }
+      }
+    },
+  
+    loadIfNeeded: function (elementScope) {
+      var notPreProcessed = elementScope.querySelectorAll('[img-src]')
+      var that = this
+      // image elements which have attribute 'i-lazy-src' were elements
+      // that had been preprocessed by lib-img-core, but not loaded yet, and
+      // must be loaded when 'appear' events were fired. It turns out the
+      // 'appear' event was not fired correctly in the css-translate-transition
+      // situation, so 'i-lazy-src' must be checked and lazyload must be
+      // fired manually.
+      var preProcessed = elementScope.querySelectorAll('[i-lazy-src]')
+      if (notPreProcessed.length > 0 || preProcessed.length > 0) {
+        that.fire()
+      }
+    },
+  
+    // fire lazyload.
+    fire: function () {
+      lib.img.fire()
+    }
+  
+  }
+  
+  module.exports = LazyLoad
+
+
+/***/ },
+/* 13 */
+/***/ function(module, exports, __webpack_require__) {
+
+  "undefined"==typeof window&&(window={ctrl:{},lib:{}}),!window.ctrl&&(window.ctrl={}),!window.lib&&(window.lib={}),function(t,i){function e(t,i){i&&("IMG"==t.nodeName.toUpperCase()?t.setAttribute("src",i):t.style.backgroundImage='url("'+i+'")')}function a(){r=i.appear.init({cls:"imgtmp",once:!0,x:o.lazyWidth,y:o.lazyHeight,onAppear:function(t){var i=this;e(i,i.getAttribute("i-lazy-src")),i.removeAttribute("i-lazy-src")}})}__webpack_require__(14);var r,A={},o={dataSrc:"img-src",lazyHeight:0,lazyWidth:0};A.logConfig=function(){console.log("lib-img Config\n",o)},A.fire=function(){r||a();var t="i_"+Date.now()%1e5,i=document.querySelectorAll("["+o.dataSrc+"]");[].forEach.call(i,function(i){"false"==i.dataset.lazy&&"true"!=i.dataset.lazy?e(i,processSrc(i,i.getAttribute(o.dataSrc))):(i.classList.add(t),i.setAttribute("i-lazy-src",i.getAttribute(o.dataSrc))),i.removeAttribute(o.dataSrc)}),r.bind("."+t),r.fire()},A.defaultSrc="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==",i.img=A,module.exports=A}(window,window.lib||(window.lib={}));
+
+/***/ },
+/* 14 */
+/***/ function(module, exports) {
+
+  "undefined"==typeof window&&(window={ctrl:{},lib:{}}),!window.ctrl&&(window.ctrl={}),!window.lib&&(window.lib={}),function(n,e){function i(){d=w.createEvent("HTMLEvents"),v=w.createEvent("HTMLEvents"),d.initEvent("_appear",!1,!0),v.initEvent("_disappear",!1,!0)}function a(t,n){var e,i,a,s=(Date.now(),0),o=null,r=function(){s=Date.now(),o=null,t.apply(e,i)};return function(){var l=Date.now();e=this,i=arguments;var c=n-(l-s);return 0>=c||c>=n?(clearTimeout(o),o=null,a=t.apply(e,i)):null==o&&(o=setTimeout(r,c)),a}}function s(n,e){var n,i,a,s;if(n)return e||(e={x:0,y:0}),n!=window?(n=n.getBoundingClientRect(),i=n.left,t=n.top,a=n.right,s=n.bottom):(i=0,t=0,a=i+n.innerWidth,s=t+n.innerHeight),{left:i,top:t,right:a+e.x,bottom:s+e.y}}function o(t,n){var e=n.right>t.left&&n.left<t.right,i=n.bottom>t.top&&n.top<t.bottom;return e&&i}function r(t,n){var e="none",i=t.left-n.left,a=t.top-n.top;return 0==a&&(e=0!=i?i>0?"left":"right":"none"),0==i&&(e=0!=a?a>0?"up":"down":"none"),e}function l(t,n){for(var e in n)n.hasOwnProperty(e)&&(t[e]=n[e]);return t}function c(){var t=this,n=a(function(){f.apply(t,arguments)},this.options.wait);this.__handle&&(this.container.removeEventListener("scroll",this.__handle),this.__handle=null),this.__handle=n,this.container.addEventListener("scroll",n,!1),this.container.addEventListener("resize",function(n){f.apply(t,arguments)},!1),this.container.addEventListener("animationEnd",function(){f.apply(t,arguments)},!1),this.container.addEventListener("webkitAnimationEnd",function(){f.apply(t,arguments)},!1),this.container.addEventListener("transitionend",function(){f.apply(t,arguments)},!1)}function p(t){var n=this,e=this.options.container;if("string"==typeof e?this.container=w.querySelector(e):this.container=e,this.container==window)var i=w.querySelectorAll(t);else var i=this.container.querySelectorAll(t);var i=[].slice.call(i,null);return i=i.filter(function(t){return"1"==t.dataset.bind?(delete t._hasAppear,delete t._hasDisAppear,delete t._appear,t.classList.remove(n.options.cls),!1):!0})}function h(t){var n=this;t&&t.length>0&&[].forEach.call(t,function(t){t._eleOffset=s(t),t.classList.remove(n.options.cls),t.dataset.bind=1})}function f(){var t=this.container,n=this.appearWatchElements,e=this.options.onAppear,i=this.options.onDisappear,a=s(t,{x:this.options.x,y:this.options.y}),l=this.options.once,c=arguments[0]||{};n&&n.length>0&&[].forEach.call(n,function(t,n){var p=s(t),h=r(t._eleOffset,p);t._eleOffset=p;var f=o(a,p),u=t._appear,w=t._hasAppear,E=t._hasDisAppear;d.data={direction:h},v.data={direction:h},f&&!u?(l&&!w||!l)&&(e&&e.call(t,c),t.dispatchEvent(d),t._hasAppear=!0,t._appear=!0):!f&&u&&(l&&!E||!l)&&(i&&i.call(t,c),t.dispatchEvent(v),t._hasDisAppear=!0,t._appear=!1)})}function u(t){l(this.options,t||(t={})),this.appearWatchElements=this.appearWatchElements||p.call(this,"."+this.options.cls),h.call(this,this.appearWatchElements),c.call(this)}var d,v,w=document,E=function(){u.apply(this,arguments)},_={instances:[],init:function(t){var n={options:{container:window,wait:100,x:0,y:0,cls:"lib-appear",once:!1,onReset:function(){},onAppear:function(){},onDisappear:function(){}},container:null,appearWatchElements:null,bind:function(t){var n=this.options.cls;if("string"==typeof t){var e=p.call(this,t);[].forEach.call(e,function(t,e){t.classList.contains(n)||t.classList.add(n)})}else{if(1!=t.nodeType||!this.container.contains(t))return this;t.classList.contains(n)||t.classList.add(n)}var i=p.call(this,"."+this.options.cls);return this.appearWatchElements=this.appearWatchElements.concat(i),h.call(this,i),this},reset:function(t){return u.call(this,t),this.appearWatchElements.forEach(function(t){delete t._hasAppear,delete t._hasDisAppear,delete t._appear}),this},fire:function(){this.appearWatchElements||(this.appearWatchElements=[]);var t=p.call(this,"."+this.options.cls);return this.appearWatchElements=this.appearWatchElements.concat(t),h.call(this,t),f.call(this),this}};E.prototype=n;var e=new E(t);return this.instances.push(e),e},fireAll:function(){var t=this.instances;t.forEach(function(t){t.fire()})}};i(),e.appear=_}(window,window.lib||(window.lib={}));
+
+/***/ },
+/* 15 */
+/***/ function(module, exports) {
+
+  'use strict'
+  
+  module.exports = {
+  
+    /**
+     * config:
+     *   - styles
+     *   - duration [Number] milliseconds(ms)
+     *   - timingFunction [string]
+     *   - dealy [Number] milliseconds(ms)
+     */
+    transitionOnce: function (comp, config, callback) {
+      var styles = config.styles || {}
+      var duration = config.duration || 1000 // ms
+      var timingFunction = config.timingFunction || 'ease'
+      var delay = config.delay || 0  // ms
+      var transitionValue = 'all ' + duration + 'ms '
+          + timingFunction + ' ' + delay + 'ms'
+      var dom = comp.node
+      var transitionEndHandler = function (e) {
+        e.stopPropagation()
+        dom.removeEventListener('webkitTransitionEnd', transitionEndHandler)
+        dom.removeEventListener('transitionend', transitionEndHandler)
+        dom.style.transition = ''
+        dom.style.webkitTransition = ''
+        callback()
+      }
+      dom.style.transition = transitionValue
+      dom.style.webkitTransition = transitionValue
+      dom.addEventListener('webkitTransitionEnd', transitionEndHandler)
+      dom.addEventListener('transitionend', transitionEndHandler)
+      comp.updateStyle(styles)
+    }
+  
+  }
+
+/***/ },
+/* 16 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var config = __webpack_require__(5)
+  var utils = __webpack_require__(7)
+  var ComponentManager = __webpack_require__(9)
+  var flexbox = __webpack_require__(17)
+  __webpack_require__(18)
+  
+  function Component(data, nodeType) {
+    this.data = data
+    this.node = this.create(nodeType)
+  
+    this.createChildren()
+    this.updateAttrs(this.data.attr)
+    // issue: when add element to a list in lifetime hook 'ready', the
+    // styles is set to the classStyle, not style. This is a issue
+    // that jsframework should do something about.
+    var classStyle = this.data.classStyle
+    classStyle && this.updateStyle(this.data.classStyle)
+    this.updateStyle(this.data.style)
+    this.bindEvents(this.data.event)
+  }
+  
+  Component.prototype = {
+  
+    create: function (nodeType) {
+      var node = document.createElement(nodeType || 'div')
+      return node
+    },
+  
+    getComponentManager: function () {
+      return ComponentManager.getInstance(this.data.instanceId)
+    },
+  
+    getParent: function () {
+      return this.getComponentManager().componentMap[this.parentRef]
+    },
+  
+    isScrollable: function () {
+      var t = this.data.type
+      return ComponentManager.getScrollableTypes().indexOf(t) !== -1
+    },
+  
+    isInScrollable: function () {
+      if (typeof this._isInScrollable === 'boolean') {
+        return this._isInScrollable
+      }
+      var parent = this.getParent()
+      if (parent
+          && (typeof parent._isInScrollable !== 'boolean')
+          && !parent.isScrollable()) {
+        if (parent.data.type === 'root') {
+          this._isInScrollable = false
+          return false
+        }
+        this._isInScrollable = parent.isInScrollable()
+        this._parentScroller = parent._parentScroller
+        return this._isInScrollable
+      }
+      if (typeof parent._isInScrollable === 'boolean') {
+        this._isInScrollable = parent._isInScrollable
+        this._parentScroller = parent._parentScroller
+        return this._isInScrollable
+      }
+      if (parent.isScrollable()) {
+        this._isInScrollable = true
+        this._parentScroller = parent
+        return true
+      }
+      if (!parent) {
+        console && console.error('isInScrollable - parent not exist.')
+      }
+    },
+  
+    createChildren: function () {
+      var children = this.data.children
+      var parentRef = this.data.ref
+      var componentManager = this.getComponentManager()
+      if (children && children.length) {
+        var fragment = document.createDocumentFragment()
+        var isFlex = false
+        for (var i = 0; i < children.length; i++) {
+          children[i].instanceId = this.data.instanceId
+          children[i].scale = this.data.scale
+          var child = componentManager.createElement(children[i])
+          fragment.appendChild(child.node)
+          child.parentRef = parentRef
+          if (!isFlex
+              && child.data.style
+              && child.data.style.hasOwnProperty('flex')
+            ) {
+            isFlex = true
+          }
+        }
+        this.node.appendChild(fragment)
+      }
+    },
+  
+    // @todo: changed param data to child
+    appendChild: function (data) {
+      var children = this.data.children
+      var componentManager = this.getComponentManager()
+      var child = componentManager.createElement(data)
+      this.node.appendChild(child.node)
+      // update this.data.children
+      if (!children || !children.length) {
+        this.data.children = [data]
+      } else {
+        children.push(data)
+      }
+  
+      return child
+    },
+  
+    insertBefore: function (child, before) {
+      var children = this.data.children
+      var i = 0
+      var l
+      var isAppend = false
+  
+      // update this.data.children
+      if (!children || !children.length || !before) {
+        isAppend = true
+      } else {
+        for (l = children.length; i < l; i++) {
+          if (children[i].ref === before.data.ref) {
+            break
+          }
+        }
+        if (i === l) {
+          isAppend = true
+        }
+      }
+  
+  
+      if (isAppend) {
+        this.node.appendChild(child.node)
+        children.push(child.data)
+      } else {
+        this.node.insertBefore(child.node, before.node)
+        children.splice(i, 0, child.data)
+      }
+  
+    },
+  
+    removeChild: function (child) {
+      var children = this.data.children
+      // remove from this.data.children
+      var i = 0
+      var componentManager = this.getComponentManager()
+      if (children && children.length) {
+        for (var l = children.length; i < l; i++) {
+          if (children[i].ref === child.data.ref) {
+            break
+          }
+        }
+        if (i < l) {
+          children.splice(i, 1)
+        }
+      }
+      // remove from componentMap recursively
+      componentManager.removeElementByRef(child.data.ref)
+      this.node.removeChild(child.node)
+    },
+  
+    updateAttrs: function (attrs) {
+      // Note:attr must be injected into the dom element because
+      // it will be accessed from the outside developer by event.target.attr.
+      if (!this.node.attr) {
+        this.node.attr = {}
+      }
+      for (var key in attrs) {
+        var value = attrs[key]
+        var attrSetter = this.attr[key]
+        if (typeof attrSetter === 'function') {
+          attrSetter.call(this, value)
+        } else {
+          if (typeof value === 'boolean') {
+            this.node[key] = value
+          } else {
+            this.node.setAttribute(key, value)
+          }
+          this.node.attr[key] = value
+        }
+      }
+    },
+  
+    updateStyle: function (style) {
+      for (var key in style) {
+        var value = style[key]
+        var styleSetter = this.style[key]
+  
+        if (typeof styleSetter === 'function') {
+          styleSetter.call(this, value)
+        } else {
+          if (typeof value === 'number'
+              && (key !== 'flex' && key !== 'opacity' && key !== 'zIndex')
+            ) {
+            value = value * this.data.scale + 'px'
+          }
+          this.node.style[key] = value
+        }
+      }
+    },
+  
+    bindEvents: function (evts) {
+      var componentManager = this.getComponentManager()
+      if (evts
+          && Object.prototype.toString.call(evts).slice(8, -1) === 'Array'
+        ) {
+        for (var i = 0, l = evts.length; i < l; i++) {
+          componentManager.addEvent(this, evts[i])
+        }
+      }
+    },
+  
+    // dispatch a specified event on this.node
+    //  - type: event type
+    //  - data: event data
+    //  - config: event config object
+    //     - bubbles
+    //     - cancelable
+    dispatchEvent: function (type, data, config) {
+      var event = document.createEvent('HTMLEvents')
+      config = config || {}
+      event.initEvent(type, config.bubbles || false, config.cancelable || false)
+      !data && (data = {})
+      event.data = utils.extend({}, data)
+      utils.extend(event, data)
+      if (type === 'appear') {
+        console.log('appear', data)
+      }
+      this.node.dispatchEvent(event)
+    },
+  
+    updateRecursiveAttr: function (data) {
+      this.updateAttrs(data.attr)
+      var componentManager = this.getComponentManager()
+      var children = this.data.children
+      if (children) {
+        for (var i = 0; i < children.length; i++) {
+          var child = componentManager.getElementByRef(children[i].ref)
+          if (child) {
+            child.updateRecursiveAttr(data.children[i])
+          }
+        }
+      }
+    },
+  
+    updateRecursiveStyle: function (data) {
+      this.updateStyle(data.style)
+      var componentManager = this.getComponentManager()
+      var children = this.data.children
+      if (children) {
+        for (var i = 0; i < children.length; i++) {
+          var child = componentManager.getElementByRef(children[i].ref)
+          if (child) {
+            child.updateRecursiveStyle(data.children[i])
+          }
+        }
+      }
+    },
+  
+    updateRecursiveAll: function (data) {
+      this.updateAttrs(data.attr)
+      this.updateStyle(data.style)
+      var componentManager = this.getComponentManager()
+  
+      // var oldRef = this.data.ref
+      // if (componentMap[oldRef]) {
+      //   delete componentMap[oldRef]
+      // }
+      // this.data.ref = data.ref
+      // componentMap[data.ref] = this
+  
+      var children = this.data.children
+      if (children) {
+        for (var i = 0; i < children.length; i++) {
+          var child = componentManager.getElementByRef(children[i].ref)
+          if (child) {
+            child.updateRecursiveAll(data.children[i])
+          }
+        }
+      }
+    },
+  
+    attr: {}, // attr setters
+  
+    style: Object.create(flexbox), // style setters
+  
+    clearAttr: function () {
+    },
+  
+    clearStyle: function () {
+      this.node.cssText = ''
+    }
+  }
+  
+  Component.prototype.style.position = function (value) {
+    // TODO: make it in a decent implementation
+    if (value === 'sticky') {
+      this.node.style.zIndex = 100
+      setTimeout(function () {
+        this.sticky = new lib.sticky(this.node, {
+          top: 0
+        })
+      }.bind(this), 0)
+    } else {
+      this.node.style.position = value
+    }
+  }
+  
+  module.exports = Component
+
+
+/***/ },
+/* 17 */
+/***/ function(module, exports) {
+
+  'use strict'
+  
+  // Flexbox polyfill
+  var flexboxSetters = (function () {
+    var BOX_ALIGN = {
+      stretch: 'stretch',
+      'flex-start': 'start',
+      'flex-end': 'end',
+      center: 'center'
+    }
+    var BOX_ORIENT = {
+      row: 'horizontal',
+      column: 'vertical'
+    }
+    var BOX_PACK = {
+      'flex-start': 'start',
+      'flex-end': 'end',
+      center: 'center',
+      'space-between': 'justify',
+      'space-around': 'justify' // Just same as `space-between`
+    }
+    return {
+      flex: function (value) {
+        this.node.style.webkitBoxFlex = value
+        this.node.style.webkitFlex = value
+        this.node.style.flex = value
+      },
+      alignItems: function (value) {
+        this.node.style.webkitBoxAlign = BOX_ALIGN[value]
+        this.node.style.webkitAlignItems = value
+        this.node.style.alignItems = value
+      },
+      alignSelf: function (value) {
+        this.node.style.webkitAlignSelf = value
+        this.node.style.alignSelf = value
+      },
+      flexDirection: function (value) {
+        this.node.style.webkitBoxOrient = BOX_ORIENT[value]
+        this.node.style.webkitFlexDirection = value
+        this.node.style.flexDirection = value
+      },
+      justifyContent: function (value) {
+        this.node.style.webkitBoxPack = BOX_PACK[value]
+        this.node.style.webkitJustifyContent = value
+        this.node.style.justifyContent = value
+      }
+    }
+  })()
+  
+  module.exports = flexboxSetters
+
+
+/***/ },
+/* 18 */
+/***/ function(module, exports) {
+
+  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b,c){function d(a){return null!=a&&"object"==typeof a&&Object.getPrototypeOf(a)==Object.prototype}function e(a,b){var c,d,e,f=null,g=0,h=function(){g=Date.now(),f=null,e=a.apply(c,d)};return function(){var i=Date.now(),j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(f),f=null,g=i,e=a.apply(c,d)):f||(f=setTimeout(h,j)),e}}function f(a){var b="";return Object.keys(a).forEach(function(c){b+=c+":"+a[c]+";"}),b}function g(a,c){!c&&d(a)&&(c=a,a=c.element),c=c||{},a.nodeType!=b.ELEMENT_NODE&&"string"==typeof a&&(a=b.querySelector(a));var e=this;e.element=a,e.top=c.top||0,e.withinParent=void 0==c.withinParent?!1:c.withinParent,e.init()}var h=a.parseInt,i=navigator.userAgent,j=!!i.match(/Firefox/i),k=!!i.match(/IEMobile/i),l=j?"-moz-":k?"-ms-":"-webkit-",m=j?"Moz":k?"ms":"webkit",n=function(){var a=b.createElement("div"),c=a.style;return c.cssText="position:"+l+"sticky;position:sticky;",-1!=c.position.indexOf("sticky")}();g.prototype={constructor:g,init:function(){var a=this,b=a.element,c=b.style;c[m+"Transform"]="translateZ(0)",c.transform="translateZ(0)",a._originCssText=c.cssText,n?(c.position=l+"sticky",c.position="sticky",c.top=a.top+"px"):(a._simulateSticky(),a._bindResize())},_bindResize:function(){var b=this,c=/android/gi.test(navigator.appVersion),d=b._resizeEvent="onorientationchange"in a?"orientationchange":"resize",e=b._resizeHandler=function(){setTimeout(function(){b.refresh()},c?200:0)};a.addEventListener(d,e,!1)},refresh:function(){var a=this;n||(a._detach(),a._simulateSticky())},_addPlaceholder:function(a){var c,d=this,e=d.element,g=a.position;if(-1!=["static","relative"].indexOf(g)){c=d._placeholderElement=b.createElement("div");var i=h(a.width)+h(a.marginLeft)+h(a.marginRight),j=h(a.height);"border-box"!=a.boxSizing&&(i+=h(a.borderLeftWidth)+h(a.borderRightWidth)+h(a.paddingLeft)+h(a.paddingRight),j+=h(a.borderTopWidth)+h(a.borderBottomWidth)+h(a.paddingTop)+h(a.paddingBottom)),c.style.cssText=f({display:"none",visibility:"hidden",width:i+"px",height:j+"px",margin:0,"margin-top":a.marginTop,"margin-bottom":a.marginBottom,border:0,padding:0,"float":a["float"]||a.cssFloat}),e.parentNode.insertBefore(c,e)}return c},_simulateSticky:function(){var c=this,d=c.element,g=c.top,i=d.style,j=d.getBoundingClientRect(),k=getComputedStyle(d,""),l=d.parentNode,m=getComputedStyle(l,""),n=c._addPlaceholder(k),o=c.withinParent,p=c._originCssText,q=j.top-g+a.pageYOffset,r=l.getBoundingClientRect().bottom-h(m.paddingBottom)-h(m.borderBottomWidth)-h(k.marginBottom)-j.height-g+a.pageYOffset,s=p+f({position:"fixed",top:g+"px",width:k.width,"margin-top":0}),t=p+f({position:"absolute",top:r+"px",width:k.width}),u=1,v=c._scrollHandler=e(function(){var b=a.pageYOffset;q>b?1!=u&&(i.cssText=p,n&&(n.style.display="none"),u=1):!o&&b>=q||o&&b>=q&&r>b?2!=u&&(i.cssText=s,n&&3!=u&&(n.style.display="block"),u=2):o&&3!=u&&(i.cssText=t,n&&2!=u&&(n.style.display="block"),u=3)},100);if(a.addEventListener("scroll",v,!1),a.pageYOffset>=q){var w=b.createEvent("HTMLEvents");w.initEvent("scroll",!0,!0),a.dispatchEvent(w)}},_detach:function(){var b=this,c=b.element;if(c.style.cssText=b._originCssText,!n){var d=b._placeholderElement;d&&c.parentNode.removeChild(d),a.removeEventListener("scroll",b._scrollHandler,!1)}},destroy:function(){var b=this;b._detach();var c=b.element.style;c.removeProperty(l+"transform"),c.removeProperty("transform"),n||a.removeEventListener(b._resizeEvent,b._resizeHandler,!1)}},c.sticky=g}(window,document,window.lib||(window.lib={}));;module.exports = window.lib['sticky'];
+
+/***/ },
+/* 19 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var utils = __webpack_require__(7)
+  
+  var _senderMap = {}
+  
+  function Sender(instance) {
+    if (!(this instanceof Sender)) {
+      return new Sender(instance)
+    }
+    this.instanceId = instance.instanceId
+    this.weexInstance = instance
+    _senderMap[this.instanceId] = this
+  }
+  
+  function _send(instanceId, msg) {
+    callJS(instanceId, [msg])
+  }
+  
+  Sender.getSender = function (instanceId) {
+    return _senderMap[instanceId]
+  }
+  
+  Sender.prototype = {
+  
+    // perform a callback to jsframework.
+    performCallback: function (callbackId, data) {
+      var args = [callbackId]
+      data && args.push(data)
+      _send(this.instanceId, {
+        method: 'callback',
+        args: args
+      })
+    },
+  
+    fireEvent: function (ref, type, event) {
+      // Note that the event.target must be the standard event's
+      // currentTarget. Therefor a process for replacing target must
+      // be done when a event is fired.
+      var evt = utils.extend({}, event)
+      evt.target = evt.currentTarget
+      evt.value = event.target.value
+      evt.timestamp = Date.now()
+      _send(this.instanceId, {
+        method: 'fireEvent',
+        args: [ref, type, evt]
+      })
+    }
+  
+  }
+  
+  module.exports = Sender
+
+/***/ },
+/* 20 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict'
+  
+  var config = __webpack_require__(5)
+  var protocol = __webpack_require__(8)
+  var utils = __webpack_require__(7)
+  var FrameUpdater = __webpack_require__(10)
+  var Sender = __webpack_require__(19)
+  
+  var callQueue = []
+  // Need a task counter?
+  // When FrameUpdater is not activated, tasks will not be push
+  // into callQueue and there will be no trace for situation of
+  // execution of tasks.
+  
+  // give 10ms for call handling, and rest 6ms for others
+  var MAX_TIME_FOR_EACH_FRAME = 10
+  
+  // callNative: jsFramework will call this method to talk to
+  // this renderer.
+  // params:
+  //  - instanceId: string.
+  //  - tasks: array of object.
+  //  - callbackId: number.
+  function callNative(instanceId, tasks, callbackId) {
+    var calls = []
+    if (typeof tasks === 'string') {
+      try {
+        calls = JSON.parse(tasks)
+      } catch (e) {
+        console.error('invalid tasks:', tasks)
+      }
+    } else if (Object.prototype.toString.call(tasks).slice(8, -1) === 'Array') {
+      calls = tasks
+    }
+    var len = calls.length
+    calls[len - 1].callbackId = (!callbackId && callbackId !== 0)
+                                ? -1
+                                : callbackId
+    // To solve the problem of callapp, the two-way time loop rule must
+    // be replaced by calling directly except the situation of page loading.
+    // 2015-11-03
+    for (var i = 0; i < len; i++) {
+      if (FrameUpdater.isActive()) {
+        callQueue.push({
+          instanceId: instanceId,
+          call: calls[i]
+        })
+      }
+      else {
+        processCall(instanceId, calls[i])
+      }
+    }
+  
+  }
+  
+  function processCallQueue() {
+    var len = callQueue.length
+    if (len === 0) {
+      return
+    }
+    var start = Date.now()
+    var elapsed = 0
+  
+    while (--len >= 0 && elapsed < MAX_TIME_FOR_EACH_FRAME) {
+      var callObj = callQueue.shift()
+      processCall(callObj.instanceId, callObj.call)
+      elapsed = Date.now() - start
+    }
+  }
+  
+  function processCall(instanceId, call) {
+    var moduleName = call.module
+    var methodName = call.method
+    var module, method
+    var args = call.args || call.arguments || []
+  
+    if (!(module = protocol.apiModule[moduleName])) {
+      return
+    }
+    if (!(method = module[methodName])) {
+      return
+    }
+  
+    method.apply(protocol.getWeexInstance(instanceId), args)
+  
+    var callbackId = call.callbackId
+    if ((callbackId
+      || callbackId === 0
+      || callbackId === '0')
+      && callbackId !== '-1'
+      && callbackId !== -1) {
+      performNextTick(instanceId, callbackId)
+    }
+  }
+  
+  function performNextTick(instanceId, callbackId) {
+    Sender.getSender(instanceId).performCallback(callbackId)
+  }
+  
+  function nativeLog() {
+    if (config.debug) {
+      if (arguments[0].match(/^perf/)) {
+        console.info.apply(console, arguments)
+        return
+      }
+      console.debug.apply(console, arguments)
+    }
+  }
+  
+  function exportsBridgeMethodsToGlobal() {
+    global.callNative = callNative
+    global.nativeLog = nativeLog
+  }
+  
+  module.exports = {
+  
+    init: function () {
+  
+      // process callQueue every 16 milliseconds.
+      FrameUpdater.addUpdateObserver(processCallQueue)
+      FrameUpdater.start()
+  
+      // exports methods to global(window).
+      exportsBridgeMethodsToGlobal()
+    }
+  
+  }
+  
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 21 */
+/***/ function(module, exports, __webpack_require__) {
+
+  var RootComponent = __webpack_require__(22)
+  var Container = __webpack_require__(23)
+  var Image = __webpack_require__(26)
+  var Text = __webpack_require__(28)
+  var List = __webpack_require__(29)
+  var Countdown = __webpack_require__(37)
+  var Marquee = __webpack_require__(39)
+  var Slider = __webpack_require__(40)
+  var Indicator = __webpack_require__(44)
+  var Tabheader = __webpack_require__(47)
+  var Scroller = __webpack_require__(51)
+  var Input = __webpack_require__(54)
+  var Select = __webpack_require__(55)
+  var Datepicker = __webpack_require__(56)
+  var Timepicker = __webpack_require__(57)
+  var Video = __webpack_require__(58)
+  var Switch = __webpack_require__(61)
+  var A = __webpack_require__(64)
+  var Embed = __webpack_require__(65)
+  
+  var components = {
+    init: function (Weex) {
+      Weex.registerComponent('root', RootComponent)
+      Weex.registerComponent('root', RootComponent)
+      Weex.registerComponent('container', Container)
+      Weex.registerComponent('image', Image)
+      Weex.registerComponent('text', Text)
+      Weex.registerComponent('list', List)
+      Weex.registerComponent('countdown', Countdown)
+      Weex.registerComponent('marquee', Marquee)
+      Weex.registerComponent('slider', Slider)
+      Weex.registerComponent('indicator', Indicator)
+      Weex.registerComponent('tabheader', Tabheader)
+      Weex.registerComponent('scroller', Scroller)
+      Weex.registerComponent('input', Input)
+      Weex.registerComponent('select', Select)
+      Weex.registerComponent('datepicker', Datepicker)
+      Weex.registerComponent('timepicker', Timepicker)
+      Weex.registerComponent('video', Video)
+      Weex.registerComponent('switch', Switch)
+      Weex.registerComponent('a', A)
+      Weex.registerComponent('embed', Embed)
+    }
+  }
+  
+  module.exports = components
+
+/***/ },
+/* 22 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var ComponentManager = __webpack_require__(9)
+  var Component = __webpack_require__(16)
+  
+  // If nodeType is in this WHITE_LIST, just ignore it and
+  // replace it with a div element.
+  var WHITE_LIST = []
+  
+  function RootComponent(data, nodeType) {
+    var id = data.rootId + '-root'
+    var componentManager = ComponentManager.getInstance(data.instanceId)
+  
+    // Return a NodeType instance.
+    if (nodeType && nodeType !== 'div' && WHITE_LIST.indexOf(nodeType) === -1) {
+      data.type = nodeType
+      var cmp = componentManager.createElement(data)
+      cmp.node.id = id
+      return cmp
+    }
+  
+    // Otherwise return a common weex-container component,
+    // whose node is a div element.
+    var node = document.createElement('div')
+    this.data = data
+    this.node = node
+  
+    this.createChildren()
+    this.updateAttrs(this.data.attr)
+    // issue: when add element to a list in lifetime hook 'ready', the
+    // styles is set to the classStyle, not style. This is a issue
+    // that jsframework should do something about.
+    var classStyle = this.data.classStyle
+    classStyle && this.updateStyle(this.data.classStyle)
+    this.updateStyle(this.data.style)
+    this.bindEvents(this.data.event)
+  }
+  
+  RootComponent.prototype = Object.create(Component.prototype)
+  
+  module.exports = RootComponent
+
+
+/***/ },
+/* 23 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  __webpack_require__(24)
+  
+  var Component = __webpack_require__(16)
+  
+  function Container (data, nodeType) {
+    Component.call(this, data, nodeType)
+    this.node.classList.add('weex-container')
+  }
+  
+  Container.prototype = Object.create(Component.prototype)
+  
+  module.exports = Container
+
+
+/***/ },
+/* 24 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(25);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./container.scss", function() {
+        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./container.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 25 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".weex-container {\n  box-sizing: border-box;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-box-orient: vertical;\n  -webkit-flex-direction: column;\n  flex-direction: column;\n  position: relative;\n  border: 0 solid black;\n  margin: 0;\n  padding: 0; }\n\n.weex-element {\n  box-sizing: border-box;\n  position: relative; }\n", "", {"version":3,"sources":["/./src/src/styles/container.scss"],"names":[],"mappings":"AAAA;EACE,uBAAsB;EACtB,qBAAoB;EACpB,sBAAqB;EACrB,cAAa;EACb,6BAA4B;EAC5B,+BAA8B;EAC9B,uBAAsB;EACtB,mBAAkB;EAClB,sBAAqB;EACrB,UAAS;EACT,WACD,EAAC;;AAEF;EACE,uBAAuB;EACvB,mBAAmB,EACpB","file":"container.scss","sourcesContent":[".weex-container {\n  box-sizing:border-box;\n  display:-webkit-box;\n  display:-webkit-flex;\n  display:flex;\n  -webkit-box-orient:vertical;\n  -webkit-flex-direction:column;\n  flex-direction:column;\n  position:relative;\n  border:0 solid black;\n  margin:0;\n  padding:0\n}\n\n.weex-element {\n  box-sizing: border-box;\n  position: relative;\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 26 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(27)
+  var LazyLoad = __webpack_require__(12)
+  var config = __webpack_require__(5)
+  
+  var DEFAULT_SIZE = 200
+  var RESIZE_MODES = ['cover', 'contain'] // not temporarily supported
+  
+  /**
+   * resize=cover|contain|stretch v1.4 temporarily not supported
+   * src=url
+   */
+  
+  function Image (data) {
+    this.width = data.style && data.style.width
+                 ? (data.style.width + '').replace(/[^\d]/g, '')
+                 : DEFAULT_SIZE
+    this.height = data.style && data.style.height
+                 ? (data.style.height + '').replace(/[^\d]/g, '')
+                 : DEFAULT_SIZE
+    this.width *= data.scale
+    this.height *= data.scale
+    var mode
+    var attr = data.attr
+    attr && (mode = attr.resize || attr.resizeMode)
+    if (RESIZE_MODES.indexOf(mode) !== -1) {
+      this.mode = mode
+      // TODO: resize-mode is not temporarily supported.
+    }
+    Atomic.call(this, data)
+  }
+  
+  Image.prototype = Object.create(Atomic.prototype)
+  
+  Image.prototype.create = function () {
+    var node = document.createElement('img')
+    node.classList.add('weex-element')
+    node.style.display = 'block'
+    node.style.outline = 'none'
+    return node
+  }
+  
+  Image.prototype.attr = {
+    src: function (value) {
+      if (!this.node.src) {
+        this.node.src = lib.img.defaultSrc
+      }
+      LazyLoad.makeImageLazy(this.node, value)
+    }
+  }
+  
+  Image.prototype.clearAttr = function () {
+    this.node.src = ''
+  }
+  
+  module.exports = Image
+
+
+/***/ },
+/* 27 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Component = __webpack_require__(16)
+  
+  // Component which can have no subcomponents.
+  // This component should not be instantiated directly, since
+  // it is designed to be used as a base class to extend from.
+  function Atomic (data) {
+    Component.call(this, data)
+  }
+  
+  Atomic.prototype = Object.create(Component.prototype)
+  
+  Atomic.prototype.appendChild = function (data) {
+    // do nothing
+    return
+  }
+  
+  Atomic.prototype.insertBefore = function (child, before) {
+    // do nothing
+    return
+  }
+  
+  Atomic.prototype.removeChild = function (child) {
+    // do nothing
+    return
+  }
+  
+  module.exports = Atomic
+
+
+/***/ },
+/* 28 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(16)
+  var utils = __webpack_require__(7)
+  
+  var DEFAULT_FONT_SIZE = 32
+  
+  // attr
+  //  - value: text content.
+  //  - lines: maximum lines of the text.
+  function Text (data) {
+    Atomic.call(this, data)
+  }
+  
+  Text.prototype = Object.create(Atomic.prototype)
+  
+  Text.prototype.create = function () {
+    var node = document.createElement('div')
+    node.classList.add('weex-container')
+    node.style.fontSize = DEFAULT_FONT_SIZE * this.data.scale + 'px'
+    this.textNode = document.createElement('span')
+    // Give the developers the ability to control space
+    // and line-breakers.
+    this.textNode.style.whiteSpace = 'pre-wrap'
+    this.textNode.style.display = '-webkit-box'
+    this.textNode.style.webkitBoxOrient = 'vertical'
+    this.style.lines.call(this, this.data.style.lines)
+    node.appendChild(this.textNode)
+    return node
+  }
+  
+  Text.prototype.attr = {
+    value: function (value) {
+      var span = this.node.firstChild
+      span.innerHTML = ''
+      if (!value) {
+        return
+      }
+      span.textContent = value
+      /**
+       * Developers are supposed to have the ability to break text
+       * lines manually. Using ``&nbsp;`` to replace text space is
+       * not compatible with the ``-webkit-line-clamp``. Therefor
+       * we use ``white-space: no-wrap`` instead (instead of the
+       * code bellow).
+  
+        var frag = document.createDocumentFragment()
+          text.split(' ').forEach(function(str) {
+            var textNode = document.createTextNode(str)
+            var space = document.createElement('i')
+            space.innerHTML = '&nbsp;'
+            frag.appendChild(space)
+            frag.appendChild(textNode)
+          })
+          frag.removeChild(frag.firstChild)
+          span.appendChild(document.createElement('br'))
+          span.appendChild(frag)
+        })
+        span.removeChild(span.firstChild)
+       */
+    }
+  }
+  
+  Text.prototype.clearAttr = function () {
+    this.node.firstChild.textContent = ''
+  }
+  
+  Text.prototype.style = utils.extend(Object.create(Atomic.prototype.style), {
+  
+    lines: function (val) {
+      val = parseInt(val)
+      if (val !== val) { // NaN
+        return
+      }
+      if (val <= 0) {
+        this.textNode.style.textOverflow = ''
+        this.textNode.style.overflow = 'visible'
+        this.textNode.style.webkitLineClamp = ''
+      } else {
+        this.textNode.style.overflow = 'hidden'
+        this.textNode.style.textOverflow = 'ellipsis'
+        this.textNode.style.webkitLineClamp = lines
+      }
+    }
+  
+  })
+  
+  module.exports = Text
+
+
+/***/ },
+/* 29 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  __webpack_require__(30)
+  __webpack_require__(32)
+  
+  var Component = __webpack_require__(16)
+  var LazyLoad = __webpack_require__(12)
+  
+  var DEFAULT_LOAD_MORE_OFFSET = 500
+  
+  function List(data, nodeType) {
+    // this.loadmoreOffset = Number(data.attr.loadmoreoffset)
+    // this.isAvailableToFireloadmore = true
+    Component.call(this, data, nodeType)
+  }
+  
+  List.prototype = Object.create(Component.prototype)
+  
+  List.prototype.create = function (nodeType) {
+    var Scroll = lib.scroll
+    var node = Component.prototype.create.call(this, nodeType)
+    node.classList.add('weex-container', 'list-wrap')
+    this.listElement = document.createElement('div')
+    this.listElement.classList.add(
+      'weex-container'
+      , 'list-element'
+    )
+    node.appendChild(this.listElement)
+    this.scroller = new Scroll({
+      scrollElement: this.listElement
+      , direction: 'y'
+    })
+    this.scroller.init()
+    return node
+  }
+  
+  List.prototype.bindEvents = function (evts) {
+    Component.prototype.bindEvents.call(this, evts)
+    // to enable lazyload for Images.
+    this.scroller.addEventListener('scrolling', function (e) {
+      var so = e.scrollObj
+      this.dispatchEvent('scroll', {
+        originalType: 'scrolling',
+        scrollTop: so.getScrollTop(),
+        scrollLeft: so.getScrollLeft()
+      }, {
+        bubbles: true
+      })
+    }.bind(this))
+  
+    this.scroller.addEventListener('pullupend', function (e) {
+      this.dispatchEvent('loadmore')
+    }.bind(this))
+  }
+  
+  List.prototype.appendChild = function (data) {
+    var children = this.data.children
+    var componentManager = this.getComponentManager()
+    var child = componentManager.createElement(data)
+    this.listElement.appendChild(child.node)
+  
+    // update this.data.children
+    if (!children || !children.length) {
+      this.data.children = [data]
+    } else {
+      children.push(data)
+    }
+  
+    return child
+  }
+  
+  List.prototype.insertBefore = function (child, before) {
+    var children = this.data.children
+    var i = 0
+    var isAppend = false
+  
+    // update this.data.children
+    if (!children || !children.length || !before) {
+      isAppend = true
+    } else {
+      for (var l = children.length; i < l; i++) {
+        if (children[i].ref === child.data.ref) {
+          break
+        }
+      }
+      if (i === l) {
+        isAppend = true
+      }
+    }
+  
+    if (isAppend) {
+      this.listElement.appendChild(child.node)
+      children.push(child.data)
+    } else {
+      this.listElement.insertBefore(child.node, before.node)
+      children.splice(i, 0, child.data)
+    }
+  }
+  
+  List.prototype.removeChild = function (child) {
+    var children = this.data.children
+    // remove from this.data.children
+    var i = 0
+    var componentManager = this.getComponentManager()
+    if (children && children.length) {
+      for (var l = children.length; i < l; i++) {
+        if (children[i].ref === child.data.ref) {
+          break
+        }
+      }
+      if (i < l) {
+        children.splice(i, 1)
+      }
+    }
+    // remove from componentMap recursively
+    componentManager.removeElementByRef(child.data.ref)
+    this.listElement.removeChild(child.node)
+  }
+  
+  module.exports = List
+
+
+/***/ },
+/* 30 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(31);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./list.scss", function() {
+        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./list.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 31 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".list-wrap {\n  display: block;\n  overflow: hidden; }\n\n.list-element {\n  -webkit-box-orient: vertical;\n  -webkit-flex-direction: column;\n  flex-direction: column; }\n", "", {"version":3,"sources":["/./src/src/styles/list.scss"],"names":[],"mappings":"AAAA;EACC,eAAe;EACf,iBAAiB,EACjB;;AAED;EACE,6BAA6B;EAC7B,+BAA+B;EAC/B,uBAAuB,EACxB","file":"list.scss","sourcesContent":[".list-wrap {\n\tdisplay: block;\n\toverflow: hidden;\n}\n\n.list-element {\n  -webkit-box-orient: vertical;\n  -webkit-flex-direction: column;\n  flex-direction: column;\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 32 */
+/***/ function(module, exports, __webpack_require__) {
+
+  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});__webpack_require__(33);__webpack_require__(34);__webpack_require__(35);__webpack_require__(36);!function(a,b,c){function d(){b.scroll.outputDebugLog&&console.debug.apply(console,arguments)}function e(a){var b=a.getBoundingClientRect();if(!b){b={},b.width=a.offsetWidth,b.height=a.offsetHeight,b.left=a.offsetLeft,b.top=a.offsetTop;for(var c=a.offsetParent;c;)b.left+=c.offsetLeft,b.top+=c.offsetTop,c=c.offsetParent;b.right=b.left+b.width,b.bottom=b.top+b.height}return b}function f(a){return 0-a.options[a.axis+"PaddingTop"]}function g(a){var b=e(a.element),c=e(a.viewport),d=f(a);if("y"===a.axis)var g=0-b.height+c.height;else var g=0-b.width+c.width;return Math.min(g+a.options[a.axis+"PaddingBottom"],d)}function h(a,b){return b>a.minScrollOffset?b-a.minScrollOffset:b<a.maxScrollOffset?b-a.maxScrollOffset:void 0}function i(a,b){return b>a.minScrollOffset?b=a.minScrollOffset:b<a.maxScrollOffset&&(b=a.maxScrollOffset),b}function j(a,b,c){d(a.element.scrollId,b,c);var e=p.createEvent("HTMLEvents");if(e.initEvent(b,!1,!0),e.scrollObj=a,c)for(var f in c)e[f]=c[f];a.element.dispatchEvent(e),a.viewport.dispatchEvent(e)}function k(a){var b,c={x:0,y:0},d=getComputedStyle(a.element)[y+"Transform"];return"none"!==d&&(b=d.match(/^matrix3d\((?:[-\d.]+,\s*){12}([-\d.]+),\s*([-\d.]+)(?:,\s*[-\d.]+){2}\)/)||d.match(/^matrix\((?:[-\d.]+,\s*){4}([-\d.]+),\s*([-\d.]+)\)$/))&&(c.x=parseFloat(b[1])||0,c.y=parseFloat(b[2])||0),c}function l(a,b){return a=parseFloat(a),b=parseFloat(b),0!=a&&(a+="px"),0!=b&&(b+="px"),A?"translate3d("+a+", "+b+", 0)":"translate("+a+", "+b+")"}function m(a,b,c){""===b&&""===c?a.element.style[y+"Transition"]="":a.element.style[y+"Transition"]=x+"transform "+b+" "+c+" 0s"}function n(a,b){var c=0,d=0;"object"==typeof b?(c=b.x,d=b.y):"y"===a.axis?d=b:c=b,a.element.style[y+"Transform"]=l(c,d)}function o(a,c){function l(a){return F||L?(a.preventDefault(),a.stopPropagation(),!1):!0}function o(a){F||L||setTimeout(function(){var b=document.createEvent("HTMLEvents");b.initEvent("niceclick",!0,!0),a.target.dispatchEvent(b)},300)}function p(a,c){I=null,clearTimeout(J),J=setTimeout(function(){I&&(I=null,b.animation.requestFrame(a))},c||400),I=a}function q(a){if(!E.enabled)return!1;if("undefined"!=typeof a.isVertical){if(!("y"===E.axis&&a.isVertical||"x"===E.axis&&!a.isVertical))return!1;a.stopPropagation()}return!0}function t(a){if(q(a))if(L&&D(),c.useFrameAnimation)H&&H.stop(),H=null;else{var b=k(E);n(E,b),m(E,"",""),I=null,clearTimeout(J)}}function w(a){if(q(a)){var d=k(E)[E.axis],e=h(E,d);if(e){var f=i(E,d);if(c.useFrameAnimation){var g=f-d;H=new b.animation(400,b.cubicbezier.ease,0,function(a,b){var c=(d+g*b).toFixed(2);n(E,c),j(E,"scrolling")}),H.onend(D),H.play()}else{var l=f.toFixed(0);m(E,"0.4s","ease"),n(E,l),p(D,400),b.animation.requestFrame(function(){L&&E.enabled&&(j(E,"scrolling"),b.animation.requestFrame(arguments.callee))})}e>0?j(E,"y"===E.axis?"pulldownend":"pullrightend"):0>e&&j(E,"y"===E.axis?"pullupend":"pullleftend")}else L&&D()}}function x(a){q(a)&&(E.transformOffset=k(E),E.minScrollOffset=f(E),E.maxScrollOffset=g(E),K=2.5,N=!0,L=!0,M=!1,j(E,"scrollstart"),O=a["displacement"+E.axis.toUpperCase()])}function z(a){if(q(a)){var b=a["displacement"+E.axis.toUpperCase()];if(Math.abs(b-O)<5)return void a.stopPropagation();O=b;var c=E.transformOffset[E.axis]+b;c>E.minScrollOffset?(c=E.minScrollOffset+(c-E.minScrollOffset)/K,K*=1.003):c<E.maxScrollOffset&&(c=E.maxScrollOffset-(E.maxScrollOffset-c)/K,K*=1.003),K>4&&(K=4);var d=h(E,c);d&&(j(E,d>0?"y"===E.axis?"pulldown":"pullright":"y"===E.axis?"pullup":"pullleft",{boundaryOffset:Math.abs(d)}),E.options.noBounce&&(c=i(E,c))),n(E,c.toFixed(2)),j(E,"scrolling")}}function A(a){q(a)&&a.isflick&&C(a)}function C(a){N=!0;var e,f,g,i,l,o,q,r,s,t,v,w,x,y,z,A,B;i=k(E)[E.axis];var C=h(E,i);if(!C){e=a["velocity"+E.axis.toUpperCase()];var F=2,G=.0015;c.inertia&&u[c.inertia]&&(F=u[c.inertia][0],G=u[c.inertia][1]),e>F&&(e=F),-F>e&&(e=-F),f=G*(e/Math.abs(e)),o=new b.motion({v:e,a:-f}),g=o.t,l=i+o.s;var I=h(E,l);if(I){d("惯性计算超出了边缘",I),q=e,r=f,I>0?(t=E.minScrollOffset,w=1):(t=E.maxScrollOffset,w=-1),v=new b.motion({v:w*q,a:-w*r,s:Math.abs(t-i)}),s=v.t;var J=v.generateCubicBezier();x=q-r*s,y=.03*(x/Math.abs(x)),B=new b.motion({v:x,a:-y}),z=B.t,A=t+B.s;B.generateCubicBezier();if(c.noBounce)if(d("没有回弹效果"),i!==t)if(c.useFrameAnimation){var K=t-i,O=b.cubicbezier(J[0][0],J[0][1],J[1][0],J[1][1]);H=new b.animation(s.toFixed(0),O,0,function(a,b){var c=i+K*b;k(E,c.toFixed(2)),j(E,"scrolling",{afterFlick:!0})}),H.onend(D),H.play()}else{var P=t.toFixed(0);m(E,(s/1e3).toFixed(2)+"s","cubic-bezier("+J+")"),n(E,P),p(D,1e3*(s/1e3).toFixed(2))}else D();else if(i!==A)if(d("惯性滚动","s="+A.toFixed(0),"t="+((s+z)/1e3).toFixed(2)),c.useFrameAnimation){var K=A-i,O=b.cubicbezier.easeOut;H=new b.animation((s+z).toFixed(0),O,0,function(a,b){var c=i+K*b;n(E,c.toFixed(2)),j(E,"scrolling",{afterFlick:!0})}),H.onend(function(){if(E.enabled){var a=t-A,c=b.cubicbezier.ease;H=new b.animation(400,c,0,function(b,c){var d=A+a*c;n(E,d.toFixed(2)),j(E,"scrolling",{afterFlick:!0})}),H.onend(D),H.play()}}),H.play()}else{var P=A.toFixed(0);m(E,((s+z)/1e3).toFixed(2)+"s","ease-out"),n(E,P),p(function(a){if(E.enabled)if(d("惯性回弹","s="+t.toFixed(0),"t=400"),A!==t){var b=t.toFixed(0);m(E,"0.4s","ease"),n(E,b),p(D,400)}else D()},1e3*((s+z)/1e3).toFixed(2))}else D()}else{d("惯性计算没有超出边缘");var Q=o.generateCubicBezier();if(c.useFrameAnimation){var K=l-i,O=b.cubicbezier(Q[0][0],Q[0][1],Q[1][0],Q[1][1]);H=new b.animation(g.toFixed(0),O,0,function(a,b){var c=(i+K*b).toFixed(2);n(E,c),j(E,"scrolling",{afterFlick:!0})}),H.onend(D),H.play()}else{var P=l.toFixed(0);m(E,(g/1e3).toFixed(2)+"s","cubic-bezier("+Q+")"),n(E,P),p(D,1e3*(g/1e3).toFixed(2))}}M=!0,c.useFrameAnimation||b.animation.requestFrame(function(){L&&M&&E.enabled&&(j(E,"scrolling",{afterFlick:!0}),b.animation.requestFrame(arguments.callee))})}}function D(){E.enabled&&(N=!1,setTimeout(function(){!N&&L&&(L=!1,M=!1,c.useFrameAnimation?(H&&H.stop(),H=null):m(E,"",""),j(E,"scrollend"))},50))}var E=this;if(c=c||{},c.noBounce=!!c.noBounce,c.padding=c.padding||{},null==c.isPrevent?c.isPrevent=!0:c.isPrevent=!!c.isPrevent,null==c.isFixScrollendClick?c.isFixScrollendClick=!0:c.isFixScrollendClick=!!c.isFixScrollendClick,c.padding?(c.yPaddingTop=-c.padding.top||0,c.yPaddingBottom=-c.padding.bottom||0,c.xPaddingTop=-c.padding.left||0,c.xPaddingBottom=-c.padding.right||0):(c.yPaddingTop=0,c.yPaddingBottom=0,c.xPaddingTop=0,c.xPaddingBottom=0),c.direction=c.direction||"y",c.inertia=c.inertia||"normal",this.options=c,E.axis=c.direction,this.element=a,this.viewport=a.parentNode,this.plugins={},this.element.scrollId=setTimeout(function(){r[E.element.scrollId+""]=E},1),this.viewport.addEventListener("touchstart",t,!1),this.viewport.addEventListener("touchend",w,!1),this.viewport.addEventListener("touchcancel",w,!1),this.viewport.addEventListener("panstart",x,!1),this.viewport.addEventListener("panmove",z,!1),this.viewport.addEventListener("panend",A,!1),c.isPrevent&&(this.viewport.addEventListener("touchstart",function(a){B=!0},!1),E.viewport.addEventListener("touchend",function(a){B=!1},!1)),c.isFixScrollendClick){var F,G;this.viewport.addEventListener("scrolling",function(){F=!0,G&&clearTimeout(G),G=setTimeout(function(a){F=!1},400)},!1),this.viewport.addEventListener("click",l,!1),this.viewport.addEventListener("tap",o,!1)}if(c.useFrameAnimation){var H;Object.defineProperty(this,"animation",{get:function(){return H}})}else{var I,J=0;a.addEventListener(v?"transitionend":y+"TransitionEnd",function(a){if(I){var c=I;I=null,clearTimeout(J),b.animation.requestFrame(function(){c(a)})}},!1)}var K,L,M,N;Object.defineProperty(this,"isScrolling",{get:function(){return!!L}});var O,P={init:function(){return this.enable(),this.refresh(),this.scrollTo(0),this},enable:function(){return this.enabled=!0,this},disable:function(){var a=this.element;return this.enabled=!1,this.options.useFrameAnimation?H&&H.stop():b.animation.requestFrame(function(){a.style[y+"Transform"]=getComputedStyle(a)[y+"Transform"]}),this},getScrollWidth:function(){return e(this.element).width},getScrollHeight:function(){return e(this.element).height},getScrollLeft:function(){return-k(this).x-this.options.xPaddingTop},getScrollTop:function(){return-k(this).y-this.options.yPaddingTop},getMaxScrollLeft:function(){return-E.maxScrollOffset-this.options.xPaddingTop},getMaxScrollTop:function(){return-E.maxScrollOffset-this.options.yPaddingTop},getBoundaryOffset:function(){return Math.abs(h(this,k(this)[this.axis])||0)},refresh:function(){var a=this.element,b="y"===this.axis,c=b?"height":"width";if(null!=this.options[c])a.style[c]=this.options[c]+"px";else if(this.options.useElementRect)a.style[c]="auto",a.style[c]=e(a)[c]+"px";else if(a.childElementCount>0){var d,h,i=a.firstElementChild,l=a.lastElementChild;if(document.createRange&&!this.options.ignoreOverflow&&(d=document.createRange(),d.selectNodeContents(a),h=e(d)),h)a.style[c]=h[c]+"px";else{for(;i&&0===e(i)[c]&&i.nextElementSibling;)i=i.nextElementSibling;for(;l&&l!==i&&0===e(l)[c]&&l.previousElementSibling;)l=l.previousElementSibling;a.style[c]=e(l)[b?"bottom":"right"]-e(i)[b?"top":"left"]+"px"}}return this.transformOffset=k(this),this.minScrollOffset=f(this),this.maxScrollOffset=g(this),this.scrollTo(-this.transformOffset[this.axis]-this.options[this.axis+"PaddingTop"]),j(this,"contentrefresh"),this},offset:function(a){var b=e(this.element),c=e(a);if("y"===this.axis){var d={top:c.top-b.top-this.options.yPaddingTop,left:c.left-b.left,right:b.right-c.right,width:c.width,height:c.height};d.bottom=d.top+d.height}else{var d={top:c.top-b.top,bottom:b.bottom-c.bottom,left:c.left-b.left-this.options.xPaddingTop,width:c.width,height:c.height};d.right=d.left+d.width}return d},getRect:function(a){var b=e(this.viewport),c=e(a);if("y"===this.axis){var d={top:c.top-b.top,left:c.left-b.left,right:b.right-c.right,width:c.width,height:c.height};d.bottom=d.top+d.height}else{var d={top:c.top-b.top,bottom:b.bottom-c.bottom,left:c.left-b.left,width:c.width,height:c.height};d.right=d.left+d.width}return d},isInView:function(a){var b=this.getRect(this.viewport),c=this.getRect(a);return"y"===this.axis?b.top<c.bottom&&b.bottom>c.top:b.left<c.right&&b.right>c.left},scrollTo:function(a,c){var d=this;this.element;if(a=-a-this.options[this.axis+"PaddingTop"],a=i(this,a),L=!0,c===!0)if(this.options.useFrameAnimation){var e=k(d)[this.axis],f=a-e;H=new b.animation(400,b.cubicbezier.ease,0,function(a,b){var c=(e+f*b).toFixed(2);n(d,c),j(d,"scrolling")}),H.onend(D),H.play()}else m(d,"0.4s","ease"),n(d,a),p(D,400),b.animation.requestFrame(function(){L&&d.enabled&&(j(d,"scrolling"),b.animation.requestFrame(arguments.callee))});else this.options.useFrameAnimation||m(d,"",""),n(d,a),D();return this},scrollToElement:function(a,b){var c=this.offset(a);return c=c["y"===this.axis?"top":"left"],this.scrollTo(c,b)},getViewWidth:function(){return e(this.viewport).width},getViewHeight:function(){return e(this.viewport).height},addPulldownHandler:function(a){var b=this;return this.element.addEventListener("pulldownend",function(c){b.disable(),a.call(b,c,function(){b.scrollTo(0,!0),b.refresh(),b.enable()})},!1),this},addPullupHandler:function(a){var b=this;return this.element.addEventListener("pullupend",function(c){b.disable(),a.call(b,c,function(){b.scrollTo(b.getScrollHeight(),!0),b.refresh(),b.enable()})},!1),this},addScrollstartHandler:function(a){var b=this;return this.element.addEventListener("scrollstart",function(c){a.call(b,c)},!1),this},addScrollingHandler:function(a){var b=this;return this.element.addEventListener("scrolling",function(c){a.call(b,c)},!1),this},addScrollendHandler:function(a){var b=this;return this.element.addEventListener("scrollend",function(c){a.call(b,c)},!1),this},addContentrenfreshHandler:function(a){var b=this;this.element.addEventListener("contentrefresh",function(c){a.call(b,c)},!1)},addEventListener:function(a,b,c){var d=this;this.element.addEventListener(a,function(a){b.call(d,a)},!!c)},removeEventListener:function(a,b){var c=this;this.element.removeEventListener(a,function(a){b.call(c,a)})},enablePlugin:function(a,b){var c=s[a];return c&&!this.plugins[a]&&(this.plugins[a]=!0,b=b||{},c.call(this,a,b)),this}};for(var Q in P)this[Q]=P[Q];delete P}var p=a.document,q=a.navigator.userAgent,r={},s={},t=a.dpr||(a.navigator.userAgent.match(/iPhone|iPad|iPod/)?document.documentElement.clientWidth/a.screen.availWidth:1),u={normal:[2*t,.0015*t],slow:[1.5*t,.003*t],veryslow:[1.5*t,.005*t]},v=!!q.match(/Firefox/i),w=!!q.match(/IEMobile/i),x=v?"-moz-":w?"-ms-":"-webkit-",y=v?"Moz":w?"ms":"webkit",z=w?"MSCSSMatrix":"WebKitCSSMatrix",A=!!v||z in a&&"m11"in new a[z],B=!1;p.addEventListener("touchmove",function(a){return B?(a.preventDefault(),!1):!0},!1),b.scroll=function(a,c){if(1===arguments.length&&!(arguments[0]instanceof HTMLElement))if(c=arguments[0],c.scrollElement)a=c.scrollElement;else{if(!c.scrollWrap)throw new Error("no scroll element");a=c.scrollWrap.firstElementChild}if(!a.parentNode)throw new Error("wrong dom tree");if(c&&c.direction&&["x","y"].indexOf(c.direction)<0)throw new Error("wrong direction");var d;return d=c.downgrade===!0&&b.scroll.downgrade?b.scroll.downgrade(a,c):a.scrollId?r[a.scrollId]:new o(a,c)},b.scroll.plugin=function(a,b){return b?(a=a.split(","),void a.forEach(function(a){s[a]=b})):s[a]}}(window,window.lib||(window.lib={}));;module.exports = window.lib['scroll'];
+
+/***/ },
+/* 33 */
+/***/ function(module, exports) {
+
+  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b){function c(a){return setTimeout(a,l)}function d(a){clearTimeout(a)}function e(){var a={},b=new m(function(b,c){a.resolve=b,a.reject=c});return a.promise=b,a}function f(a,b){return["then","catch"].forEach(function(c){b[c]=function(){return a[c].apply(a,arguments)}}),b}function g(b){var c,d,h=!1;this.request=function(){h=!1;var g=arguments;return c=e(),f(c.promise,this),d=n(function(){h||c&&c.resolve(b.apply(a,g))}),this},this.cancel=function(){return d&&(h=!0,o(d),c&&c.reject("CANCEL")),this},this.clone=function(){return new g(b)}}function h(a,b){"function"==typeof b&&(b={0:b});for(var c=a/l,d=1/c,e=[],f=Object.keys(b).map(function(a){return parseInt(a)}),h=0;c>h;h++){var i=f[0],j=d*h;if(null!=i&&100*j>=i){var k=b[""+i];k instanceof g||(k=new g(k)),e.push(k),f.shift()}else e.length&&e.push(e[e.length-1].clone())}return e}function i(a){var c;return"string"==typeof a||a instanceof Array?b.cubicbezier?"string"==typeof a?b.cubicbezier[a]&&(c=b.cubicbezier[a]):a instanceof Array&&4===a.length&&(c=b.cubicbezier.apply(b.cubicbezier,a)):console.error("require lib.cubicbezier"):"function"==typeof a&&(c=a),c}function j(a,b,c){var d,g=h(a,c),j=1/(a/l),k=0,m=i(b);if(!m)throw new Error("unexcept timing function");var n=!1;this.play=function(){function a(){var c=j*(k+1).toFixed(10),e=g[k];e.request(c.toFixed(10),b(c).toFixed(10)).then(function(){n&&(k===g.length-1?(n=!1,d&&d.resolve("FINISH"),d=null):(k++,a()))},function(){})}if(!n)return n=!0,d||(d=e(),f(d.promise,this)),a(),this},this.stop=function(){return n?(n=!1,g[k]&&g[k].cancel(),this):void 0}}var k=60,l=1e3/k,m=a.Promise||b.promise&&b.promise.ES6Promise,n=window.requestAnimationFrame||window.msRequestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||c,o=window.cancelAnimationFrame||window.msCancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||d;(n===c||o===d)&&(n=c,o=d),b.animation=function(a,b,c){return new j(a,b,c)},b.animation.frame=function(a){return new g(a)},b.animation.requestFrame=function(a){var b=new g(a);return b.request()}}(window,window.lib||(window.lib={}));;module.exports = window.lib['animation'];
+
+/***/ },
+/* 34 */
+/***/ function(module, exports) {
+
+  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b){function c(a,b,c,d){function e(a){return(3*k*a+2*l)*a+m}function f(a){return((k*a+l)*a+m)*a}function g(a){return((n*a+o)*a+p)*a}function h(a){for(var b,c,d=a,g=0;8>g;g++){if(c=f(d)-a,Math.abs(c)<j)return d;if(b=e(d),Math.abs(b)<j)break;d-=c/b}var h=1,i=0;for(d=a;h>i;){if(c=f(d)-a,Math.abs(c)<j)return d;c>0?h=d:i=d,d=(h+i)/2}return d}function i(a){return g(h(a))}var j=1e-6,k=3*a-3*c+1,l=3*c-6*a,m=3*a,n=3*b-3*d+1,o=3*d-6*b,p=3*b;return i}b.cubicbezier=c,b.cubicbezier.linear=c(0,0,1,1),b.cubicbezier.ease=c(.25,.1,.25,1),b.cubicbezier.easeIn=c(.42,0,1,1),b.cubicbezier.easeOut=c(0,0,.58,1),b.cubicbezier.easeInOut=c(.42,0,.58,1)}(window,window.lib||(window.lib={}));;module.exports = window.lib['cubicbezier'];
+
+/***/ },
+/* 35 */
+/***/ function(module, exports) {
+
+  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a){"use strict";function b(a,b){for(var c=a;c;){if(c.contains(b)||c==b)return c;c=c.parentNode}return null}function c(a,b,c){var d=i.createEvent("HTMLEvents");if(d.initEvent(b,!0,!0),"object"==typeof c)for(var e in c)d[e]=c[e];a.dispatchEvent(d)}function d(a,b,c,d,e,f,g,h){var i=Math.atan2(h-f,g-e)-Math.atan2(d-b,c-a),j=Math.sqrt((Math.pow(h-f,2)+Math.pow(g-e,2))/(Math.pow(d-b,2)+Math.pow(c-a,2))),k=[e-j*a*Math.cos(i)+j*b*Math.sin(i),f-j*b*Math.cos(i)-j*a*Math.sin(i)];return{rotate:i,scale:j,translate:k,matrix:[[j*Math.cos(i),-j*Math.sin(i),k[0]],[j*Math.sin(i),j*Math.cos(i),k[1]],[0,0,1]]}}function e(a){0===Object.keys(l).length&&(j.addEventListener("touchmove",f,!1),j.addEventListener("touchend",g,!1),j.addEventListener("touchcancel",h,!1));for(var d=0;d<a.changedTouches.length;d++){var e=a.changedTouches[d],i={};for(var m in e)i[m]=e[m];var n={startTouch:i,startTime:Date.now(),status:"tapping",element:a.srcElement||a.target,pressingHandler:setTimeout(function(b,d){return function(){"tapping"===n.status&&(n.status="pressing",c(b,"longpress",{touch:d,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a})),clearTimeout(n.pressingHandler),n.pressingHandler=null}}(a.srcElement||a.target,a.changedTouches[d]),500)};l[e.identifier]=n}if(2==Object.keys(l).length){var o=[];for(var m in l)o.push(l[m].element);c(b(o[0],o[1]),"dualtouchstart",{touches:k.call(a.touches),touchEvent:a})}}function f(a){for(var e=0;e<a.changedTouches.length;e++){var f=a.changedTouches[e],g=l[f.identifier];if(!g)return;g.lastTouch||(g.lastTouch=g.startTouch),g.lastTime||(g.lastTime=g.startTime),g.velocityX||(g.velocityX=0),g.velocityY||(g.velocityY=0),g.duration||(g.duration=0);var h=Date.now()-g.lastTime,i=(f.clientX-g.lastTouch.clientX)/h,j=(f.clientY-g.lastTouch.clientY)/h,k=70;h>k&&(h=k),g.duration+h>k&&(g.duration=k-h),g.velocityX=(g.velocityX*g.duration+i*h)/(g.duration+h),g.velocityY=(g.velocityY*g.duration+j*h)/(g.duration+h),g.duration+=h,g.lastTouch={};for(var m in f)g.lastTouch[m]=f[m];g.lastTime=Date.now();var n=f.clientX-g.startTouch.clientX,o=f.clientY-g.startTouch.clientY,p=Math.sqrt(Math.pow(n,2)+Math.pow(o,2));("tapping"===g.status||"pressing"===g.status)&&p>10&&(g.status="panning",g.isVertical=!(Math.abs(n)>Math.abs(o)),c(g.element,"panstart",{touch:f,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a,isVertical:g.isVertical}),c(g.element,(g.isVertical?"vertical":"horizontal")+"panstart",{touch:f,touchEvent:a})),"panning"===g.status&&(g.panTime=Date.now(),c(g.element,"panmove",{displacementX:n,displacementY:o,touch:f,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a,isVertical:g.isVertical}),g.isVertical?c(g.element,"verticalpanmove",{displacementY:o,touch:f,touchEvent:a}):c(g.element,"horizontalpanmove",{displacementX:n,touch:f,touchEvent:a}))}if(2==Object.keys(l).length){for(var q,r=[],s=[],t=[],e=0;e<a.touches.length;e++){var f=a.touches[e],g=l[f.identifier];r.push([g.startTouch.clientX,g.startTouch.clientY]),s.push([f.clientX,f.clientY])}for(var m in l)t.push(l[m].element);q=d(r[0][0],r[0][1],r[1][0],r[1][1],s[0][0],s[0][1],s[1][0],s[1][1]),c(b(t[0],t[1]),"dualtouch",{transform:q,touches:a.touches,touchEvent:a})}}function g(a){if(2==Object.keys(l).length){var d=[];for(var e in l)d.push(l[e].element);c(b(d[0],d[1]),"dualtouchend",{touches:k.call(a.touches),touchEvent:a})}for(var i=0;i<a.changedTouches.length;i++){var n=a.changedTouches[i],o=n.identifier,p=l[o];if(p){if(p.pressingHandler&&(clearTimeout(p.pressingHandler),p.pressingHandler=null),"tapping"===p.status&&(p.timestamp=Date.now(),c(p.element,"tap",{touch:n,touchEvent:a}),m&&p.timestamp-m.timestamp<300&&c(p.element,"doubletap",{touch:n,touchEvent:a}),m=p),"panning"===p.status){var q=Date.now(),r=q-p.startTime,s=((n.clientX-p.startTouch.clientX)/r,(n.clientY-p.startTouch.clientY)/r,n.clientX-p.startTouch.clientX),t=n.clientY-p.startTouch.clientY,u=Math.sqrt(p.velocityY*p.velocityY+p.velocityX*p.velocityX),v=u>.5&&q-p.lastTime<100,w={duration:r,isflick:v,velocityX:p.velocityX,velocityY:p.velocityY,displacementX:s,displacementY:t,touch:n,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a,isVertical:p.isVertical};c(p.element,"panend",w),v&&(c(p.element,"swipe",w),p.isVertical?c(p.element,"verticalswipe",w):c(p.element,"horizontalswipe",w))}"pressing"===p.status&&c(p.element,"pressend",{touch:n,touchEvent:a}),delete l[o]}}0===Object.keys(l).length&&(j.removeEventListener("touchmove",f,!1),j.removeEventListener("touchend",g,!1),j.removeEventListener("touchcancel",h,!1))}function h(a){if(2==Object.keys(l).length){var d=[];for(var e in l)d.push(l[e].element);c(b(d[0],d[1]),"dualtouchend",{touches:k.call(a.touches),touchEvent:a})}for(var i=0;i<a.changedTouches.length;i++){var m=a.changedTouches[i],n=m.identifier,o=l[n];o&&(o.pressingHandler&&(clearTimeout(o.pressingHandler),o.pressingHandler=null),"panning"===o.status&&c(o.element,"panend",{touch:m,touches:a.touches,changedTouches:a.changedTouches,touchEvent:a}),"pressing"===o.status&&c(o.element,"pressend",{touch:m,touchEvent:a}),delete l[n])}0===Object.keys(l).length&&(j.removeEventListener("touchmove",f,!1),j.removeEventListener("touchend",g,!1),j.removeEventListener("touchcancel",h,!1))}var i=a.document,j=i.documentElement,k=Array.prototype.slice,l={},m=null;j.addEventListener("touchstart",e,!1)}(window);;module.exports = window.lib['gesturejs'];
+
+/***/ },
+/* 36 */
+/***/ function(module, exports) {
+
+  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b){function c(a,b){return[[(a/3+(a+b)/3-a)/(b-a),(a*a/3+a*b*2/3-a*a)/(b*b-a*a)],[(b/3+(a+b)/3-a)/(b-a),(b*b/3+a*b*2/3-a*a)/(b*b-a*a)]]}function d(a){if(this.v=a.v||0,this.a=a.a||0,"undefined"!=typeof a.t&&(this.t=a.t),"undefined"!=typeof a.s&&(this.s=a.s),"undefined"==typeof this.t)if("undefined"==typeof this.s)this.t=-this.v/this.a;else{var b=(Math.sqrt(this.v*this.v+2*this.a*this.s)-this.v)/this.a,c=(-Math.sqrt(this.v*this.v+2*this.a*this.s)-this.v)/this.a;this.t=Math.min(b,c)}"undefined"==typeof this.s&&(this.s=this.a*this.t*this.t/2+this.v*this.t)}d.prototype.generateCubicBezier=function(){return c(this.v/this.a,this.t+this.v/this.a)},b.motion=d}(window,window.lib||(window.lib={}));;module.exports = window.lib['motion'];
+
+/***/ },
+/* 37 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(27)
+  __webpack_require__(38)
+  
+  var FORMATTER_REGEXP = /(\\)?(dd*|hh?|mm?|ss?)/gi
+  
+  function formatDateTime(data, formatter, timeColor) {
+    return formatter.replace(FORMATTER_REGEXP, function (m) {
+      var len = m.length
+      var firstChar = m.charAt(0)
+      // escape character
+      if (firstChar === '\\') {
+        return m.replace('\\', '')
+      }
+      var value = (firstChar === 'd' ? data.days :
+                  firstChar === 'h' ? data.hours :
+                  firstChar === 'm' ? data.minutes :
+                  firstChar === 's' ? data.seconds : 0) + ''
+  
+      // 5 zero should be enough
+      return '<span style="margin:4px;color:'
+        + timeColor + '" >'
+        + ('00000' + value).substr(-Math.max(value.length, len))
+        + '</span>'
+    })
+  }
+  
+  function Countdown (data) {
+    Atomic.call(this, data)
+  }
+  
+  Countdown.prototype = Object.create(Atomic.prototype)
+  
+  Countdown.prototype.create = function () {
+    var node = document.createElement('div')
+    node.classList.add('weex-element')
+    var data = this.data
+    var time = Number(data.attr.countdownTime) || 0
+    var endTime = Date.now() / 1000 + time
+    var cd = lib.countdown({
+      endDate: endTime,
+      onUpdate: function (time) {
+        var timeColor = data.style.timeColor || '#000'
+        var result = formatDateTime(time, data.attr.formatterValue, timeColor)
+        node.innerHTML = result
+      },
+      onEnd: function () {
+      }
+    }).start()
+  
+    return node
+  }
+  
+  Countdown.prototype.style = {
+    textColor: function (value) {
+      this.node.style.color = value
+    }
+  }
+  
+  module.exports = Countdown
+
+
+/***/ },
+/* 38 */
+/***/ function(module, exports) {
+
+  !function(a,b){function c(a){var b;if("number"==typeof a)b=new Date(1e3*a);else if("string"==typeof a){var c=a.charAt(0),d="+"===c,h="-"===c;if(d||h){for(var i,j=a.substr(1),k=j.split(":"),l=[0,0,0,0],m=4;k.length&&--m>=0;)l[m]=parseInt(k.pop())||0;i=e*l[0]+f*l[1]+g*l[2]+l[3],b=new Date,b.setSeconds(b.getSeconds()+i*(h?-1:1)),b.setMilliseconds(0)}}return b||(b=new Date(a)),b}function d(a,b){return b.replace(FORMATTER_REGEXP,function(b){var c=b.length,d=b.charAt(0);if("\\"===d)return b.replace("\\","");var e=("d"===d?a.days:"h"===d?a.hours:"m"===d?a.minutes:"s"===d?a.seconds:0)+"";return("00000"+e).substr(-Math.max(e.length,c))})}var e=86400,f=3600,g=60,h="d天hh时mm分ss秒";FORMATTER_REGEXP=/(\\)?(dd*|hh?|mm?|ss?)/gi;var i=function(a){a=a||{};var b=this,d=c(a.endDate);if(!d||!d.getTime())throw new Error("Invalid endDate");b.endDate=d,b.onUpdate=a.onUpdate,b.onEnd=a.onEnd,b.interval=a.interval||1e3,b.stringFormatter=a.stringFormatter||h,b.correctDateOffset=a.correctDateOffset||0,b.updateElement=a.updateElement,b._data={days:0,hours:0,minutes:0,seconds:0}};i.prototype={start:function(){var a=this;return a.stop(),a._update()&&(a._intervalId=setInterval(function(){a._update()},a.interval)),a},_update:function(){var a,b=this,c=b._data,h=b.updateElement,i=+new Date+1e3*b.correctDateOffset,j=Math.max(0,Math.round((b.endDate.getTime()-i)/1e3)),k=0>=j;return c.totalSeconds=j,j-=(c.days=Math.floor(j/e))*e,j-=(c.hours=Math.floor(j/f))*f,j-=(c.minutes=Math.floor(j/g))*g,c.seconds=j,c.stringValue=d(c,b.stringFormatter),h&&(h.innerHTML=c.stringValue),(a=b.onUpdate)&&a.call(b,c),k?(b.stop(),(a=b.onEnd)&&a.call(b),!1):!0},stop:function(){var a=this;return a._intervalId&&(clearInterval(a._intervalId),a._intervalId=null),a},setEndDate:function(a){var b=this;return b.endDate=c(a),b}},b.countdown=function(a){return new i(a)}}(window,window.lib||(window.lib={}));
+
+/***/ },
+/* 39 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var config = __webpack_require__(5)
+  var Component = __webpack_require__(16)
+  var ComponentManager = __webpack_require__(9)
+  var LazyLoad = __webpack_require__(12)
+  
+  function Marquee (data) {
+    this.interval = Number(data.attr.interval) || 5 * 1000
+    this.transitionDuration = Number(data.attr.transitionDuration) || 500
+    this.delay = Number(data.attr.delay) || 0
+    Component.call(this, data)
+  }
+  
+  Marquee.prototype = Object.create(Component.prototype)
+  
+  Marquee.prototype.create = function () {
+    var node = document.createElement('div')
+    node.classList.add('weex-container')
+    node.style.overflow = 'hidden'
+    // fix page shaking during slider's playing
+    node.style.webkitTransform = 'translate3D(0,0,0)'
+    node.addEventListener('webkitTransitionEnd', this.end.bind(this), false)
+    return node
+  }
+  
+  Marquee.prototype.createChildren = function () {
+    // first run:
+    // - create each child
+    // - append to parentNode
+    // - find current and next
+    // - set current and next shown and others hidden
+    var children = this.data.children
+    var parentRef = this.data.ref
+    var instanceId = this.data.instanceId
+    var items = []
+    var componentManager = this.getComponentManager()
+  
+    var fragment, isFlex, child, node, i
+  
+    if (children && children.length) {
+      fragment = document.createDocumentFragment()
+      isFlex = false
+      for (i = 0; i < children.length; i++) {
+        children[i].scale = this.data.scale
+        children[i].instanceId = instanceId
+        child = componentManager.createElement(children[i])
+        child.parentRef = parentRef
+        this.initChild(child)
+        // append and push
+        items.push(child)
+        fragment.appendChild(child.node)
+        if (!isFlex && child.data.style.hasOwnProperty('flex')) {
+          isFlex = true
+        }
+      }
+      this.node.appendChild(fragment)
+    }
+  
+    // set items
+    this.items = items
+  
+    // reset the clock for first transition
+    this.reset()
+  }
+  
+  Marquee.prototype.initChild = function (child) {
+    var node = child.node
+    node.style.position = 'absolute'
+    node.style.top = '0'
+    node.style.left = '0'
+  }
+  
+  Marquee.prototype.appendChild = function (data) {
+    // dom + items
+    var componentManager = ComponentManager.getInstance(this.data.instanceId)
+    var child = componentManager.createElement(data)
+    this.initChild(child)
+    this.node.appendChild(child.node)
+    this.items.push(child)
+    this.reset()
+    return child // @todo redesign Component#appendChild(component)
+  }
+  
+  Marquee.prototype.insertBefore = function (child, before) {
+    // dom + items
+    var index = this.items.indexOf(before)
+    this.items.splice(index, 0, child)
+    this.initChild(child)
+    this.node.insertBefore(child.node, before.node)
+    this.reset()
+  }
+  
+  Marquee.prototype.removeChild = function (child) {
+    // dom + items
+    var index = this.items.indexOf(child)
+    this.items.splice(index, 1)
+    this.node.removeChild(child.node)
+    this.reset()
+  }
+  
+  /**
+   * status: {
+   *   current: {translateY: 0, shown: true},
+   *   next: {translateY: height, shown: true},
+   *   others[]: {shown: false}
+   *   index: index
+   * }
+   */
+  Marquee.prototype.reset = function () {
+    var interval = this.interval - 0
+    var delay = this.delay - 0
+    var items = this.items
+    var self = this
+  
+    var loop = function () {
+      self.next()
+      self.timerId = setTimeout(loop, self.interval)
+    }
+  
+    // reset display and transform
+    items.forEach(function (item, index) {
+      var node = item.node
+      // set non-current(0)|next(1) item hidden
+      node.style.display = index > 1 ? 'none' : ''
+      // set next(1) item translateY
+      // TODO: it supposed to use item.data.style
+      // but somehow the style object is empty.
+      // This problem relies on jsframework's bugfix.
+  
+      // node.style.transform = index === 1
+      //     ? 'translate3D(0,' + config.scale * item.data.style.height + 'px,0)'
+      //     : ''
+      // node.style.webkitTransform = index === 1
+      //     ? 'translate3D(0,' + config.scale * item.data.style.height + 'px,0)'
+      //     : ''
+      node.style.transform = index === 1
+          ? 'translate3D(0,' + self.data.scale * self.data.style.height + 'px,0)'
+          : ''
+      node.style.webkitTransform = index === 1
+          ? 'translate3D(0,' + self.data.scale * self.data.style.height + 'px,0)'
+          : ''
+    })
+  
+    setTimeout(function () {
+      // reset current, next, index
+      self.currentItem = items[0]
+      self.nextItem = items[1]
+      self.currentIndex = 0
+  
+      items.forEach(function (item, index) {
+        var node = item.node
+        // set transition
+        node.style.transition = 'transform '
+            + self.transitionDuration
+            + 'ms ease'
+        node.style.webkitTransition = '-webkit-transform '
+            + self.transitionDuration
+            + 'ms ease'
+      })
+  
+      clearTimeout(self.timerId)
+  
+      if (items.length > 1) {
+        self.timerId = setTimeout(loop, delay + interval)
+      }
+    }, 13)
+  
+  }
+  
+  /**
+   * next:
+   * - current: {translateY: -height}
+   * - next: {translateY: 0}
+   */
+  Marquee.prototype.next = function () {
+    // - update state
+    //   - set current and next transition
+    //   - hide current when transition end
+    //   - set next to current
+    //   - find new next
+    var next = this.nextItem.node
+    var current = this.currentItem.node
+    this.transitionIndex = this.currentIndex
+  
+    // Use setTimeout to fix the problem that when the
+    // page recover from backstage, the slider will
+    // not work any longer.
+    setTimeout(function () {
+      next.style.transform = 'translate3D(0,0,0)'
+      next.style.webkitTransform = 'translate3D(0,0,0)'
+      current.style.transform = 'translate3D(0,-'
+          + this.data.scale * this.data.style.height
+          + 'px,0)'
+      current.style.webkitTransform = 'translate3D(0,-'
+          + this.data.scale * this.data.style.height
+          + 'px,0)'
+      this.fireEvent('change')
+    }.bind(this), 300)
+  }
+  
+  Marquee.prototype.fireEvent = function (type) {
+    var length = this.items.length
+    var nextIndex = (this.currentIndex + 1) % length
+    var evt = document.createEvent('HTMLEvents')
+    evt.initEvent(type, false, false)
+    evt.data = {
+      prevIndex: this.currentIndex,
+      index: nextIndex
+    }
+    this.node.dispatchEvent(evt)
+  }
+  
+  /**
+   * end:
+   * - old current: {shown: false}
+   * - old current: {translateY: 0}
+   * - index++ % length
+   * - new current = old next
+   * - new next = items[index+1 % length]
+   * - new next: {translateY: height}
+   * - new next: {shown: true}
+   */
+  Marquee.prototype.end = function (e) {
+    var target = e.target
+    var items = this.items
+    var length = items.length
+    var current, next
+    var currentIndex, nextIndex
+  
+    currentIndex = this.transitionIndex
+  
+    if (isNaN(currentIndex)) {
+      return
+    }
+    delete this.transitionIndex
+  
+    current = this.currentItem.node
+    current.style.display = 'none'
+    current.style.webkitTransform = ''
+  
+    currentIndex = (currentIndex + 1) % length
+    nextIndex = (currentIndex + 1) % length
+  
+    this.currentIndex = currentIndex
+    this.currentItem = this.nextItem
+    this.nextItem = items[nextIndex]
+  
+    setTimeout(function () {
+      next = this.nextItem.node
+      // TODO: it supposed to use this.nextItem.data.style
+      // but somehow the style object is empty.
+      // This problem relies on jsframework's bugfix.
+  
+      next.style.webkitTransform = 'translate3D(0,'
+          + this.data.scale * this.data.style.height
+          + 'px,0)'
+      next.style.display = ''
+      LazyLoad.loadIfNeeded(next)
+    }.bind(this))
+  }
+  
+  Marquee.prototype.attr = {
+    interval: function (value) {
+      this.interval = value
+    },
+    transitionDuration: function (value) {
+      this.transitionDuration = value
+    },
+    delay: function (value) {
+      this.delay = value
+    }
+  }
+  
+  Marquee.prototype.clearAttr = function () {
+    this.interval = 5 * 1000
+    this.transitionDuration = 500
+    this.delay = 0
+  }
+  
+  module.exports = Marquee
+
+
+/***/ },
+/* 40 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var extend = __webpack_require__(7).extend
+  var config = __webpack_require__(5)
+  var Component = __webpack_require__(16)
+  var ComponentManager = __webpack_require__(9)
+  var LazyLoad = __webpack_require__(12)
+  __webpack_require__(41)
+  __webpack_require__(42)
+  
+  function Slider (data) {
+    this.autoPlay = true  // always true for autoplay
+    this.direction = 'row' // 'column' is not temporarily supported.
+    this.children = []
+    this.isPageShow = true
+    this.isDomRendering = true
+  
+    // bind event 'pageshow' and 'pagehide' on window.
+    this._idleWhenPageDisappear()
+    // bind event 'renderBegin' and 'renderEnd' on window.
+    this._idleWhenDomRendering()
+  
+    Component.call(this, data)
+  }
+  
+  Slider.prototype = Object.create(Component.prototype)
+  
+  Slider.prototype._idleWhenPageDisappear = function () {
+    var _this = this
+    window.addEventListener('pageshow', function () {
+      _this.isPageShow = true
+      _this.autoPlay && !_this.isDomRendering && _this.play()
+    })
+    window.addEventListener('pagehide', function () {
+      _this.isPageShow = false
+      _this.stop()
+    })
+  }
+  
+  Slider.prototype._idleWhenDomRendering = function () {
+    var _this = this
+    window.addEventListener('renderend', function () {
+      _this.isDomRendering = false
+      _this.autoPlay && _this.isPageShow && _this.play()
+    })
+    window.addEventListener('renderbegin', function () {
+      _this.isDomRendering = true
+      _this.stop()
+    })
+  }
+  
+  Slider.prototype.attr = {
+    interval: function (val) {
+      this.interval = parseInt(val) || 3000
+      if (this.carrousel) {
+        this.carrousel.playInterval = this.interval
+      }
+    },
+  
+    playstatus: function (val) {
+      this.playstatus = val && val !== 'false' ? true : false
+      this.autoPlay = this.playstatus
+      if (this.carrousel) {
+        if (this.playstatus) {
+          this.play()
+        } else {
+          this.stop()
+        }
+      }
+    },
+  
+    // support playstatus' alias auto-play for compatibility
+    autoPlay: function (val) {
+      this.attr.playstatus.call(this, val)
+    }
+  }
+  
+  Slider.prototype.create = function () {
+    var node = document.createElement('div')
+    node.classList.add('slider')
+    node.style.position = 'relative'
+    node.style.overflow = 'hidden'
+    return node
+  }
+  
+  Slider.prototype._doRender = function () {
+    var _this = this
+    _this.createChildren()
+    _this.onAppend()
+  }
+  
+  Slider.prototype.removeChild = function (child) {
+    var children = this.data.children
+    if (children) {
+      for (var i = 0; i < children.length; i++) {
+        if (child.data.ref === children[i].ref) {
+          children.splice(i, 1)
+          break
+        }
+      }
+    }
+  
+    this._doRender()
+  }
+  
+  Slider.prototype.insertBefore = function (child, before) {
+    var children = this.data.children
+    // var childIndex = this.children.indexOf(before.data)
+    var childIndex = -1
+    for (var i = 0, l = children.length; i < l; i++) {
+      if (children[i].ref === before.data.ref) {
+        childIndex = i
+        break
+      }
+    }
+    children.splice(childIndex, 0, child.data)
+  
+    this._doRender()
+    if (this.children.length > 0) {
+      return this.children[this.children.length - 1]
+    }
+  }
+  
+  Slider.prototype.appendChild = function (data) {
+    var children = this.data.children || (this.data.children = [])
+    children.push(data)
+    this._doRender()
+    if (this.children.length > 0) {
+      return this.children[this.children.length - 1]
+    }
+  }
+  
+  Slider.prototype.createChildren = function () {
+  
+    var componentManager = this.getComponentManager()
+  
+    // recreate slider container.
+    if (this.sliderContainer) {
+      this.node.removeChild(this.sliderContainer)
+    }
+    if (this.indicator) {
+      this.indicator.node.parentNode.removeChild(this.indicator.node)
+    }
+    this.children = []
+  
+    var sliderContainer = document.createElement('ul')
+    sliderContainer.style.listStyle = 'none'
+    this.node.appendChild(sliderContainer)
+    this.sliderContainer = sliderContainer
+  
+    var children = this.data.children
+    var scale = this.data.scale
+    var fragment = document.createDocumentFragment()
+    var indicatorData, width, height
+    var childWidth = 0
+    var childHeight = 0
+  
+    if (children && children.length) {
+      for (var i = 0; i < children.length; i++) {
+        var child
+        children[i].scale = this.data.scale
+        children[i].instanceId = this.data.instanceId
+        if (children[i].type === 'indicator') {
+          indicatorData = extend(children[i], {
+            extra: {
+              amount: children.length - 1,
+              index: 0
+            }
+          })
+        } else {
+          child = componentManager.createElement(children[i], 'li')
+          this.children.push(child)
+          fragment.appendChild(child.node)
+          width = child.data.style.width || 0
+          height = child.data.style.height || 0
+          width > childWidth && (childWidth = width)
+          height > childHeight && (childHeight = height)
+          child.parentRef = this.data.ref
+        }
+      }
+      // append indicator
+      if (indicatorData) {
+        indicatorData.extra.width = this.data.style.width || childWidth
+        indicatorData.extra.height = this.data.style.height || childHeight
+        this.indicator = componentManager.createElement(indicatorData)
+        this.indicator.parentRef = this.data.ref
+        this.indicator.slider = this
+        this.node.appendChild(this.indicator.node)
+      }
+  
+      sliderContainer.style.height = scale * this.data.style.height + 'px'
+      sliderContainer.appendChild(fragment)
+    }
+  }
+  
+  Slider.prototype.onAppend = function () {
+    if (this.carrousel) {
+      this.carrousel.removeEventListener('change', this._getSliderChangeHandler())
+      this.carrousel.stop()
+      this.carrousel = null
+    }
+    this.carrousel = new lib.carrousel(this.sliderContainer, {
+      autoplay: this.autoPlay,
+      useGesture: true
+    })
+  
+    this.carrousel.playInterval = this.interval
+    this.carrousel.addEventListener('change', this._getSliderChangeHandler())
+    this.currentIndex = 0
+  
+    // preload all images for slider
+    // because:
+    // 1. lib-img doesn't listen to event transitionend
+    // 2. even if we fire lazy load in slider's change event handler,
+    //    the next image still won't be preloaded utill the moment it
+    //    slides into the view, which is too late.
+    if (this.preloadImgsTimer) {
+      clearTimeout(this.preloadImgsTimer)
+    }
+    // The time just before the second slide appear and enough
+    // for all child elements to append is ok.
+    var preloadTime = 0.8
+    this.preloadImgsTimer = setTimeout(function () {
+      var imgs = this.carrousel.element.querySelectorAll('img')
+      for (var i = 0, l = imgs.length; i < l; i++) {
+        var img = imgs[i]
+        var iLazySrc = img.getAttribute('i-lazy-src')
+        var imgSrc = img.getAttribute('img-src')
+        if (iLazySrc) {
+          img.setAttribute('src', iLazySrc)
+        } else if (imgSrc) {
+          img.setAttribute('src', imgSrc)
+        }
+        img.removeAttribute('i-lazy-src')
+        img.removeAttribute('img-src')
+      }
+    }.bind(this), preloadTime * 1000)
+  
+    // avoid page scroll when panning
+    var panning = false
+    this.carrousel.element.addEventListener('panstart', function (e) {
+      if (!e.isVertical) {
+        panning = true
+      }
+    })
+    this.carrousel.element.addEventListener('panend', function (e) {
+      if (!e.isVertical) {
+        panning = false
+      }
+    })
+  
+    document.addEventListener('touchmove', function (e) {
+      if (panning) {
+        e.preventDefault()
+        return false
+      }
+      return true
+    }.bind(this))
+  
+  }
+  
+  Slider.prototype._updateIndicators = function () {
+    this.indicator && this.indicator.setIndex(this.currentIndex)
+  }
+  
+  Slider.prototype._getSliderChangeHandler = function (e) {
+    if (!this.sliderChangeHandler) {
+      this.sliderChangeHandler = (function (e) {
+        var index = this.carrousel.items.index
+        this.currentIndex = index
+  
+        // updateIndicators
+        this._updateIndicators()
+  
+        this.dispatchEvent('change', { index: index })
+      }).bind(this)
+    }
+    return this.sliderChangeHandler
+  }
+  
+  Slider.prototype.play = function () {
+    this.carrousel.play()
+  }
+  
+  Slider.prototype.stop = function () {
+    this.carrousel.stop()
+  }
+  
+  Slider.prototype.slideTo = function (index) {
+    var offset = index - this.currentIndex
+    this.carrousel.items.slide(offset)
+  }
+  
+  module.exports = Slider
+
+
+/***/ },
+/* 41 */
+/***/ function(module, exports, __webpack_require__) {
+
+  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});__webpack_require__(33);__webpack_require__(34);__webpack_require__(35);!function(){var a="[data-ctrl-name=carrousel]{position:relative;-webkit-transform:translateZ(1px);-ms-transform:translateZ(1px);transform:translateZ(1px)}",b=document.createElement("style");if(document.getElementsByTagName("head")[0].appendChild(b),b.styleSheet)b.styleSheet.disabled||(b.styleSheet.cssText=a);else try{b.innerHTML=a}catch(c){b.innerText=a}}();!function(a,b,c){function d(a){var b,c={x:0,y:0},d=getComputedStyle(a)[l+"Transform"];return"none"!==d&&(b=d.match(/^matrix3d\((?:[-\d.]+,\s*){12}([-\d.]+),\s*([-\d.]+)(?:,\s*[-\d.]+){2}\)/)||d.match(/^matrix\((?:[-\d.]+,\s*){4}([-\d.]+),\s*([-\d.]+)\)$/))&&(c.x=parseFloat(b[1])||0,c.y=parseFloat(b[2])||0),c}function e(a,b){return a=parseFloat(a),b=parseFloat(b),0!=a&&(a+="px"),0!=b&&(b+="px"),n?"translate3d("+a+", "+b+", 0)":"translate("+a+", "+b+")"}function f(a){return o.call(a)}function g(a,c){function g(a,b){var c=h.createEvent("HTMLEvents");if(c.initEvent(a,!1,!1),b)for(var d in b)c[d]=b[d];n.dispatchEvent(c)}function i(a){for(;0>a;)a+=r;for(;a>=r;)a-=r;return a}function j(a){if(0!==r){var b,c,d=q.get(a);r>1&&(b=q.get(a-1),c=2===r?q.getCloned(a+1):q.get(a+1),d.style.left=-o+"px",b.style.left=-o-s+"px",c.style.left=-o+s+"px"),t=d.index,g("change",{prevItem:b,curItem:d,nextItem:c})}}var k=this,m=Date.now()+"-"+ ++p,n=document.createDocumentFragment();1!==arguments.length||arguments[0]instanceof HTMLElement||(c=arguments[0],a=null),a||(a=document.createElement("ul"),n.appendChild(a)),c=c||{},a.setAttribute("data-ctrl-name","carrousel"),a.setAttribute("data-ctrl-id",m),a.style.position="relative",a.style[l+"Transform"]=e(0,0);var o=0,q={},r=0,s=c.step||a.getBoundingClientRect().width,t=0;q.add=function(b){var c=document.createElement("li");return c.style.display="none",c.style["float"]="left",c.index=r,"string"==typeof b?c.innerHTML=b:b instanceof HTMLElement&&c.appendChild(b),a.appendChild(c),Object.defineProperty(q,r+"",{get:function(){return c}}),r++,c},q.get=function(a){return q[i(a)]},q.getCloned=function(b){function c(a,b,d){var e=a._listeners;if(e){b._listeners=e;for(var f in e)b.addEventListener(f,e[f])}if(d&&a.children&&a.children.length)for(var g=0,h=a.children.length;h>g;g++)c(a.children[g],b.children[g],d)}var b=i(b),d=a.querySelector('[cloned="cloned-'+b+'"]'),e=q[b];return d||(d=e.cloneNode(!0),c(e,d,!0),a.appendChild(d),d.setAttribute("cloned","cloned-"+b),d.index=b),d},q.slide=function(c){if(0!==r){1===r&&(c=0);var f=d(a).x,g=o+s*-c,h=g-f;if(0!==h){new b.animation(400,b.cubicbezier.ease,function(b,c){a.style[l+"Transform"]=e(f+h*c,0)}).play().then(function(){o=g,a.style[l+"Transform"]=e(g,0),c&&j(t+c)})}}},q.next=function(){q.slide(1)},q.prev=function(){q.slide(-1)},f(a.querySelectorAll("li")).forEach(function(a){a.style.position="absolute",a.style.top="0",a.style.left=r*s+"px",a.style["float"]="left",a.index=r,Object.defineProperty(q,r+"",{get:function(){return a}}),r++}),Object.defineProperty(this,"items",{get:function(){return q}}),Object.defineProperty(q,"length",{get:function(){return r}}),Object.defineProperty(q,"index",{get:function(){return t}}),Object.defineProperty(q,"step",{get:function(){return s},set:function(a){s=a}});var u=!1,v=!1,w=!1;this.play=function(){return u?void(v||(v=setTimeout(function(){w=!0,q.next(),setTimeout(function(){w=!1},500),v=setTimeout(arguments.callee,400+z)},400+z))):(u=!0,j(0))},this.stop=function(){v&&(clearTimeout(v),setTimeout(function(){v=!1},500))};var x=!1,y=!1;Object.defineProperty(this,"autoplay",{get:function(){return x},set:function(a){x=!!a,y&&(clearTimeout(y),y=!1),x?y=setTimeout(function(){k.play()},2e3):k.stop()}}),this.autoplay=!!c.autoplay;var z=1500;if(Object.defineProperty(this,"playInterval",{get:function(){return z},set:function(a){z=a}}),this.playInterval=!!c.playInterval||1500,c.useGesture){var A,B=!1;a.addEventListener("panstart",function(a){a.isVertical||B&&w||(a.preventDefault(),a.stopPropagation(),x&&k.stop(),A=0,B=!0)}),a.addEventListener("panmove",function(b){!b.isVertical&&B&&(b.preventDefault(),b.stopPropagation(),A=b.displacementX,a.style[l+"Transform"]=e(o+A,0))}),a.addEventListener("panend",function(a){!a.isVertical&&B&&(a.preventDefault(),a.stopPropagation(),B=!1,a.isflick?0>A?q.next():q.prev():Math.abs(A)<s/2?q.slide(0):q.slide(0>A?1:-1),x&&setTimeout(function(){k.play()},2e3))},!1),a.addEventListener("swipe",function(a){a.isVertical||(a.preventDefault(),a.stopPropagation())})}this.addEventListener=function(a,b){this.root.addEventListener(a,b,!1)},this.removeEventListener=function(a,b){this.root.removeEventListener(a,b,!1)},this.root=n,this.element=a}var h=a.document,i=a.navigator.userAgent,j=!!i.match(/Firefox/i),k=!!i.match(/IEMobile/i),l=j?"Moz":k?"ms":"webkit",m=k?"MSCSSMatrix":"WebKitCSSMatrix",n=!!j||m in a&&"m11"in new a[m],o=Array.prototype.slice,p=0;b.carrousel=g}(window,window.lib,window.ctrl||(window.ctrl={}));;module.exports = window.lib['carrousel'];
+
+/***/ },
+/* 42 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(43);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./slider.scss", function() {
+        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./slider.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 43 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".slider {\n  position: relative; }\n\n.slider .indicator-container {\n  position: absolute;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-box-align: center;\n  box-align: center;\n  -webkit-align-items: center;\n  align-items: center;\n  -webkit-box-pack: center;\n  box-pack: center;\n  -webkit-justify-content: center;\n  justify-content: center;\n  font-size: 0; }\n  .slider .indicator-container .indicator {\n    border-radius: 50%; }\n  .slider .indicator-container.row {\n    -webkit-box-orient: horizontal;\n    box-orient: horizontal;\n    -webkit-flex-direction: row;\n    flex-direction: row; }\n  .slider .indicator-container.column {\n    -webkit-box-orient: vertical;\n    box-orient: vertical;\n    -webkit-flex-direction: column;\n    flex-direction: column; }\n", "", {"version":3,"sources":["/./src/src/styles/slider.scss"],"names":[],"mappings":"AAAA;EACE,mBAAmB,EACpB;;AACD;EACE,mBAAmB;EACnB,qBAAqB;EACrB,sBAAsB;EACtB,cAAc;EACd,0BAA0B;EAC1B,kBAAkB;EAClB,4BAA4B;EAC5B,oBAAoB;EACpB,yBAAyB;EACzB,iBAAiB;EACjB,gCAAgC;EAChC,wBAAwB;EACxB,aAAa,EAoBd;EAjCD;IAgBI,mBAAmB,EACpB;EAjBH;IAoBI,+BAA+B;IAC/B,uBAAuB;IACvB,4BAA4B;IAC5B,oBAAoB,EACrB;EAxBH;IA2BI,6BAA6B;IAC7B,qBAAqB;IACrB,+BAA+B;IAC/B,uBAAuB,EACxB","file":"slider.scss","sourcesContent":[".slider {\n  position: relative;\n}\n.slider .indicator-container {\n  position: absolute;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-box-align: center;\n  box-align: center;\n  -webkit-align-items: center;\n  align-items: center;\n  -webkit-box-pack: center;\n  box-pack: center;\n  -webkit-justify-content: center;\n  justify-content: center;\n  font-size: 0;\n\n  .indicator {\n    border-radius: 50%;\n  }\n\n  &.row {\n    -webkit-box-orient: horizontal;\n    box-orient: horizontal;\n    -webkit-flex-direction: row;\n    flex-direction: row;\n  }\n\n  &.column {\n    -webkit-box-orient: vertical;\n    box-orient: vertical;\n    -webkit-flex-direction: column;\n    flex-direction: column;\n  }\n\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 44 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var extend = __webpack_require__(7).extend
+  var config = __webpack_require__(5)
+  var Atomic = __webpack_require__(27)
+  var Component = __webpack_require__(16)
+  
+  __webpack_require__(45)
+  
+  var DEFAULT_ITEM_COLOR = '#999'
+  var DEFAULT_ITEM_SELECTED_COLOR = '#0000ff'
+  var DEFAULT_ITEM_SIZE = 20
+  var DEFAULT_MARGIN_SIZE = 10
+  
+  // Style supported:
+  //   position: (default - absolute)
+  //   itemColor: color of indicator dots
+  //   itemSelectedColor: color of the selected indicator dot
+  //   itemSize: size of indicators
+  //   other layout styles
+  function Indicator (data) {
+    this.direction = 'row' // 'column' is not temporarily supported.
+    this.amount = data.extra.amount
+    this.index = data.extra.index
+    this.sliderWidth = data.extra.width
+    this.sliderHeight = data.extra.height
+    var styles = data.style || {}
+    this.data = data
+    this.style.width.call(this, styles.width)
+    this.style.height.call(this, styles.height)
+    this.items = []
+    Atomic.call(this, data)
+  }
+  
+  Indicator.prototype = Object.create(Atomic.prototype)
+  
+  Indicator.prototype.create = function () {
+    var node = document.createElement('div')
+    node.classList.add('weex-indicators')
+    node.classList.add('weex-element')
+    node.style.position = 'absolute'
+    this.node = node
+    this.style.itemSize.call(this, 0)
+    this.itemColor = DEFAULT_ITEM_COLOR
+    this.itemSelectedColor = DEFAULT_ITEM_SELECTED_COLOR
+    this.updateStyle({
+      left: 0,
+      top: 0,
+      itemSize: 0
+    })
+    return node
+  }
+  
+  Indicator.prototype.createChildren = function () {
+    var root = document.createDocumentFragment()
+    for (var i = 0; i < this.amount; i++) {
+      var indicator = document.createElement('div')
+      indicator.classList.add('weex-indicator')
+      indicator.style.boxSizing = 'border-box'
+      indicator.style.margin = '0 '
+                              + (DEFAULT_MARGIN_SIZE * this.data.scale)
+                              + 'px'
+      indicator.style.width = this.itemSize + 'px'
+      indicator.style.height = this.itemSize + 'px'
+      indicator.setAttribute('index', i)
+      if (this.index === i) {
+        indicator.style.backgroundColor = this.itemSelectedColor
+      } else {
+        indicator.style.backgroundColor = this.itemColor
+      }
+      indicator.addEventListener('click', this._clickHandler.bind(this, i))
+      this.items[i] = indicator
+      root.appendChild(indicator)
+    }
+    this.node.appendChild(root)
+  }
+  
+  Indicator.prototype.style
+      = extend(Object.create(Atomic.prototype.style), {
+    itemColor: function (val) {
+      this.itemColor = val || DEFAULT_ITEM_COLOR
+      for (var i = 0, l = this.items.length; i < l; i++) {
+        this.items[i].style.backgroundColor = this.itemColor
+      }
+    },
+  
+    itemSelectedColor: function (val) {
+      this.itemSelectedColor = val || DEFAULT_ITEM_SELECTED_COLOR
+      if (typeof this.index !== 'undefined'
+          && this.items.length > this.index) {
+        this.items[this.index].style.backgroundColor
+            = this.itemSelectedColor
+      }
+    },
+  
+    itemSize: function (val) {
+      val = parseInt(val) * this.data.scale
+            || DEFAULT_ITEM_SIZE * this.data.scale
+      this.itemSize = val
+      this.node.style.height = val + 'px'
+      for (var i = 0, l = this.items.length; i < l; i++) {
+        this.items[i].style.width = val + 'px'
+        this.items[i].style.height = val + 'px'
+      }
+    },
+  
+    width: function (val) {
+      val = parseInt(val) * this.data.scale || parseInt(this.sliderWidth)
+      this.virtualWrapperWidth = val
+    },
+  
+    height: function (val) {
+      val = parseInt(val) * this.data.scale || parseInt(this.sliderHeight)
+      this.virtualWrapperHeight = val
+    },
+  
+    top: function (val) {
+      val = this.virtualWrapperHeight / 2 - this.itemSize / 2
+          + val * this.data.scale
+      this.node.style.bottom = ''
+      this.node.style.top = val + 'px'
+    },
+  
+    bottom: function (val) {
+      val = this.virtualWrapperHeight / 2 - this.itemSize / 2
+          + val * this.data.scale
+      this.node.style.top = ''
+      this.node.style.bottom = val + 'px'
+    },
+  
+    left: function (val) {
+      val = this.virtualWrapperWidth / 2
+            - (this.itemSize + 2 * DEFAULT_MARGIN_SIZE * this.data.scale)
+                * this.amount / 2
+            + val * this.data.scale
+      this.node.style.right = ''
+      this.node.style.left = val + 'px'
+    },
+  
+    right: function (val) {
+      val = this.virtualWrapperWidth / 2
+            - (this.itemSize + 2 * DEFAULT_MARGIN_SIZE * this.data.scale)
+                * this.amount / 2
+            + val * this.data.scale
+      this.node.style.left = ''
+      this.node.style.right = val + 'px'
+    }
+  })
+  
+  Indicator.prototype.setIndex = function (idx) {
+    if (idx >= this.amount) {
+      return
+    }
+    var prev = this.items[this.index]
+    var cur = this.items[idx]
+    prev.classList.remove('active')
+    prev.style.backgroundColor = this.itemColor
+    cur.classList.add('active')
+    cur.style.backgroundColor = this.itemSelectedColor
+    this.index = idx
+  }
+  
+  Indicator.prototype._clickHandler = function (idx) {
+    this.slider.slideTo(idx)
+  }
+  
+  module.exports = Indicator
+
+
+/***/ },
+/* 45 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(46);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./indicator.scss", function() {
+        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./indicator.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 46 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".weex-indicators {\n  position: absolute;\n  white-space: nowrap; }\n  .weex-indicators .weex-indicator {\n    float: left;\n    border-radius: 50%; }\n", "", {"version":3,"sources":["/./src/src/styles/indicator.scss"],"names":[],"mappings":"AAAA;EACE,mBAAmB;EACnB,oBAAoB,EAOrB;EATD;IAKI,YAAY;IACZ,mBAAmB,EACpB","file":"indicator.scss","sourcesContent":[".weex-indicators {\n  position: absolute;\n  white-space: nowrap;\n\n  .weex-indicator {\n    float: left;\n    border-radius: 50%;\n  }\n\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 47 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(27)
+  var msgQueue = __webpack_require__(48)
+  var config = __webpack_require__(5)
+  var utils = __webpack_require__(7)
+  
+  // TODO: refactor this scss code since this is strongly
+  // dependent on lib.flexible other than the value of
+  // scale.
+  __webpack_require__(49)
+  
+  function TabHeader(data) {
+    Atomic.call(this, data)
+  }
+  
+  var proto = TabHeader.prototype = Object.create(Atomic.prototype)
+  
+  proto.create = function () {
+    // outside container.
+    var node = document.createElement('div')
+    node.className = 'tab-header'
+    // tip on the top.
+    var bar = document.createElement('div')
+    bar.className = 'header-bar'
+    bar.textContent = 'CHANGE FLOOR'
+    // middle layer.
+    var body = document.createElement('div')
+    body.className = 'header-body'
+    var box = document.createElement('ul')
+    box.className = 'tabheader'
+  
+    body.appendChild(box)
+    node.appendChild(bar)
+    node.appendChild(body)
+    this._bar = bar
+    this._body = body
+    this.box = box
+    this.node = node
+    // init events.
+    this._initFoldBtn()
+    this._initEvent()
+    return node
+  }
+  
+  proto._initFoldBtn = function () {
+    var _this = this
+    var node = this.node
+    var btn = document.createElement('span')
+    btn.className = 'fold-toggle iconfont'
+    btn.innerHTML = '&#xe661;'
+    node.appendChild(btn)
+  
+    btn.addEventListener('click', function () {
+      if (_this.unfolding) {
+        _this._folding()
+      } else {
+        _this._unfolding()
+      }
+    })
+  }
+  
+  proto._initMask = function () {
+    var mask = document.createElement('div')
+    mask.className = 'tabheader-mask'
+    this.mask = mask
+    // stop default behavior: page moving.
+    mask.addEventListener('touchmove', function (evt) {
+      evt.preventDefault()
+    })
+    // click to unfold.
+    var _this = this
+    mask.addEventListener('click', function () {
+      _this._folding()
+    })
+  
+    document.body.appendChild(mask)
+  }
+  
+  proto._unfolding = function () {
+    // mark the initial posiiton of tabheader
+    if (!this.flag) {
+      var flag = document.createComment('tabheader')
+      this.flag = flag
+      this.node.parentNode.insertBefore(flag, this.node)
+    }
+    if (!this.mask) {
+      this._initMask()
+    }
+  
+    // record the scroll position.
+    this._scrollVal = this._body.scrollLeft
+    // record the position in document.
+    this._topVal = this.node.getBoundingClientRect().top
+    this._styleTop = this.node.style.top
+  
+    document.body.appendChild(this.node)
+    this.node.classList.add('unfold-header')
+    this.node.style.height = 'auto'
+    // recalc the position when it is unfolded.
+    var thHeight = this.node.getBoundingClientRect().height
+    if (thHeight + this._topVal > window.innerHeight) {
+      this._topVal = this._topVal
+          + (window.innerHeight - thHeight - this._topVal)
+    }
+  
+    this.node.style.top = this._topVal + 'px'
+    // process mask style
+    this.mask.classList.add('unfold-header')
+    this.mask.style.height = window.innerHeight + 'px'
+    this.unfolding = true
+  }
+  
+  proto._folding = function () {
+    if (this.unfolding !== true) {
+      return
+    }
+  
+    this.mask.classList.remove('unfold-header')
+    this.node.classList.remove('unfold-header')
+  
+    this.node.style.height = ''
+    this.node.style.top = this._styleTop
+  
+    // recover the position of tabheader.
+    this.flag.parentNode.insertBefore(this.node, this.flag)
+    // recover the position of scoller.
+    this._body.scrollLeft = this._scrollVal
+  
+    this._scrollToView()
+    this.unfolding = false
+  }
+  
+  proto._initEvent = function () {
+    this._initClickEvent()
+    this._initSelectEvent()
+  }
+  
+  // init events.
+  proto._initClickEvent = function () {
+    var box = this.box
+    var _this = this
+  
+    box.addEventListener('click', function (evt) {
+      var target = evt.target
+      if (target.nodeName === 'UL') {
+        return
+      }
+  
+      if (target.parentNode.nodeName === 'LI') {
+        target = target.parentNode
+      }
+  
+      var floor = target.getAttribute('data-floor')
+  
+      if (_this.data.attr.selectedIndex == floor) {
+        // Duplicated clicking, not to trigger select event.
+        return
+      }
+  
+      fireEvent(target, 'select', {index:  floor})
+    })
+  }
+  
+  proto._initSelectEvent = function () {
+    var node = this.node
+    var _this = this
+    node.addEventListener('select', function (evt) {
+      var index
+      if (evt.index !== undefined) {
+        index = evt.index
+      } else if (evt.data && evt.data.index !== undefined) {
+        index = evt.data.index
+      }
+  
+      if (index === undefined) {
+        return
+      }
+  
+      _this.attr.selectedIndex.call(_this, index)
+    })
+  }
+  
+  proto.attr = {
+    highlightIcon: function () {
+      return createHighlightIcon()
+    },
+    data: function () {
+      var attr = this.data.attr
+      // Ensure there is a default selected value.
+      if (attr.selectedIndex === undefined) {
+        attr.selectedIndex = 0
+      }
+  
+      var list = attr.data || []
+      var curItem = attr.selectedIndex
+  
+      var ret = []
+      var itemTmpl = '<li class="th-item" data-floor="{{floor}}">'
+          + '{{hlIcon}}{{floorName}}</li>'
+  
+      list.forEach(function (item, idx) {
+        var html = itemTmpl.replace('{{floor}}', idx)
+        if (curItem == idx) {
+          html = html.replace('{{hlIcon}}', createHighlightIcon())
+        } else {
+          html = html.replace('{{hlIcon}}', '')
+        }
+  
+        html = html.replace('{{floorName}}', item)
+  
+        ret.push(html)
+      }, this)
+  
+      this.box.innerHTML = ret.join('')
+    },
+    selectedIndex: function (val) {
+      var attr = this.data.attr
+  
+      if (val === undefined) {
+        val = 0
+      }
+  
+      // if (val == attr.selectedIndex) {
+      //   return
+      // }
+  
+      attr.selectedIndex = val
+  
+      this.attr.data.call(this)
+  
+      this._folding()
+      this.style.textHighlightColor.call(this, this.textHighlightColor)
+    }
+  }
+  
+  proto.style = Object.create(Atomic.prototype.style)
+  
+  proto.style.opacity = function (val) {
+    if (val === undefined || val < 0 || val > 1) {
+      val = 1
+    }
+  
+    this.node.style.opacity = val
+  }
+  
+  proto.style.textColor = function (val) {
+    if (!isValidColor(val)) {
+      return
+    }
+  
+    this.node.style.color = val
+  }
+  
+  proto.style.textHighlightColor = function (val) {
+    if (!isValidColor(val)) {
+      return
+    }
+    this.textHighlightColor = val
+    var attr = this.data.attr
+  
+    var node = this.node.querySelector('[data-floor="'
+        + attr.selectedIndex + '"]')
+    if (node) {
+      node.style.color = val
+      this._scrollToView(node)
+    }
+  }
+  
+  proto._scrollToView = function (node) {
+    if (!node) {
+      var attr = this.data.attr
+      node = this.node.querySelector('[data-floor="' + attr.selectedIndex + '"]')
+    }
+    if (!node) {
+      return
+    }
+  
+    var defaultVal = this._body.scrollLeft
+    var leftVal = defaultVal  - node.offsetLeft + 300
+  
+    var scrollVal = getScrollVal(this._body.getBoundingClientRect(), node)
+    doScroll(this._body, scrollVal)
+  }
+  
+  // scroll the tabheader.
+  // positive val means to scroll right.
+  // negative val means to scroll left.
+  function doScroll(node, val, finish) {
+    if (!val) {
+      return
+    }
+    if (finish === undefined) {
+      finish = Math.abs(val)
+    }
+  
+    if (finish <= 0) {
+      return
+    }
+  
+    setTimeout(function () {
+      if (val > 0) {
+        node.scrollLeft += 2
+      } else {
+        node.scrollLeft -= 2
+      }
+      finish -= 2
+  
+      doScroll(node, val, finish)
+    })
+  }
+  
+  // get scroll distance.
+  function getScrollVal(rect, node) {
+    var left = node.previousSibling
+    var right = node.nextSibling
+    var scrollVal
+  
+    // process left-side element first.
+    if (left) {
+      var leftRect = left.getBoundingClientRect()
+      // only need to compare the value of left.
+      if (leftRect.left < rect.left) {
+        scrollVal = leftRect.left
+        return scrollVal
+      }
+    }
+  
+    if (right) {
+      var rightRect = right.getBoundingClientRect()
+      // compare the value of right.
+      if (rightRect.right > rect.right) {
+        scrollVal = rightRect.right - rect.right
+        return scrollVal
+      }
+    }
+  
+    // process current node, from left to right.
+    var nodeRect = node.getBoundingClientRect()
+    if (nodeRect.left < rect.left) {
+      scrollVal = nodeRect.left
+    } else if (nodeRect.right > rect.right) {
+      scrollVal = nodeRect.right - rect.right
+    }
+  
+    return scrollVal
+  }
+  
+  // trigger and broadcast events.
+  function fireEvent(element, type, data) {
+    var evt = document.createEvent('Event')
+    evt.data = data
+    utils.extend(evt, data)
+    // need bubble.
+    evt.initEvent(type, true, true)
+  
+    element.dispatchEvent(evt)
+  }
+  
+  function createHighlightIcon(code) {
+    var html = '<i class="hl-icon iconfont">' + '&#xe650' + '</i>'
+    return html
+  }
+  
+  function isValidColor(color) {
+    if (!color) {
+      return false
+    }
+  
+    if (color.charAt(0) !== '#') {
+      return false
+    }
+  
+    if (color.length !== 7) {
+      return false
+    }
+  
+    return true
+  }
+  
+  module.exports = TabHeader
+
+
+/***/ },
+/* 48 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var config = __webpack_require__(5)
+  var messageQueue = []
+  
+  function flushMessage() {
+    if (typeof callJS === 'function' && messageQueue.length > 0) {
+      callJS(config.instanceId, JSON.stringify(messageQueue))
+      messageQueue.length = 0
+    }
+  }
+  
+  function push(msg) {
+    messageQueue.push(msg)
+  }
+  
+  /**
+   * To fix the problem of callapp, the two-way time loop mechanism must
+   * be replaced by directly procedure call except the situation of
+   * page loading.
+   * 2015-11-03
+   */
+  function pushDirectly(msg) {
+    callJS(config.instanceId, [msg])
+  }
+  
+  module.exports = {
+    push: pushDirectly
+  }
+
+
+/***/ },
+/* 49 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(50);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./tabheader.scss", function() {
+        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./tabheader.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 50 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".tab-header {\n  position: relative;\n  width: 10rem;\n  font-size: 14px;\n  color: #333; }\n  .tab-header .header-bar {\n    height: 1.17rem;\n    line-height: 1.17rem;\n    display: none;\n    color: #999;\n    padding-left: 0.4rem; }\n  .tab-header .header-body {\n    margin-right: 1.07rem;\n    overflow-x: auto;\n    overflow-y: hidden; }\n    .tab-header .header-body::-webkit-scrollbar {\n      width: 0;\n      height: 0;\n      overflow: hidden; }\n  .tab-header .fold-toggle {\n    position: absolute;\n    top: 0.59rem;\n    -webkit-transform: translateY(-50%);\n    right: 0.29rem;\n    width: 0.48rem;\n    height: 0.48rem;\n    line-height: 0.48rem;\n    text-align: center;\n    z-index: 99;\n    font-size: 14px; }\n  .tab-header.unfold-header {\n    position: fixed !important;\n    top: 0;\n    left: 0;\n    overflow: hidden; }\n\n.tabheader {\n  list-style: none;\n  white-space: nowrap;\n  height: 1.17rem;\n  line-height: 1.17rem; }\n  .tabheader .th-item {\n    padding-left: 0.72rem;\n    position: relative;\n    display: inline-block; }\n  .tabheader .hl-icon {\n    width: 0.4rem;\n    height: 0.4rem;\n    line-height: 0.4rem;\n    text-align: center;\n    position: absolute;\n    top: 50%;\n    -webkit-transform: translateY(-50%);\n    left: 0.24rem;\n    font-size: 14px; }\n\n.unfold-header .header-bar {\n  display: block; }\n\n.unfold-header .fold-toggle {\n  -webkit-transform: translateY(-50%) rotate(180deg); }\n\n.unfold-header .header-body {\n  margin-right: 0;\n  padding: 0.24rem; }\n\n.unfold-header .tabheader {\n  display: block;\n  height: auto; }\n\n.unfold-header .th-item {\n  box-sizing: border-box;\n  float: left;\n  width: 33.3333%;\n  height: 1.01rem;\n  line-height: 1.01rem; }\n\n.unfold-header .hl-icon {\n  margin-right: 0;\n  position: absolute; }\n\n.unfold-header.tabheader-mask {\n  display: block;\n  width: 100%;\n  height: 100%;\n  background-color: rgba(0, 0, 0, 0.6); }\n\n.tabheader-mask {\n  display: none;\n  position: fixed;\n  left: 0;\n  top: 0; }\n\n@font-face {\n  font-family: \"iconfont\";\n  src: url(\"data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAPAIAAAwBwRkZUTXBD98UAAAD8AAAAHE9TLzJXL1zIAAABGAAAAGBjbWFws6IHbgAAAXgAAAFaY3Z0IAyV/swAAApQAAAAJGZwZ20w956VAAAKdAAACZZnYXNwAAAAEAAACkgAAAAIZ2x5ZuxoPFIAAALUAAAEWGhlYWQHA5h3AAAHLAAAADZoaGVhBzIDcgAAB2QAAAAkaG10eAs2AW0AAAeIAAAAGGxvY2EDcAQeAAAHoAAAABBtYXhwASkKKwAAB7AAAAAgbmFtZQl/3hgAAAfQAAACLnBvc3Tm7f0bAAAKAAAAAEhwcmVwpbm+ZgAAFAwAAACVAAAAAQAAAADMPaLPAAAAANIDKnoAAAAA0gMqewAEA/oB9AAFAAACmQLMAAAAjwKZAswAAAHrADMBCQAAAgAGAwAAAAAAAAAAAAEQAAAAAAAAAAAAAABQZkVkAMAAeObeAyz/LABcAxgAlAAAAAEAAAAAAxgAAAAAACAAAQAAAAMAAAADAAAAHAABAAAAAABUAAMAAQAAABwABAA4AAAACgAIAAIAAgB45lDmYebe//8AAAB45lDmYebe////ixm0GaQZKAABAAAAAAAAAAAAAAAAAQYAAAEAAAAAAAAAAQIAAAACAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACACIAAAEyAqoAAwAHAClAJgAAAAMCAANXAAIBAQJLAAICAU8EAQECAUMAAAcGBQQAAwADEQUPKzMRIREnMxEjIgEQ7szMAqr9ViICZgAAAAUALP/hA7wDGAAWADAAOgBSAF4Bd0uwE1BYQEoCAQANDg0ADmYAAw4BDgNeAAEICAFcEAEJCAoGCV4RAQwGBAYMXgALBAtpDwEIAAYMCAZYAAoHBQIECwoEWRIBDg4NUQANDQoOQhtLsBdQWEBLAgEADQ4NAA5mAAMOAQ4DXgABCAgBXBABCQgKCAkKZhEBDAYEBgxeAAsEC2kPAQgABgwIBlgACgcFAgQLCgRZEgEODg1RAA0NCg5CG0uwGFBYQEwCAQANDg0ADmYAAw4BDgNeAAEICAFcEAEJCAoICQpmEQEMBgQGDARmAAsEC2kPAQgABgwIBlgACgcFAgQLCgRZEgEODg1RAA0NCg5CG0BOAgEADQ4NAA5mAAMOAQ4DAWYAAQgOAQhkEAEJCAoICQpmEQEMBgQGDARmAAsEC2kPAQgABgwIBlgACgcFAgQLCgRZEgEODg1RAA0NCg5CWVlZQChTUzs7MjEXF1NeU15bWDtSO1JLQzc1MToyOhcwFzBRETEYESgVQBMWKwEGKwEiDgIdASE1NCY1NC4CKwEVIQUVFBYUDgIjBiYrASchBysBIiciLgI9ARciBhQWMzI2NCYXBgcOAx4BOwYyNicuAScmJwE1ND4COwEyFh0BARkbGlMSJRwSA5ABChgnHoX+SgKiARUfIw4OHw4gLf5JLB0iFBkZIBMIdwwSEgwNEhKMCAYFCwQCBA8OJUNRUEAkFxYJBQkFBQb+pAUPGhW8HykCHwEMGScaTCkQHAQNIBsSYYg0Fzo6JRcJAQGAgAETGyAOpz8RGhERGhF8GhYTJA4QDQgYGg0jERMUAXfkCxgTDB0m4wAAAgCg/2wDYALsABIAGgAhQB4AAAADAgADWQACAQECTQACAgFRAAECAUUTFjkQBBIrACAGFRQeAxcWOwEyPwESNTQAIiY0NjIWFAKS/tzORFVvMRAJDgEOCW3b/uKEXl6EXgLszpI1lXyJNhEKC30BDIyS/s5ehF5ehAAAAAEAggBJA4QB6AAdABtAGBIRAgEAAUAFAQA+AAABAGgAAQFfEx8CECsBJgcGBwkBLgEGBwYUFwEwMxcVFjI3AT4DLgIDehEWAwP+uP60BhEQBgoKAWEBAQoaCQFeAwQCAQECBAHhEg0DAv61AUkHBAUGCRsJ/qIBAQkJAWICBwYHCAYGAAEAfwCLA4ECJwAhAB1AGhYPAgEAAUAFAQA+AAABAGgCAQEBXyQuEwMRKyUBMCcjNSYHBgcBDgEUFhceAjMyNwkBFjMyNjc+Ai4BA3f+nwEBEhUEAv6iBQUFBQMHCAQOCQFIAUwKDQYMBQMFAQEFwwFeAQERDQID/p8FDAwMBAMEAgkBS/62CQUFAwoJCgkAAAEAAAABAAALIynoXw889QALBAAAAAAA0gMqewAAAADSAyp7ACL/bAO8AxgAAAAIAAIAAAAAAAAAAQAAAxj/bABcBAAAAAAAA7wAAQAAAAAAAAAAAAAAAAAAAAUBdgAiAAAAAAFVAAAD6QAsBAAAoACCAH8AAAAoACgAKAFkAaIB5AIsAAEAAAAHAF8ABQAAAAAAAgAmADQAbAAAAIoJlgAAAAAAAAAMAJYAAQAAAAAAAQAIAAAAAQAAAAAAAgAGAAgAAQAAAAAAAwAkAA4AAQAAAAAABAAIADIAAQAAAAAABQBGADoAAQAAAAAABgAIAIAAAwABBAkAAQAQAIgAAwABBAkAAgAMAJgAAwABBAkAAwBIAKQAAwABBAkABAAQAOwAAwABBAkABQCMAPwAAwABBAkABgAQAYhpY29uZm9udE1lZGl1bUZvbnRGb3JnZSAyLjAgOiBpY29uZm9udCA6IDI2LTgtMjAxNWljb25mb250VmVyc2lvbiAxLjAgOyB0dGZhdXRvaGludCAodjAuOTQpIC1sIDggLXIgNTAgLUcgMjAwIC14IDE0IC13ICJHIiAtZiAtc2ljb25mb250AGkAYwBvAG4AZgBvAG4AdABNAGUAZABpAHUAbQBGAG8AbgB0AEYAbwByAGcAZQAgADIALgAwACAAOgAgAGkAYwBvAG4AZgBvAG4AdAAgADoAIAAyADYALQA4AC0AMgAwADEANQBpAGMAbwBuAGYAbwBuAHQAVgBlAHIAcwBpAG8AbgAgADEALgAwACAAOwAgAHQAdABmAGEAdQB0AG8AaABpAG4AdAAgACgAdgAwAC4AOQA0ACkAIAAtAGwAIAA4ACAALQByACAANQAwACAALQBHACAAMgAwADAAIAAtAHgAIAAxADQAIAAtAHcAIAAiAEcAIgAgAC0AZgAgAC0AcwBpAGMAbwBuAGYAbwBuAHQAAAACAAAAAAAA/4MAMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAABAAIAWwECAQMBBAd1bmlFNjUwB3VuaUU2NjEHdW5pRTZERQABAAH//wAPAAAAAAAAAAAAAAAAAAAAAAAyADIDGP/hAxj/bAMY/+EDGP9ssAAssCBgZi2wASwgZCCwwFCwBCZasARFW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCwCkVhZLAoUFghsApFILAwUFghsDBZGyCwwFBYIGYgiophILAKUFhgGyCwIFBYIbAKYBsgsDZQWCGwNmAbYFlZWRuwACtZWSOwAFBYZVlZLbACLCBFILAEJWFkILAFQ1BYsAUjQrAGI0IbISFZsAFgLbADLCMhIyEgZLEFYkIgsAYjQrIKAAIqISCwBkMgiiCKsAArsTAFJYpRWGBQG2FSWVgjWSEgsEBTWLAAKxshsEBZI7AAUFhlWS2wBCywCCNCsAcjQrAAI0KwAEOwB0NRWLAIQyuyAAEAQ2BCsBZlHFktsAUssABDIEUgsAJFY7ABRWJgRC2wBiywAEMgRSCwACsjsQQEJWAgRYojYSBkILAgUFghsAAbsDBQWLAgG7BAWVkjsABQWGVZsAMlI2FERC2wByyxBQVFsAFhRC2wCCywAWAgILAKQ0qwAFBYILAKI0JZsAtDSrAAUlggsAsjQlktsAksILgEAGIguAQAY4ojYbAMQ2AgimAgsAwjQiMtsAosS1RYsQcBRFkksA1lI3gtsAssS1FYS1NYsQcBRFkbIVkksBNlI3gtsAwssQANQ1VYsQ0NQ7ABYUKwCStZsABDsAIlQrIAAQBDYEKxCgIlQrELAiVCsAEWIyCwAyVQWLAAQ7AEJUKKiiCKI2GwCCohI7ABYSCKI2GwCCohG7AAQ7ACJUKwAiVhsAgqIVmwCkNHsAtDR2CwgGIgsAJFY7ABRWJgsQAAEyNEsAFDsAA+sgEBAUNgQi2wDSyxAAVFVFgAsA0jQiBgsAFhtQ4OAQAMAEJCimCxDAQrsGsrGyJZLbAOLLEADSstsA8ssQENKy2wECyxAg0rLbARLLEDDSstsBIssQQNKy2wEyyxBQ0rLbAULLEGDSstsBUssQcNKy2wFiyxCA0rLbAXLLEJDSstsBgssAcrsQAFRVRYALANI0IgYLABYbUODgEADABCQopgsQwEK7BrKxsiWS2wGSyxABgrLbAaLLEBGCstsBsssQIYKy2wHCyxAxgrLbAdLLEEGCstsB4ssQUYKy2wHyyxBhgrLbAgLLEHGCstsCEssQgYKy2wIiyxCRgrLbAjLCBgsA5gIEMjsAFgQ7ACJbACJVFYIyA8sAFgI7ASZRwbISFZLbAkLLAjK7AjKi2wJSwgIEcgILACRWOwAUViYCNhOCMgilVYIEcgILACRWOwAUViYCNhOBshWS2wJiyxAAVFVFgAsAEWsCUqsAEVMBsiWS2wJyywByuxAAVFVFgAsAEWsCUqsAEVMBsiWS2wKCwgNbABYC2wKSwAsANFY7ABRWKwACuwAkVjsAFFYrAAK7AAFrQAAAAAAEQ+IzixKAEVKi2wKiwgPCBHILACRWOwAUViYLAAQ2E4LbArLC4XPC2wLCwgPCBHILACRWOwAUViYLAAQ2GwAUNjOC2wLSyxAgAWJSAuIEewACNCsAIlSYqKRyNHI2EgWGIbIVmwASNCsiwBARUUKi2wLiywABawBCWwBCVHI0cjYbAGRStlii4jICA8ijgtsC8ssAAWsAQlsAQlIC5HI0cjYSCwBCNCsAZFKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgsAlDIIojRyNHI2EjRmCwBEOwgGJgILAAKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwgGJhIyAgsAQmI0ZhOBsjsAlDRrACJbAJQ0cjRyNhYCCwBEOwgGJgIyCwACsjsARDYLAAK7AFJWGwBSWwgGKwBCZhILAEJWBkI7ADJWBkUFghGyMhWSMgILAEJiNGYThZLbAwLLAAFiAgILAFJiAuRyNHI2EjPDgtsDEssAAWILAJI0IgICBGI0ewACsjYTgtsDIssAAWsAMlsAIlRyNHI2GwAFRYLiA8IyEbsAIlsAIlRyNHI2EgsAUlsAQlRyNHI2GwBiWwBSVJsAIlYbABRWMjIFhiGyFZY7ABRWJgIy4jICA8ijgjIVktsDMssAAWILAJQyAuRyNHI2EgYLAgYGawgGIjICA8ijgtsDQsIyAuRrACJUZSWCA8WS6xJAEUKy2wNSwjIC5GsAIlRlBYIDxZLrEkARQrLbA2LCMgLkawAiVGUlggPFkjIC5GsAIlRlBYIDxZLrEkARQrLbA3LLAuKyMgLkawAiVGUlggPFkusSQBFCstsDgssC8riiAgPLAEI0KKOCMgLkawAiVGUlggPFkusSQBFCuwBEMusCQrLbA5LLAAFrAEJbAEJiAuRyNHI2GwBkUrIyA8IC4jOLEkARQrLbA6LLEJBCVCsAAWsAQlsAQlIC5HI0cjYSCwBCNCsAZFKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgR7AEQ7CAYmAgsAArIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbCAYmGwAiVGYTgjIDwjOBshICBGI0ewACsjYTghWbEkARQrLbA7LLAuKy6xJAEUKy2wPCywLyshIyAgPLAEI0IjOLEkARQrsARDLrAkKy2wPSywABUgR7AAI0KyAAEBFRQTLrAqKi2wPiywABUgR7AAI0KyAAEBFRQTLrAqKi2wPyyxAAEUE7ArKi2wQCywLSotsEEssAAWRSMgLiBGiiNhOLEkARQrLbBCLLAJI0KwQSstsEMssgAAOistsEQssgABOistsEUssgEAOistsEYssgEBOistsEcssgAAOystsEgssgABOystsEkssgEAOystsEossgEBOystsEsssgAANystsEwssgABNystsE0ssgEANystsE4ssgEBNystsE8ssgAAOSstsFAssgABOSstsFEssgEAOSstsFIssgEBOSstsFMssgAAPCstsFQssgABPCstsFUssgEAPCstsFYssgEBPCstsFcssgAAOCstsFgssgABOCstsFkssgEAOCstsFossgEBOCstsFsssDArLrEkARQrLbBcLLAwK7A0Ky2wXSywMCuwNSstsF4ssAAWsDArsDYrLbBfLLAxKy6xJAEUKy2wYCywMSuwNCstsGEssDErsDUrLbBiLLAxK7A2Ky2wYyywMisusSQBFCstsGQssDIrsDQrLbBlLLAyK7A1Ky2wZiywMiuwNistsGcssDMrLrEkARQrLbBoLLAzK7A0Ky2waSywMyuwNSstsGossDMrsDYrLbBrLCuwCGWwAyRQeLABFTAtAABLuADIUlixAQGOWbkIAAgAYyCwASNEILADI3CwDkUgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbABRWMjYrACI0SzCgkFBCuzCgsFBCuzDg8FBCtZsgQoCUVSRLMKDQYEK7EGAUSxJAGIUViwQIhYsQYDRLEmAYhRWLgEAIhYsQYBRFlZWVm4Af+FsASNsQUARAAAAA==\") format(\"truetype\"); }\n\n.iconfont {\n  font-family: iconfont !important;\n  font-size: 16px;\n  font-style: normal;\n  -webkit-font-smoothing: antialiased;\n  -webkit-text-stroke-width: 0.2px;\n  -moz-osx-font-smoothing: grayscale; }\n\n[data-dpr=\"2\"] .tab-header {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tab-header {\n  font-size: 42px; }\n\n[data-dpr=\"2\"] .tabheader .hl-icon {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tabheader .hl-icon {\n  font-size: 42px; }\n\n[data-dpr=\"2\"] .tab-header .fold-toggle {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tab-header .fold-toggle {\n  font-size: 42px; }\n", "", {"version":3,"sources":["/./src/src/styles/tabheader.scss","/./src/styles/tabheader.scss"],"names":[],"mappings":"AAGA;EACE,mBAAmB;EACnB,aAAa;EACb,gBAAgB;EAChB,YAAY,EA0Cb;EA9CD;IAOI,gBAAgB;IAChB,qBAAqB;IACrB,cAAc;IACd,YAAY;IACZ,qBAAqB,EACtB;EAZH;IAeI,sBAAsB;IACtB,iBAAiB;IACjB,mBAAmB,EAOpB;IAxBH;MAoBM,SAAS;MACT,UAAU;MACV,iBAAiB,EAClB;EAvBL;IA2BI,mBAAmB;IACnB,aAAa;IACb,oCAA6B;IAC7B,eAAe;IACf,eAAe;IACf,gBAAgB;IAChB,qBAAqB;IACrB,mBAAmB;IACnB,YAAY;IACZ,gBAAgB,EACjB;EArCH;IAwCI,2BAA2B;IAC3B,OAAO;IACP,QAAQ;IACR,iBAAiB,EAClB;;AAIH;EACE,iBAAiB;EACjB,oBAAoB;EACpB,gBAAgB;EAChB,qBAAqB,EAoBtB;EAxBD;IAOI,sBAAsB;IACtB,mBAAmB;IACnB,sBAAsB,EACvB;EAVH;IAaI,cAAc;IACd,eAAe;IACf,oBAAoB;IACpB,mBAAmB;IACnB,mBAAmB;IACnB,SAAS;IACT,oCAA6B;IAC7B,cAAc;IACd,gBAAgB,EACjB;;AAIH;EAGI,eAAe,EAChB;;AAJH;EAOI,mDAA0C,EAC3C;;AARH;EAWI,gBAAgB;EAChB,iBAAiB,EAClB;;AAbH;EAgBI,eAAe;EACf,aAAa,EACd;;AAlBH;EAqBI,uBAAuB;EACvB,YAAY;EACZ,gBAAgB;EAChB,gBAAgB;EAChB,qBAAqB,EACtB;;AA1BH;EA6BI,gBAAgB;EAChB,mBAAmB,EACpB;;AA/BH;EAkCI,eAAe;EACf,YAAY;EACZ,aAAa;EACb,qCAAsB,EACvB;;AAGH;EACE,cAAc;EACd,gBAAgB;EAChB,QAAQ;EACR,OAAO,EACR;;AAED;EACE,wBAAwB;EACxB,y9NAA48N,EAAA;;AAG98N;EACE,iCAAiC;EACjC,gBAAgB;EAChB,mBAAmB;EACnB,oCAAoC;EACpC,iCAAiC;EACjC,mCAAmC,EACpC;;AChCD;EDmCE,gBAAgB,EACjB;;ACjCD;EDoCE,gBAAgB,EACjB;;AClCD;EDqCE,gBAAgB,EACjB;;ACnCD;EDsCE,gBAAgB,EACjB;;ACpCD;EDuCE,gBAAgB,EACjB;;ACrCD;EDwCE,gBAAgB,EACjB","file":"tabheader.scss","sourcesContent":["// Heads up! Rem is not a good way for\n// weex HTML5 renderer.\n\n.tab-header {\n  position: relative;\n  width: 10rem;\n  font-size: 14px;\n  color: #333;\n\n  .header-bar {\n    height: 1.17rem;\n    line-height: 1.17rem;\n    display: none;\n    color: #999;\n    padding-left: 0.4rem;\n  }\n  \n  .header-body {\n    margin-right: 1.07rem;\n    overflow-x: auto;\n    overflow-y: hidden;\n\n    &::-webkit-scrollbar {\n      width: 0;\n      height: 0;\n      overflow: hidden;\n    }\n  }\n\n  .fold-toggle {\n    position: absolute;\n    top: 0.59rem;\n    -webkit-transform: translateY(-50%);\n    right: 0.29rem;\n    width: 0.48rem;\n    height: 0.48rem;\n    line-height: 0.48rem;\n    text-align: center;\n    z-index: 99;\n    font-size: 14px;\n  }\n\n  &.unfold-header {\n    position: fixed !important;\n    top: 0;\n    left: 0;\n    overflow: hidden;\n  }\n\n}\n\n.tabheader {\n  list-style: none;\n  white-space: nowrap;\n  height: 1.17rem;\n  line-height: 1.17rem;\n\n  .th-item {\n    padding-left: 0.72rem;\n    position: relative;\n    display: inline-block;\n  }\n\n  .hl-icon {\n    width: 0.4rem;\n    height: 0.4rem;\n    line-height: 0.4rem;\n    text-align: center;\n    position: absolute;\n    top: 50%;\n    -webkit-transform: translateY(-50%);\n    left: 0.24rem;\n    font-size: 14px;\n  }\n\n}\n\n.unfold-header {\n\n  .header-bar {\n    display: block;\n  }\n\n  .fold-toggle {\n    -webkit-transform: translateY(-50%) rotate(180deg);\n  }\n\n  .header-body {\n    margin-right: 0;\n    padding: 0.24rem;\n  }\n\n  .tabheader {\n    display: block;\n    height: auto;\n  }\n\n  .th-item {\n    box-sizing: border-box;\n    float: left;\n    width: 33.3333%;\n    height: 1.01rem;\n    line-height: 1.01rem;\n  }\n\n  .hl-icon {\n    margin-right: 0;\n    position: absolute;\n  }\n\n  &.tabheader-mask {\n    display: block;\n    width: 100%;\n    height: 100%;\n    background-color: rgba(0, 0, 0, 0.6);\n  }\n}\n\n.tabheader-mask {\n  display: none;\n  position: fixed;\n  left: 0;\n  top: 0;\n}\n\n@font-face {\n  font-family: \"iconfont\";\n  src: url(\"data:application/x-font-ttf;charset=utf-8;base64,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R7AEQ7CAYmAgsAArIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbCAYmGwAiVGYTgjIDwjOBshICBGI0ewACsjYTghWbEkARQrLbA7LLAuKy6xJAEUKy2wPCywLyshIyAgPLAEI0IjOLEkARQrsARDLrAkKy2wPSywABUgR7AAI0KyAAEBFRQTLrAqKi2wPiywABUgR7AAI0KyAAEBFRQTLrAqKi2wPyyxAAEUE7ArKi2wQCywLSotsEEssAAWRSMgLiBGiiNhOLEkARQrLbBCLLAJI0KwQSstsEMssgAAOistsEQssgABOistsEUssgEAOistsEYssgEBOistsEcssgAAOystsEgssgABOystsEkssgEAOystsEossgEBOystsEsssgAANystsEwssgABNystsE0ssgEANystsE4ssgEBNystsE8ssgAAOSstsFAssgABOSstsFEssgEAOSstsFIssgEBOSstsFMssgAAPCstsFQssgABPCstsFUssgEAPCstsFYssgEBPCstsFcssgAAOCstsFgssgABOCstsFkssgEAOCstsFossgEBOCstsFsssDArLrEkARQrLbBcLLAwK7A0Ky2wXSywMCuwNSstsF4ssAAWsDArsDYrLbBfLLAxKy6xJAEUKy2wYCywMSuwNCstsGEssDErsDUrLbBiLLAxK7A2Ky2wYyywMisusSQBFCstsGQssDIrsDQrLbBlLLAyK7A1Ky2wZiywMiuwNistsGcssDMrLrEkARQrLbBoLLAzK7A0Ky2waSywMyuwNSstsGossDMrsDYrLbBrLCuwCGWwAyRQeLABFTAtAABLuADIUlixAQGOWbkIAAgAYyCwASNEILADI3CwDkUgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbABRWMjYrACI0SzCgkFBCuzCgsFBCuzDg8FBCtZsgQoCUVSRLMKDQYEK7EGAUSxJAGIUViwQIhYsQYDRLEmAYhRWLgEAIhYsQYBRFlZWVm4Af+FsASNsQUARAAAAA==\") format(\"truetype\");\n}\n\n.iconfont {\n  font-family: iconfont !important;\n  font-size: 16px;\n  font-style: normal;\n  -webkit-font-smoothing: antialiased;\n  -webkit-text-stroke-width: 0.2px;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n[data-dpr=\"2\"] .tab-header {\n  font-size: 28px;\n}\n\n[data-dpr=\"3\"] .tab-header {\n  font-size: 42px;\n}\n\n[data-dpr=\"2\"] .tabheader .hl-icon {\n  font-size: 28px;\n}\n\n[data-dpr=\"3\"] .tabheader .hl-icon {\n  font-size: 42px;\n}\n\n[data-dpr=\"2\"] .tab-header .fold-toggle {\n  font-size: 28px;\n}\n\n[data-dpr=\"3\"] .tab-header .fold-toggle {\n  font-size: 42px;\n}",".tab-header {\n  position: relative;\n  width: 10rem;\n  font-size: 14px;\n  color: #333; }\n  .tab-header .header-bar {\n    height: 1.17rem;\n    line-height: 1.17rem;\n    display: none;\n    color: #999;\n    padding-left: 0.4rem; }\n  .tab-header .header-body {\n    margin-right: 1.07rem;\n    overflow-x: auto;\n    overflow-y: hidden; }\n    .tab-header .header-body::-webkit-scrollbar {\n      width: 0;\n      height: 0;\n      overflow: hidden; }\n  .tab-header .fold-toggle {\n    position: absolute;\n    top: 0.59rem;\n    -webkit-transform: translateY(-50%);\n    right: 0.29rem;\n    width: 0.48rem;\n    height: 0.48rem;\n    line-height: 0.48rem;\n    text-align: center;\n    z-index: 99;\n    font-size: 14px; }\n  .tab-header.unfold-header {\n    position: fixed !important;\n    top: 0;\n    left: 0;\n    overflow: hidden; }\n\n.tabheader {\n  list-style: none;\n  white-space: nowrap;\n  height: 1.17rem;\n  line-height: 1.17rem; }\n  .tabheader .th-item {\n    padding-left: 0.72rem;\n    position: relative;\n    display: inline-block; }\n  .tabheader .hl-icon {\n    width: 0.4rem;\n    height: 0.4rem;\n    line-height: 0.4rem;\n    text-align: center;\n    position: absolute;\n    top: 50%;\n    -webkit-transform: translateY(-50%);\n    left: 0.24rem;\n    font-size: 14px; }\n\n.unfold-header .header-bar {\n  display: block; }\n\n.unfold-header .fold-toggle {\n  -webkit-transform: translateY(-50%) rotate(180deg); }\n\n.unfold-header .header-body {\n  margin-right: 0;\n  padding: 0.24rem; }\n\n.unfold-header .tabheader {\n  display: block;\n  height: auto; }\n\n.unfold-header .th-item {\n  box-sizing: border-box;\n  float: left;\n  width: 33.3333%;\n  height: 1.01rem;\n  line-height: 1.01rem; }\n\n.unfold-header .hl-icon {\n  margin-right: 0;\n  position: absolute; }\n\n.unfold-header.tabheader-mask {\n  display: block;\n  width: 100%;\n  height: 100%;\n  background-color: rgba(0, 0, 0, 0.6); }\n\n.tabheader-mask {\n  display: none;\n  position: fixed;\n  left: 0;\n  top: 0; }\n\n@font-face {\n  font-family: \"iconfont\";\n  src: url(\"data:application/x-font-ttf;charset=utf-8;base64,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R7AEQ7CAYmAgsAArIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbCAYmGwAiVGYTgjIDwjOBshICBGI0ewACsjYTghWbEkARQrLbA7LLAuKy6xJAEUKy2wPCywLyshIyAgPLAEI0IjOLEkARQrsARDLrAkKy2wPSywABUgR7AAI0KyAAEBFRQTLrAqKi2wPiywABUgR7AAI0KyAAEBFRQTLrAqKi2wPyyxAAEUE7ArKi2wQCywLSotsEEssAAWRSMgLiBGiiNhOLEkARQrLbBCLLAJI0KwQSstsEMssgAAOistsEQssgABOistsEUssgEAOistsEYssgEBOistsEcssgAAOystsEgssgABOystsEkssgEAOystsEossgEBOystsEsssgAANystsEwssgABNystsE0ssgEANystsE4ssgEBNystsE8ssgAAOSstsFAssgABOSstsFEssgEAOSstsFIssgEBOSstsFMssgAAPCstsFQssgABPCstsFUssgEAPCstsFYssgEBPCstsFcssgAAOCstsFgssgABOCstsFkssgEAOCstsFossgEBOCstsFsssDArLrEkARQrLbBcLLAwK7A0Ky2wXSywMCuwNSstsF4ssAAWsDArsDYrLbBfLLAxKy6xJAEUKy2wYCywMSuwNCstsGEssDErsDUrLbBiLLAxK7A2Ky2wYyywMisusSQBFCstsGQssDIrsDQrLbBlLLAyK7A1Ky2wZiywMiuwNistsGcssDMrLrEkARQrLbBoLLAzK7A0Ky2waSywMyuwNSstsGossDMrsDYrLbBrLCuwCGWwAyRQeLABFTAtAABLuADIUlixAQGOWbkIAAgAYyCwASNEILADI3CwDkUgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbABRWMjYrACI0SzCgkFBCuzCgsFBCuzDg8FBCtZsgQoCUVSRLMKDQYEK7EGAUSxJAGIUViwQIhYsQYDRLEmAYhRWLgEAIhYsQYBRFlZWVm4Af+FsASNsQUARAAAAA==\") format(\"truetype\"); }\n\n.iconfont {\n  font-family: iconfont !important;\n  font-size: 16px;\n  font-style: normal;\n  -webkit-font-smoothing: antialiased;\n  -webkit-text-stroke-width: 0.2px;\n  -moz-osx-font-smoothing: grayscale; }\n\n[data-dpr=\"2\"] .tab-header {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tab-header {\n  font-size: 42px; }\n\n[data-dpr=\"2\"] .tabheader .hl-icon {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tabheader .hl-icon {\n  font-size: 42px; }\n\n[data-dpr=\"2\"] .tab-header .fold-toggle {\n  font-size: 28px; }\n\n[data-dpr=\"3\"] .tab-header .fold-toggle {\n  font-size: 42px; }\n"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 51 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  __webpack_require__(52)
+  __webpack_require__(32)
+  
+  // lib.scroll events:
+  //  - scrollstart
+  //  - scrolling
+  //  - pulldownend
+  //  - pullupend
+  //  - pullleftend
+  //  - pullrightend
+  //  - pulldown
+  //  - pullup
+  //  - pullleft
+  //  - pullright
+  //  - contentrefresh
+  
+  var Component = __webpack_require__(16)
+  var utils = __webpack_require__(7)
+  
+  // attrs:
+  //  - scroll-direciton: none|vertical|horizontal (default is vertical)
+  //  - show-scrollbar: true|false (default is true)
+  function Scroller (data, nodeType) {
+    var attrs = data.attr || {}
+    this.items = []
+    this.totalWidth = 0
+    this.scrollDirection = attrs.scrollDirection === 'horizontal'
+                            ? 'horizontal'
+                            : 'vertical'
+    this.showScrollbar = attrs.showScrollbar || true
+    Component.call(this, data, nodeType)
+  }
+  
+  Scroller.prototype = Object.create(Component.prototype)
+  
+  Scroller.prototype.create = function (nodeType) {
+    var Scroll = lib.scroll
+    var node = Component.prototype.create.call(this, nodeType)
+    node.classList.add('weex-container', 'scroll-wrap')
+    this.scrollElement = document.createElement('div')
+    this.scrollElement.classList.add(
+      'weex-container',
+      'scroll-element',
+      this.scrollDirection
+    )
+    node.appendChild(this.scrollElement)
+    this.scroller = new Scroll({
+      scrollElement: this.scrollElement,
+      direction: this.scrollDirection === 'vertical' ? 'y' : 'x'
+    })
+    this.scroller.init()
+    return node
+  }
+  
+  Scroller.prototype.bindEvents = function (evts) {
+    Component.prototype.bindEvents.call(this, evts)
+    // to enable lazyload for Images
+    this.scroller.addEventListener('scrolling', function (e) {
+      var so = e.scrollObj
+      this.dispatchEvent('scroll', {
+        originalType: 'scrolling',
+        scrollTop: so.getScrollTop(),
+        scrollLeft: so.getScrollLeft()
+      }, {
+        bubbles: true
+      })
+    }.bind(this))
+  }
+  
+  Scroller.prototype.appendChild = function (data) {
+    var children = this.data.children
+    var componentManager = this.getComponentManager()
+    var child = componentManager.createElement(data)
+    this.scrollElement.appendChild(child.node)
+  
+    var childWidth = child.node.getBoundingClientRect().width
+    this.totalWidth += childWidth
+    // if direction is horizontal then the width of scrollElement
+    // should be set manually due to flexbox's rule (child elements
+    // will not exceed box's width but to shrink to adapt).
+    if (this.scrollDirection === 'horizontal') {
+      this.scrollElement.style.width = this.totalWidth + 'px'
+    }
+  
+    // update this.data.children
+    if (!children || !children.length) {
+      this.data.children = [data]
+    } else {
+      children.push(data)
+    }
+  
+    this.items.push(child)
+    return child
+  }
+  
+  Scroller.prototype.insertBefore = function (child, before) {
+    var children = this.data.children
+    var i = 0
+    var isAppend = false
+  
+    // update this.data.children
+    if (!children || !children.length || !before) {
+      isAppend = true
+    } else {
+      for (var l = children.length; i < l; i++) {
+        if (children[i].ref === child.data.ref) {
+          break
+        }
+      }
+      if (i === l) {
+        isAppend = true
+      }
+    }
+  
+    if (isAppend) {
+      this.scrollElement.appendChild(child.node)
+      children.push(child.data)
+      this.items.push(child)
+    } else {
+      this.scrollElement.insertBefore(child.node, before.node)
+      children.splice(i, 0, child.data)
+      this.items.splice(i, 0, child)
+    }
+  }
+  
+  Scroller.prototype.removeChild = function () {
+    var children = this.data.children
+    // remove from this.data.children
+    var i = 0
+    var componentManager = this.getComponentManager()
+    if (children && children.length) {
+      for (var l = children.length; i < l; i++) {
+        if (children[i].ref === child.data.ref) {
+          break
+        }
+      }
+      if (i < l) {
+        children.splice(i, 1)
+        this.items.splice(i, 1)
+      }
+    }
+    // remove from componentMap recursively
+    componentManager.removeElementByRef(child.data.ref)
+    this.scrollElement.removeChild(child.node)
+  }
+  
+  module.exports = Scroller
+
+
+/***/ },
+/* 52 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(53);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./scroller.scss", function() {
+        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./scroller.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 53 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".scroll-wrap {\n  display: block;\n  overflow: hidden; }\n\n.scroll-element.horizontal {\n  -webkit-box-orient: horizontal;\n  -webkit-flex-direction: row;\n  flex-direction: row; }\n\n.scroll-element.vertical {\n  -webkit-box-orient: vertical;\n  -webkit-flex-direction: column;\n  flex-direction: column; }\n", "", {"version":3,"sources":["/./src/src/styles/scroller.scss"],"names":[],"mappings":"AAAA;EACC,eAAe;EACf,iBAAiB,EACjB;;AAED;EAEI,+BAA+B;EAC/B,4BAA4B;EAC5B,oBAAoB,EACrB;;AALH;EAOI,6BAA6B;EAC7B,+BAA+B;EAC/B,uBAAuB,EACxB","file":"scroller.scss","sourcesContent":[".scroll-wrap {\n\tdisplay: block;\n\toverflow: hidden;\n}\n\n.scroll-element {\n  &.horizontal {\n    -webkit-box-orient: horizontal;\n    -webkit-flex-direction: row;\n    flex-direction: row;\n  }\n  &.vertical {\n    -webkit-box-orient: vertical;\n    -webkit-flex-direction: column;\n    flex-direction: column;\n  }\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 54 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(27)
+  var utils = __webpack_require__(7)
+  
+  // attrs:
+  //   - type: text|password|tel|email|url
+  //   - value
+  //   - placeholder
+  //   - disabled
+  //   - autofocus
+  function Input (data) {
+    var attrs = data.attr || {}
+    this.type = attrs.type || 'text'
+    this.value = attrs.value
+    this.placeholder = attrs.placeholder
+    this.autofocus = attrs.autofocus && (attrs.autofocus !== 'false')
+                      ? true
+                      : false
+    Atomic.call(this, data)
+  }
+  
+  Input.prototype = Object.create(Atomic.prototype)
+  
+  Input.prototype.create = function () {
+    var node = document.createElement('input')
+    var uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
+    this.className = 'weex-ipt-' + uuid
+    this.styleId = 'weex-style-' + uuid
+    node.classList.add(this.className)
+    node.setAttribute('type', this.type)
+    node.type = this.type
+    // For the consistency of input component's width.
+    // The date and time type of input will have a bigger width
+    // when the 'box-sizing' is not set to 'border-box'
+    node.classList.add('weex-element')
+    this.value && (node.value = this.value)
+    this.placeholder && (node.placeholder = this.placeholder)
+    return node
+  }
+  
+  Input.prototype.updateStyle = function (style) {
+    Atomic.prototype.updateStyle.call(this, style)
+    if (style && style.placeholderColor) {
+      this.placeholderColor = style.placeholderColor
+      this.setPlaceholderColor()
+    }
+  }
+  
+  Input.prototype.attr = {
+    disabled: function (val) {
+      this.node.disabled = val && val !== 'false'
+                      ? true
+                      : false
+    }
+  }
+  
+  Input.prototype.setPlaceholderColor = function () {
+    if (!this.placeholderColor) {
+      return
+    }
+    var vendors = [
+      '::-webkit-input-placeholder',
+      ':-moz-placeholder',
+      '::-moz-placeholder',
+      ':-ms-input-placeholder',
+      ':placeholder-shown'
+    ]
+    var css = ''
+    var cssRule = 'color: ' + this.placeholderColor + ';'
+    for (var i = 0, l = vendors.length; i < l; i++) {
+      css += '.' + this.className + vendors[i] + '{'
+             + cssRule + '}'
+    }
+    utils.appendStyle(css, this.styleId, true)
+  }
+  
+  module.exports = Input
+
+
+/***/ },
+/* 55 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(16)
+  var sender = __webpack_require__(19)
+  
+  // attrs:
+  //   - options: the options to be listed, as a array of strings.
+  //   - selectedIndex: the selected options' index number.
+  //   - disabled
+  function Select (data) {
+    var attrs = data.attr || {}
+    this.options = []
+    this.selectedIndex = 0
+    Atomic.call(this, data)
+  }
+  
+  Select.prototype = Object.create(Atomic.prototype)
+  
+  Select.prototype.create = function () {
+    var node = document.createElement('select')
+    var uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
+    this.className = 'weex-slct-' + uuid
+    this.styleId = 'weex-style-' + uuid
+    node.classList.add(this.className)
+    // For the consistency of input component's width.
+    // The date and time type of input will have a bigger width
+    // when the 'box-sizing' is not set to 'border-box'
+    node.style['box-sizing'] = 'border-box'
+    return node
+  }
+  
+  Select.prototype.attr = {
+    disabled: function (val) {
+      this.node.disabled = val && val !== 'false'
+                      ? true
+                      : false
+    },
+    options: function (val) {
+      if (Object.prototype.toString.call(val) !== '[object Array]') {
+        return
+      }
+      this.options = val
+      this.node.innerHTML = ''
+      this.createOptions(val)
+    },
+    selectedIndex: function (val) {
+      val = parseInt(val)
+      if (typeof val !== 'number' || val !== val || val >= this.options.length) {
+        return
+      }
+      this.node.value = this.options[val]
+    }
+  }
+  
+  Select.prototype.bindEvents = function (evts) {
+    var isListenToChange = false
+    Atomic.prototype.bindEvents.call(
+        this,
+        evts.filter(function (val) {
+          var pass = val !== 'change'
+          !pass && (isListenToChange = true)
+          return pass
+        }))
+    if (isListenToChange) {
+      this.node.addEventListener('change', function (e) {
+        e.index = this.options.indexOf(this.node.value)
+        sender.fireEvent(this.data.ref, 'change', e)
+      }.bind(this))
+    }
+  }
+  
+  Select.prototype.createOptions = function (opts) {
+    var optDoc = document.createDocumentFragment()
+    var opt
+    for (var i = 0, l = opts.length; i < l; i++) {
+      opt = document.createElement('option')
+      opt.appendChild(document.createTextNode(opts[i]))
+      optDoc.appendChild(opt)
+    }
+    this.node.appendChild(optDoc)
+  }
+  
+  module.exports = Select
+
+
+/***/ },
+/* 56 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(27)
+  
+  // attrs:
+  //   - value
+  //   - disabled
+  function Datepicker (data) {
+    Atomic.call(this, data)
+  }
+  
+  Datepicker.prototype = Object.create(Atomic.prototype)
+  
+  Datepicker.prototype.create = function () {
+    var node = document.createElement('input')
+    var uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
+    this.className = 'weex-ipt-' + uuid
+    this.styleId = 'weex-style-' + uuid
+    node.classList.add(this.className)
+    node.setAttribute('type', 'date')
+    node.type = 'date'
+    // For the consistency of input component's width.
+    // The date and time type of input will have a bigger width
+    // when the 'box-sizing' is not set to 'border-box'
+    node.classList.add('weex-element')
+    return node
+  }
+  
+  Datepicker.prototype.attr = {
+    disabled: function (val) {
+      this.node.disabled = val && val !== 'false'
+                      ? true
+                      : false
+    }
+  }
+  
+  module.exports = Datepicker
+
+
+/***/ },
+/* 57 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(27)
+  
+  // attrs:
+  //   - value
+  //   - disabled
+  function Timepicker (data) {
+    Atomic.call(this, data)
+  }
+  
+  Timepicker.prototype = Object.create(Atomic.prototype)
+  
+  Timepicker.prototype.create = function () {
+    var node = document.createElement('input')
+    var uuid = Math.floor(10000000000000 * Math.random()) + Date.now()
+    this.className = 'weex-ipt-' + uuid
+    this.styleId = 'weex-style-' + uuid
+    node.classList.add(this.className)
+    node.setAttribute('type', 'time')
+    node.type = 'time'
+    // For the consistency of input component's width.
+    // The date and time type of input will have a bigger width
+    // when the 'box-sizing' is not set to 'border-box'
+    node.classList.add('weex-element')
+    return node
+  }
+  
+  Timepicker.prototype.attr = {
+    disabled: function (val) {
+      this.node.disabled = val && val !== 'false'
+                      ? true
+                      : false
+    }
+  }
+  
+  module.exports = Timepicker
+
+
+/***/ },
+/* 58 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(27)
+  var utils = __webpack_require__(7)
+  __webpack_require__(59)
+  
+  // attrs:
+  //   - autoPlay: true | false (default: false)
+  //   - playStatus: play | pause | stop
+  //   - src: {string}
+  //   - poster: {string}
+  //   - loop: true | false (default: false)
+  //   - muted: true | false (default: false)
+  // events:
+  //   - start
+  //   - pause
+  //   - finish
+  //   - fail
+  function Video (data) {
+    var autoPlay = data.attr.autoPlay
+    var playStatus = data.attr.playStatus
+    this.autoPlay = autoPlay === true || autoPlay === 'true'
+    if (playStatus !== 'play'
+        && playStatus !== 'stop'
+        && playStatus !== 'pause') {
+      this.playStatus = 'pause'
+    } else {
+      this.playStatus = playStatus
+    }
+    Atomic.call(this, data)
+  }
+  
+  Video.prototype = Object.create(Atomic.prototype)
+  
+  Video.prototype.attr = {
+    playStatus: function (val) {
+      if (val !== 'play' && val !== 'stop' && val !== 'pause') {
+        val = 'pause'
+      }
+      if (this.playStatus === val) {
+        return
+      }
+      this.playStatus = val
+      this.node.setAttribute('play-status', val)
+      this[this.playStatus]()
+    },
+    autoPlay: function (val) {
+      // DO NOTHING
+    }
+  }
+  
+  Video.prototype.create = function () {
+    var node = document.createElement('video')
+    node.classList.add('weex-video', 'weex-element')
+    node.controls = true
+    node.autoplay = this.autoPlay
+    node.setAttribute('play-status', this.playStatus)
+    this.node = node
+    if (this.autoPlay && this.playStatus === 'play') {
+      this.play()
+    }
+    return node
+  }
+  
+  Video.prototype.bindEvents = function (evts) {
+    Atomic.prototype.bindEvents.call(this, evts)
+  
+    // convert w3c-video events to weex-video events.
+    var evtsMap = {
+      start: 'play',
+      finish: 'ended',
+      fail: 'error'
+    }
+    for (var evtName in evtsMap) {
+      this.node.addEventListener(evtsMap[evtName], function (type, e) {
+        this.dispatchEvent(type, e.data)
+      }.bind(this, evtName))
+    }
+  }
+  
+  Video.prototype.play = function () {
+    var src = this.node.getAttribute('src')
+    if (!src) {
+      src = this.node.getAttribute('data-src')
+      src && this.node.setAttribute('src', src)
+    }
+    this.node.play()
+  }
+  
+  Video.prototype.pause = function () {
+    this.node.pause()
+  }
+  
+  Video.prototype.stop = function () {
+    this.node.pause()
+    this.node.autoplay = false
+    this.node.setAttribute('data-src', this.node.src)
+    this.node.src = ''
+  }
+  
+  module.exports = Video
+
+
+/***/ },
+/* 59 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(60);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./video.scss", function() {
+        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./video.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 60 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".weex-video {\n  background-color: #000; }\n", "", {"version":3,"sources":["/./src/src/styles/video.scss"],"names":[],"mappings":"AAAA;EACC,uBAAuB,EACvB","file":"video.scss","sourcesContent":[".weex-video {\n\tbackground-color: #000;\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 61 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Atomic = __webpack_require__(27)
+  var utils = __webpack_require__(7)
+  __webpack_require__(62)
+  
+  var defaults = {
+    color: '#64bd63'
+    , secondaryColor: '#dfdfdf'
+    , jackColor: '#fff'
+    , jackSecondaryColor: null
+    , className: 'weex-switch'
+    , disabledOpacity: 0.5
+    , speed: '0.4s'
+    , width: 100
+    , height: 60
+    // is width and height scalable ?
+    , scalable: false
+  }
+  
+  // attrs:
+  //   - checked: if is checked.
+  //   - disabled: if true, this component is not available for interaction.
+  function Switch (data) {
+    this.options = utils.extend({}, defaults)
+    this.checked = data.attr.checked
+        && data.attr.checked !== 'false' ? true : false
+    this.data = data
+    this.width = this.options.width * data.scale
+    this.height = this.options.height * data.scale
+    Atomic.call(this, data)
+  }
+  
+  Switch.prototype = Object.create(Atomic.prototype)
+  
+  Switch.prototype.create = function () {
+    var node = document.createElement('span')
+    this.jack = document.createElement('small')
+    node.appendChild(this.jack)
+    node.className = this.options.className
+    this.node = node
+    this.attr.disabled.call(this, this.data.attr.disabled)
+    return node
+  }
+  
+  Switch.prototype.onAppend = function () {
+    this.setSize()
+    this.setPosition()
+  }
+  
+  Switch.prototype.attr = {
+    disabled: function (val) {
+      this.disabled = val && val !== 'false'
+                      ? true
+                      : false
+      this.disabled ? this.disable() : this.enable()
+    }
+  }
+  
+  Switch.prototype.setSize = function () {
+    var min = Math.min(this.width, this.height)
+    var max = Math.max(this.width, this.height)
+    this.node.style.width = max + 'px'
+    this.node.style.height = min + 'px'
+    this.node.style.borderRadius = min / 2 + 'px'
+    this.jack.style.width
+        = this.jack.style.height
+        = min + 'px'
+  }
+  
+  Switch.prototype.setPosition = function (clicked) {
+    var checked = this.checked
+    var node = this.node
+    var jack = this.jack
+  
+    if (clicked && checked) {
+      checked = false
+    } else if (clicked && !checked) {
+      checked = true
+    }
+  
+    if (checked === true) {
+      this.checked = true
+  
+      if (window.getComputedStyle) {
+        jack.style.left = parseInt(window.getComputedStyle(node).width)
+                          - parseInt(window.getComputedStyle(jack).width) + 'px'
+      } else {
+        jack.style.left = parseInt(node.currentStyle['width'])
+                          - parseInt(jack.currentStyle['width']) + 'px'
+      }
+  
+      this.options.color && this.colorize()
+      this.setSpeed()
+    } else {
+      this.checked = false
+      jack.style.left = 0
+      node.style.boxShadow = 'inset 0 0 0 0 ' + this.options.secondaryColor
+      node.style.borderColor = this.options.secondaryColor
+      node.style.backgroundColor
+          = (this.options.secondaryColor !== defaults.secondaryColor)
+            ? this.options.secondaryColor
+            : '#fff'
+      jack.style.backgroundColor
+          = (this.options.jackSecondaryColor !== this.options.jackColor)
+            ? this.options.jackSecondaryColor
+            : this.options.jackColor
+      this.setSpeed()
+    }
+  }
+  
+  Switch.prototype.colorize = function () {
+    var nodeHeight = this.node.offsetHeight / 2
+  
+    this.node.style.backgroundColor = this.options.color
+    this.node.style.borderColor = this.options.color
+    this.node.style.boxShadow = 'inset 0 0 0 '
+                                + nodeHeight
+                                + 'px '
+                                + this.options.color
+    this.jack.style.backgroundColor = this.options.jackColor
+  }
+  
+  Switch.prototype.setSpeed = function () {
+    var switcherProp = {}
+    var jackProp = {
+        'background-color': this.options.speed
+        , left: this.options.speed.replace(/[a-z]/, '') / 2 + 's'
+      }
+  
+    if (this.checked) {
+      switcherProp = {
+        border: this.options.speed
+        , 'box-shadow': this.options.speed
+        , 'background-color': this.options.speed.replace(/[a-z]/, '') * 3 + 's'
+      }
+    } else {
+      switcherProp = {
+        border: this.options.speed
+        , 'box-shadow': this.options.speed
+      }
+    }
+  
+    utils.transitionize(this.node, switcherProp)
+    utils.transitionize(this.jack, jackProp)
+  }
+  
+  Switch.prototype.disable = function () {
+    !this.disabled && (this.disabled = true)
+    this.node.style.opacity = defaults.disabledOpacity
+    this.node.removeEventListener('click', this.getClickHandler())
+  }
+  
+  Switch.prototype.enable = function () {
+    this.disabled && (this.disabled = false)
+    this.node.style.opacity = 1
+    this.node.addEventListener('click', this.getClickHandler())
+  }
+  
+  Switch.prototype.getClickHandler = function () {
+    if (!this._clickHandler) {
+      this._clickHandler = function () {
+        // var parent = this.node.parentNode.tagName.toLowerCase()
+        // var labelParent = (parent === 'label') ? false : true
+        this.setPosition(true)
+        this.dispatchEvent('change', {
+          checked: this.checked
+        })
+      }.bind(this)
+    }
+    return this._clickHandler
+  }
+  
+  Switch.prototype.style
+      = utils.extend(Object.create(Atomic.prototype.style), {
+  
+        width: function (val) {
+          if (!this.options.scalable) {
+            return
+          }
+          val = parseFloat(val)
+          if (val !== val || val < 0) { // NaN
+            val = this.options.width
+          }
+          this.width = val * this.data.scale
+          this.setSize()
+        },
+  
+        height: function (val) {
+          if (!this.options.scalable) {
+            return
+          }
+          val = parseFloat(val)
+          if (val !== val || val < 0) { // NaN
+            val = this.options.height
+          }
+          this.height = val * this.data.scale
+          this.setSize()
+        }
+  
+      })
+  
+  module.exports = Switch
+
+
+/***/ },
+/* 62 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(63);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./switch.scss", function() {
+        var newContent = require("!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/sass-loader/index.js?sourceMap!./switch.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 63 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, "/* switch defaults. */\n.weex-switch {\n  background-color: #fff;\n  border: 1px solid #dfdfdf;\n  cursor: pointer;\n  display: inline-block;\n  position: relative;\n  vertical-align: middle;\n  -moz-user-select: none;\n  -khtml-user-select: none;\n  -webkit-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  box-sizing: content-box;\n  background-clip: content-box; }\n\n.weex-switch > small {\n  background: #fff;\n  border-radius: 100%;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);\n  position: absolute;\n  top: 0; }\n", "", {"version":3,"sources":["/./src/src/styles/switch.scss"],"names":[],"mappings":"AAAA,sBAAsB;AAEtB;EACE,uBAAuB;EACvB,0BAA0B;EAC1B,gBAAgB;EAChB,sBAAsB;EACtB,mBAAmB;EACnB,uBAAuB;EAEvB,uBAAuB;EACvB,yBAAyB;EACzB,0BAA0B;EAC1B,sBAAsB;EACtB,kBAAkB;EAClB,wBAAwB;EACxB,6BAA6B,EAC9B;;AAED;EACE,iBAAiB;EACjB,oBAAoB;EACpB,yCAA0B;EAC1B,mBAAmB;EACnB,OAAO,EACR","file":"switch.scss","sourcesContent":["/* switch defaults. */\n\n.weex-switch {\n  background-color: #fff;\n  border: 1px solid #dfdfdf;\n  cursor: pointer;\n  display: inline-block;\n  position: relative;\n  vertical-align: middle;\n\n  -moz-user-select: none;\n  -khtml-user-select: none;\n  -webkit-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  box-sizing: content-box;\n  background-clip: content-box;\n}\n\n.weex-switch > small {\n  background: #fff;\n  border-radius: 100%;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);\n  position: absolute;\n  top: 0;\n}\n"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 64 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Component = __webpack_require__(16)
+  
+  // attrs:
+  //   - href
+  function A (data) {
+    Component.call(this, data)
+  }
+  
+  A.prototype = Object.create(Component.prototype)
+  
+  A.prototype.create = function () {
+    var node = document.createElement('a')
+    node.classList.add('weex-container')
+    this.node = node
+    this.style.alignItems.call(this, 'center')
+    this.style.justifyContent.call(this, 'center')
+    this.node.style.textDecoration = 'none'
+    return node
+  }
+  
+  module.exports = A
+
+
+/***/ },
+/* 65 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Component = __webpack_require__(16)
+  var utils = __webpack_require__(7)
+  
+  var ID_PREFIX = 'weex_embed_'
+  
+  function _generateId() {
+    return ID_PREFIX + utils.getRandom(10)
+  }
+  
+  function Embed (data, nodeType) {
+    var attr = data.attr
+    if (attr) {
+      this.source = attr.src
+      this.loader = attr.loade || 'xhr'
+    }
+    Component.call(this, data, nodeType)
+    this.initWeex()
+  }
+  
+  Embed.prototype = Object.create(Component.prototype)
+  
+  Embed.prototype.create = function () {
+  
+    var node = document.createElement('div')
+    node.id = this.id
+    node.style.overflow = 'scroll'
+    // node.classList.add('weex-container')
+    return node
+  }
+  
+  Embed.prototype.initWeex = function () {
+    this.id = _generateId()
+    this.node.id = this.id
+    var config = {
+      appId: this.id,
+      source: this.source,
+      loader: this.loader,
+      width: this.node.getBoundingClientRect().width,
+      rootId: this.id
+    }
+    window.weex.init(config)
+  }
+  
+  Embed.prototype.destroyWeex = function () {
+    this.id && window.destroyInstance(this.id)
+    // TODO: unbind events and clear doms.
+    this.node.innerHTML = ''
+  }
+  
+  Embed.prototype.reloadWeex = function () {
+    this.destroyWeex()
+    this.initWeex()
+  }
+  
+  // src is not updatable temporarily
+  // Embed.prototype.attr = {
+  //   src: function (value) {
+  //     this.src = value
+  //     this.reloadWeex()
+  //   }
+  // }
+  
+  module.exports = Embed
+
+
+/***/ },
+/* 66 */
+/***/ function(module, exports, __webpack_require__) {
+
+  var dom = __webpack_require__(67)
+  var event = __webpack_require__(75)
+  var pageInfo = __webpack_require__(76)
+  var stream = __webpack_require__(77)
+  var modal = __webpack_require__(78)
+  var animation = __webpack_require__(95)
+  
+  var api = {
+    init: function (Weex) {
+      Weex.registerApiModule('dom', dom, dom._meta)
+      Weex.registerApiModule('event', event, event._meta)
+      Weex.registerApiModule('pageInfo', pageInfo, pageInfo._meta)
+      Weex.registerApiModule('stream', stream, stream._meta)
+      Weex.registerApiModule('modal', modal, modal._meta)
+      Weex.registerApiModule('animation', animation, animation._meta)
+    }
+  }
+  
+  module.exports = api
+
+/***/ },
+/* 67 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var messageQueue = __webpack_require__(48)
+  var FrameUpdater = __webpack_require__(10)
+  var Component = __webpack_require__(16)
+  var scroll = __webpack_require__(68)
+  var config = __webpack_require__(5)
+  // var Weex = require('../weex')
+  
+  var dom = {
+  
+    /**
+     * createBody: create root component
+     * @param  {object} element
+     *    container|listview|scrollview
+     * @return {[type]}      [description]
+     */
+    createBody: function (element) {
+      var componentManager = this.getComponentManager()
+      element.scale = this.scale
+      element.instanceId = componentManager.instanceId
+      return componentManager.createBody(element)
+    },
+  
+    addElement: function (parentRef, element, index) {
+      var componentManager = this.getComponentManager()
+      element.scale = this.scale
+      element.instanceId = componentManager.instanceId
+      return componentManager.addElement(parentRef, element, index)
+    },
+  
+    removeElement: function (ref) {
+      var componentManager = this.getComponentManager()
+      return componentManager.removeElement(ref)
+    },
+  
+    moveElement: function (ref, parentRef, index) {
+      var componentManager = this.getComponentManager()
+      return componentManager.moveElement(ref, parentRef, index)
+    },
+  
+    addEvent: function (ref, type) {
+      var componentManager = this.getComponentManager()
+      return componentManager.addEvent(ref, type)
+    },
+  
+    removeEvent: function (ref, type) {
+      var componentManager = this.getComponentManager()
+      return componentManager.removeEvent(ref, type)
+    },
+  
+    /**
+     * updateAttrs: update attributes of component
+     * @param  {string} ref
+     * @param  {obj} attr
+     */
+    updateAttrs: function (ref, attr) {
+      var componentManager = this.getComponentManager()
+      return componentManager.updateAttrs(ref, attr)
+    },
+  
+    /**
+     * updateStyle: udpate style of component
+     * @param {string} ref
+     * @param {obj} style
+     */
+    updateStyle: function (ref, style) {
+      var componentManager = this.getComponentManager()
+      return componentManager.updateStyle(ref, style)
+    },
+  
+    createFinish: function () {
+      // TODO
+      // FrameUpdater.pause()
+    },
+  
+    refreshFinish: function () {
+      // TODO
+    },
+  
+    /**
+     * scrollToElement
+     * @param  {string} ref
+     * @param  {obj} options {offset:Number}
+     *   ps: scroll-to has 'ease' and 'duration'(ms) as options.
+     */
+    scrollToElement: function (ref, options) {
+      !options && (options = {})
+      var componentManager = this.getComponentManager()
+      var elem = componentManager.getElementByRef(ref)
+      if (elem) {
+        var offsetTop = elem.node.getBoundingClientRect().top
+            + document.body.scrollTop
+        var offset = (Number(options.offset) || 0) * this.scale
+        var tween = scroll(0, offsetTop + offset, options)
+        // tween.on('end', function () {
+        // })
+      }
+    }
+  
+  }
+  
+  dom._meta = {
+    dom: [{
+      name: 'createBody',
+      args: ['object']
+    }, {
+      name: 'addElement',
+      args: ['string', 'object', 'number']
+    }, {
+      name: 'removeElement',
+      args: ['string']
+    }, {
+      name: 'moveElement',
+      args: ['string', 'string', 'number']
+    }, {
+      name: 'addEvent',
+      args: ['string', 'string']
+    }, {
+      name: 'removeEvent',
+      args: ['string', 'string']
+    }, {
+      name: 'updateAttrs',
+      args: ['string', 'object']
+    }, {
+      name: 'updateStyle',
+      args: ['string', 'object']
+    }, {
+      name: 'createFinish',
+      args: []
+    }, {
+      name: 'refreshFinish',
+      args: []
+    }, {
+      name: 'scrollToElement',
+      args: ['string', 'object']
+    }]
+  }
+  
+  module.exports = dom
+
+
+/***/ },
+/* 68 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /**
+   * Module dependencies.
+   */
+  
+  var Tween = __webpack_require__(69);
+  var raf = __webpack_require__(74);
+  
+  /**
+   * Expose `scrollTo`.
+   */
+  
+  module.exports = scrollTo;
+  
+  /**
+   * Scroll to `(x, y)`.
+   *
+   * @param {Number} x
+   * @param {Number} y
+   * @api public
+   */
+  
+  function scrollTo(x, y, options) {
+    options = options || {};
+  
+    // start position
+    var start = scroll();
+  
+    // setup tween
+    var tween = Tween(start)
+      .ease(options.ease || 'out-circ')
+      .to({ top: y, left: x })
+      .duration(options.duration || 1000);
+  
+    // scroll
+    tween.update(function(o){
+      window.scrollTo(o.left | 0, o.top | 0);
+    });
+  
+    // handle end
+    tween.on('end', function(){
+      animate = function(){};
+    });
+  
+    // animate
+    function animate() {
+      raf(animate);
+      tween.update();
+    }
+  
+    animate();
+    
+    return tween;
+  }
+  
+  /**
+   * Return scroll position.
+   *
+   * @return {Object}
+   * @api private
+   */
+  
+  function scroll() {
+    var y = window.pageYOffset || document.documentElement.scrollTop;
+    var x = window.pageXOffset || document.documentElement.scrollLeft;
+    return { top: y, left: x };
+  }
+
+
+/***/ },
+/* 69 */
+/***/ function(module, exports, __webpack_require__) {
+
+  
+  /**
+   * Module dependencies.
+   */
+  
+  var Emitter = __webpack_require__(70);
+  var clone = __webpack_require__(71);
+  var type = __webpack_require__(72);
+  var ease = __webpack_require__(73);
+  
+  /**
+   * Expose `Tween`.
+   */
+  
+  module.exports = Tween;
+  
+  /**
+   * Initialize a new `Tween` with `obj`.
+   *
+   * @param {Object|Array} obj
+   * @api public
+   */
+  
+  function Tween(obj) {
+    if (!(this instanceof Tween)) return new Tween(obj);
+    this._from = obj;
+    this.ease('linear');
+    this.duration(500);
+  }
+  
+  /**
+   * Mixin emitter.
+   */
+  
+  Emitter(Tween.prototype);
+  
+  /**
+   * Reset the tween.
+   *
+   * @api public
+   */
+  
+  Tween.prototype.reset = function(){
+    this.isArray = 'array' === type(this._from);
+    this._curr = clone(this._from);
+    this._done = false;
+    this._start = Date.now();
+    return this;
+  };
+  
+  /**
+   * Tween to `obj` and reset internal state.
+   *
+   *    tween.to({ x: 50, y: 100 })
+   *
+   * @param {Object|Array} obj
+   * @return {Tween} self
+   * @api public
+   */
+  
+  Tween.prototype.to = function(obj){
+    this.reset();
+    this._to = obj;
+    return this;
+  };
+  
+  /**
+   * Set duration to `ms` [500].
+   *
+   * @param {Number} ms
+   * @return {Tween} self
+   * @api public
+   */
+  
+  Tween.prototype.duration = function(ms){
+    this._duration = ms;
+    return this;
+  };
+  
+  /**
+   * Set easing function to `fn`.
+   *
+   *    tween.ease('in-out-sine')
+   *
+   * @param {String|Function} fn
+   * @return {Tween}
+   * @api public
+   */
+  
+  Tween.prototype.ease = function(fn){
+    fn = 'function' == typeof fn ? fn : ease[fn];
+    if (!fn) throw new TypeError('invalid easing function');
+    this._ease = fn;
+    return this;
+  };
+  
+  /**
+   * Stop the tween and immediately emit "stop" and "end".
+   *
+   * @return {Tween}
+   * @api public
+   */
+  
+  Tween.prototype.stop = function(){
+    this.stopped = true;
+    this._done = true;
+    this.emit('stop');
+    this.emit('end');
+    return this;
+  };
+  
+  /**
+   * Perform a step.
+   *
+   * @return {Tween} self
+   * @api private
+   */
+  
+  Tween.prototype.step = function(){
+    if (this._done) return;
+  
+    // duration
+    var duration = this._duration;
+    var now = Date.now();
+    var delta = now - this._start;
+    var done = delta >= duration;
+  
+    // complete
+    if (done) {
+      this._from = this._to;
+      this._update(this._to);
+      this._done = true;
+      this.emit('end');
+      return this;
+    }
+  
+    // tween
+    var from = this._from;
+    var to = this._to;
+    var curr = this._curr;
+    var fn = this._ease;
+    var p = (now - this._start) / duration;
+    var n = fn(p);
+  
+    // array
+    if (this.isArray) {
+      for (var i = 0; i < from.length; ++i) {
+        curr[i] = from[i] + (to[i] - from[i]) * n;
+      }
+  
+      this._update(curr);
+      return this;
+    }
+  
+    // objech
+    for (var k in from) {
+      curr[k] = from[k] + (to[k] - from[k]) * n;
+    }
+  
+    this._update(curr);
+    return this;
+  };
+  
+  /**
+   * Set update function to `fn` or
+   * when no argument is given this performs
+   * a "step".
+   *
+   * @param {Function} fn
+   * @return {Tween} self
+   * @api public
+   */
+  
+  Tween.prototype.update = function(fn){
+    if (0 == arguments.length) return this.step();
+    this._update = fn;
+    return this;
+  };
+
+/***/ },
+/* 70 */
+/***/ function(module, exports) {
+
+  
+  /**
+   * Expose `Emitter`.
+   */
+  
+  module.exports = Emitter;
+  
+  /**
+   * Initialize a new `Emitter`.
+   *
+   * @api public
+   */
+  
+  function Emitter(obj) {
+    if (obj) return mixin(obj);
+  };
+  
+  /**
+   * Mixin the emitter properties.
+   *
+   * @param {Object} obj
+   * @return {Object}
+   * @api private
+   */
+  
+  function mixin(obj) {
+    for (var key in Emitter.prototype) {
+      obj[key] = Emitter.prototype[key];
+    }
+    return obj;
+  }
+  
+  /**
+   * Listen on the given `event` with `fn`.
+   *
+   * @param {String} event
+   * @param {Function} fn
+   * @return {Emitter}
+   * @api public
+   */
+  
+  Emitter.prototype.on =
+  Emitter.prototype.addEventListener = function(event, fn){
+    this._callbacks = this._callbacks || {};
+    (this._callbacks['$' + event] = this._callbacks['$' + event] || [])
+      .push(fn);
+    return this;
+  };
+  
+  /**
+   * Adds an `event` listener that will be invoked a single
+   * time then automatically removed.
+   *
+   * @param {String} event
+   * @param {Function} fn
+   * @return {Emitter}
+   * @api public
+   */
+  
+  Emitter.prototype.once = function(event, fn){
+    function on() {
+      this.off(event, on);
+      fn.apply(this, arguments);
+    }
+  
+    on.fn = fn;
+    this.on(event, on);
+    return this;
+  };
+  
+  /**
+   * Remove the given callback for `event` or all
+   * registered callbacks.
+   *
+   * @param {String} event
+   * @param {Function} fn
+   * @return {Emitter}
+   * @api public
+   */
+  
+  Emitter.prototype.off =
+  Emitter.prototype.removeListener =
+  Emitter.prototype.removeAllListeners =
+  Emitter.prototype.removeEventListener = function(event, fn){
+    this._callbacks = this._callbacks || {};
+  
+    // all
+    if (0 == arguments.length) {
+      this._callbacks = {};
+      return this;
+    }
+  
+    // specific event
+    var callbacks = this._callbacks['$' + event];
+    if (!callbacks) return this;
+  
+    // remove all handlers
+    if (1 == arguments.length) {
+      delete this._callbacks['$' + event];
+      return this;
+    }
+  
+    // remove specific handler
+    var cb;
+    for (var i = 0; i < callbacks.length; i++) {
+      cb = callbacks[i];
+      if (cb === fn || cb.fn === fn) {
+        callbacks.splice(i, 1);
+        break;
+      }
+    }
+    return this;
+  };
+  
+  /**
+   * Emit `event` with the given args.
+   *
+   * @param {String} event
+   * @param {Mixed} ...
+   * @return {Emitter}
+   */
+  
+  Emitter.prototype.emit = function(event){
+    this._callbacks = this._callbacks || {};
+    var args = [].slice.call(arguments, 1)
+      , callbacks = this._callbacks['$' + event];
+  
+    if (callbacks) {
+      callbacks = callbacks.slice(0);
+      for (var i = 0, len = callbacks.length; i < len; ++i) {
+        callbacks[i].apply(this, args);
+      }
+    }
+  
+    return this;
+  };
+  
+  /**
+   * Return array of callbacks for `event`.
+   *
+   * @param {String} event
+   * @return {Array}
+   * @api public
+   */
+  
+  Emitter.prototype.listeners = function(event){
+    this._callbacks = this._callbacks || {};
+    return this._callbacks['$' + event] || [];
+  };
+  
+  /**
+   * Check if this emitter has `event` handlers.
+   *
+   * @param {String} event
+   * @return {Boolean}
+   * @api public
+   */
+  
+  Emitter.prototype.hasListeners = function(event){
+    return !! this.listeners(event).length;
+  };
+
+
+/***/ },
+/* 71 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /**
+   * Module dependencies.
+   */
+  
+  var type;
+  try {
+    type = __webpack_require__(72);
+  } catch (_) {
+    type = __webpack_require__(72);
+  }
+  
+  /**
+   * Module exports.
+   */
+  
+  module.exports = clone;
+  
+  /**
+   * Clones objects.
+   *
+   * @param {Mixed} any object
+   * @api public
+   */
+  
+  function clone(obj){
+    switch (type(obj)) {
+      case 'object':
+        var copy = {};
+        for (var key in obj) {
+          if (obj.hasOwnProperty(key)) {
+            copy[key] = clone(obj[key]);
+          }
+        }
+        return copy;
+  
+      case 'array':
+        var copy = new Array(obj.length);
+        for (var i = 0, l = obj.length; i < l; i++) {
+          copy[i] = clone(obj[i]);
+        }
+        return copy;
+  
+      case 'regexp':
+        // from millermedeiros/amd-utils - MIT
+        var flags = '';
+        flags += obj.multiline ? 'm' : '';
+        flags += obj.global ? 'g' : '';
+        flags += obj.ignoreCase ? 'i' : '';
+        return new RegExp(obj.source, flags);
+  
+      case 'date':
+        return new Date(obj.getTime());
+  
+      default: // string, number, boolean, …
+        return obj;
+    }
+  }
+
+
+/***/ },
+/* 72 */
+/***/ function(module, exports) {
+
+  /**
+   * toString ref.
+   */
+  
+  var toString = Object.prototype.toString;
+  
+  /**
+   * Return the type of `val`.
+   *
+   * @param {Mixed} val
+   * @return {String}
+   * @api public
+   */
+  
+  module.exports = function(val){
+    switch (toString.call(val)) {
+      case '[object Date]': return 'date';
+      case '[object RegExp]': return 'regexp';
+      case '[object Arguments]': return 'arguments';
+      case '[object Array]': return 'array';
+      case '[object Error]': return 'error';
+    }
+  
+    if (val === null) return 'null';
+    if (val === undefined) return 'undefined';
+    if (val !== val) return 'nan';
+    if (val && val.nodeType === 1) return 'element';
+  
+    val = val.valueOf
+      ? val.valueOf()
+      : Object.prototype.valueOf.apply(val)
+  
+    return typeof val;
+  };
+
+
+/***/ },
+/* 73 */
+/***/ function(module, exports) {
+
+  
+  // easing functions from "Tween.js"
+  
+  exports.linear = function(n){
+    return n;
+  };
+  
+  exports.inQuad = function(n){
+    return n * n;
+  };
+  
+  exports.outQuad = function(n){
+    return n * (2 - n);
+  };
+  
+  exports.inOutQuad = function(n){
+    n *= 2;
+    if (n < 1) return 0.5 * n * n;
+    return - 0.5 * (--n * (n - 2) - 1);
+  };
+  
+  exports.inCube = function(n){
+    return n * n * n;
+  };
+  
+  exports.outCube = function(n){
+    return --n * n * n + 1;
+  };
+  
+  exports.inOutCube = function(n){
+    n *= 2;
+    if (n < 1) return 0.5 * n * n * n;
+    return 0.5 * ((n -= 2 ) * n * n + 2);
+  };
+  
+  exports.inQuart = function(n){
+    return n * n * n * n;
+  };
+  
+  exports.outQuart = function(n){
+    return 1 - (--n * n * n * n);
+  };
+  
+  exports.inOutQuart = function(n){
+    n *= 2;
+    if (n < 1) return 0.5 * n * n * n * n;
+    return -0.5 * ((n -= 2) * n * n * n - 2);
+  };
+  
+  exports.inQuint = function(n){
+    return n * n * n * n * n;
+  }
+  
+  exports.outQuint = function(n){
+    return --n * n * n * n * n + 1;
+  }
+  
+  exports.inOutQuint = function(n){
+    n *= 2;
+    if (n < 1) return 0.5 * n * n * n * n * n;
+    return 0.5 * ((n -= 2) * n * n * n * n + 2);
+  };
+  
+  exports.inSine = function(n){
+    return 1 - Math.cos(n * Math.PI / 2 );
+  };
+  
+  exports.outSine = function(n){
+    return Math.sin(n * Math.PI / 2);
+  };
+  
+  exports.inOutSine = function(n){
+    return .5 * (1 - Math.cos(Math.PI * n));
+  };
+  
+  exports.inExpo = function(n){
+    return 0 == n ? 0 : Math.pow(1024, n - 1);
+  };
+  
+  exports.outExpo = function(n){
+    return 1 == n ? n : 1 - Math.pow(2, -10 * n);
+  };
+  
+  exports.inOutExpo = function(n){
+    if (0 == n) return 0;
+    if (1 == n) return 1;
+    if ((n *= 2) < 1) return .5 * Math.pow(1024, n - 1);
+    return .5 * (-Math.pow(2, -10 * (n - 1)) + 2);
+  };
+  
+  exports.inCirc = function(n){
+    return 1 - Math.sqrt(1 - n * n);
+  };
+  
+  exports.outCirc = function(n){
+    return Math.sqrt(1 - (--n * n));
+  };
+  
+  exports.inOutCirc = function(n){
+    n *= 2
+    if (n < 1) return -0.5 * (Math.sqrt(1 - n * n) - 1);
+    return 0.5 * (Math.sqrt(1 - (n -= 2) * n) + 1);
+  };
+  
+  exports.inBack = function(n){
+    var s = 1.70158;
+    return n * n * (( s + 1 ) * n - s);
+  };
+  
+  exports.outBack = function(n){
+    var s = 1.70158;
+    return --n * n * ((s + 1) * n + s) + 1;
+  };
+  
+  exports.inOutBack = function(n){
+    var s = 1.70158 * 1.525;
+    if ( ( n *= 2 ) < 1 ) return 0.5 * ( n * n * ( ( s + 1 ) * n - s ) );
+    return 0.5 * ( ( n -= 2 ) * n * ( ( s + 1 ) * n + s ) + 2 );
+  };
+  
+  exports.inBounce = function(n){
+    return 1 - exports.outBounce(1 - n);
+  };
+  
+  exports.outBounce = function(n){
+    if ( n < ( 1 / 2.75 ) ) {
+      return 7.5625 * n * n;
+    } else if ( n < ( 2 / 2.75 ) ) {
+      return 7.5625 * ( n -= ( 1.5 / 2.75 ) ) * n + 0.75;
+    } else if ( n < ( 2.5 / 2.75 ) ) {
+      return 7.5625 * ( n -= ( 2.25 / 2.75 ) ) * n + 0.9375;
+    } else {
+      return 7.5625 * ( n -= ( 2.625 / 2.75 ) ) * n + 0.984375;
+    }
+  };
+  
+  exports.inOutBounce = function(n){
+    if (n < .5) return exports.inBounce(n * 2) * .5;
+    return exports.outBounce(n * 2 - 1) * .5 + .5;
+  };
+  
+  // aliases
+  
+  exports['in-quad'] = exports.inQuad;
+  exports['out-quad'] = exports.outQuad;
+  exports['in-out-quad'] = exports.inOutQuad;
+  exports['in-cube'] = exports.inCube;
+  exports['out-cube'] = exports.outCube;
+  exports['in-out-cube'] = exports.inOutCube;
+  exports['in-quart'] = exports.inQuart;
+  exports['out-quart'] = exports.outQuart;
+  exports['in-out-quart'] = exports.inOutQuart;
+  exports['in-quint'] = exports.inQuint;
+  exports['out-quint'] = exports.outQuint;
+  exports['in-out-quint'] = exports.inOutQuint;
+  exports['in-sine'] = exports.inSine;
+  exports['out-sine'] = exports.outSine;
+  exports['in-out-sine'] = exports.inOutSine;
+  exports['in-expo'] = exports.inExpo;
+  exports['out-expo'] = exports.outExpo;
+  exports['in-out-expo'] = exports.inOutExpo;
+  exports['in-circ'] = exports.inCirc;
+  exports['out-circ'] = exports.outCirc;
+  exports['in-out-circ'] = exports.inOutCirc;
+  exports['in-back'] = exports.inBack;
+  exports['out-back'] = exports.outBack;
+  exports['in-out-back'] = exports.inOutBack;
+  exports['in-bounce'] = exports.inBounce;
+  exports['out-bounce'] = exports.outBounce;
+  exports['in-out-bounce'] = exports.inOutBounce;
+
+
+/***/ },
+/* 74 */
+/***/ function(module, exports) {
+
+  /**
+   * Expose `requestAnimationFrame()`.
+   */
+  
+  exports = module.exports = window.requestAnimationFrame
+    || window.webkitRequestAnimationFrame
+    || window.mozRequestAnimationFrame
+    || fallback;
+  
+  /**
+   * Fallback implementation.
+   */
+  
+  var prev = new Date().getTime();
+  function fallback(fn) {
+    var curr = new Date().getTime();
+    var ms = Math.max(0, 16 - (curr - prev));
+    var req = setTimeout(fn, ms);
+    prev = curr;
+    return req;
+  }
+  
+  /**
+   * Cancel.
+   */
+  
+  var cancel = window.cancelAnimationFrame
+    || window.webkitCancelAnimationFrame
+    || window.mozCancelAnimationFrame
+    || window.clearTimeout;
+  
+  exports.cancel = function(id){
+    cancel.call(window, id);
+  };
+
+
+/***/ },
+/* 75 */
+/***/ function(module, exports) {
+
+  'use strict'
+  
+  var event = {
+    /**
+     * openUrl
+     * @param  {string} url
+     */
+    openURL: function (url) {
+      location.href = url
+    }
+  
+  }
+  
+  event._meta = {
+    event: [{
+      name: 'openURL',
+      args: ['string']
+    }]
+  }
+  
+  module.exports = event
+
+/***/ },
+/* 76 */
+/***/ function(module, exports) {
+
+  'use strict'
+  
+  var pageInfo = {
+  
+    setTitle: function (title) {
+      title = title || 'Weex HTML5'
+      try {
+        title = decodeURIComponent(title)
+      } catch (e) {}
+      document.title = title
+    }
+  }
+  
+  pageInfo._meta = {
+    pageInfo: [{
+      name: 'setTitle',
+      args: ['string']
+    }]
+  }
+  
+  module.exports = pageInfo
+
+/***/ },
+/* 77 */
+/***/ function(module, exports) {
+
+  'use strict'
+  
+  // require('httpurl')
+  
+  // var jsonpCnt = 0
+  
+  // function _sendJsonp(config, callbackId) {
+  //   var cbName = '_callback_' + (++jsonpCnt)
+  //   var script, url, head
+  //   global[cbName] = (function (cb) {
+  //     return function (response) {
+  //       this.sender.performCallback(callbackId, response)
+  //       delete global[cb]
+  //     }
+  //   })(cbName)
+  //   script = document.createElement('script')
+  //   url = lib.httpurl(config.url)
+  //   url.params.callback = cbName
+  //   script.type = 'text/javascript'
+  //   script.src = url.toString()
+  //   // script.onerror is not working on IE or safari.
+  //   // but they are not considered here.
+  //   script.onerror = (function (cb) {
+  //     return function (err) {
+  //       this.sender.performCallback(callbackId, err)
+  //       delete global[cb]
+  //     }
+  //   })(cbName)
+  //   head = document.getElementsByTagName('head')[0]
+  //   head.insertBefore(script, null)
+  // }
+  
+  var stream = {
+  
+    /**
+     * sendHttp
+     * @param  {obj} params
+     *  - method: 'GET' | 'POST',
+     *  - url: url requested
+     * @param  {string} callbackId
+     */
+    sendHttp: function (param, callbackId) {
+      if (typeof param === 'string') {
+        try {
+          param = JSON.parse(param)
+        } catch (e) {
+          return
+        }
+      }
+      if (typeof param !== 'object' || !param.url) {
+        return
+      }
+  
+      // Not to use jsonp to send http request since it requires the server
+      // to support jsonp callback at the first place.
+      // _sendJsonp.call(this, param, callbackId)
+  
+      var self = this
+      var method = param.method || 'GET'
+      var xhr = new XMLHttpRequest()
+      xhr.open(method, param.url, true)
+      xhr.onload = function () {
+        self.sender.performCallback(callbackId, this.responseText)
+      }
+      xhr.onerror = function (error) {
+        self.sender.performCallback(callbackId, error)
+      }
+      xhr.send()
+    }
+  
+  }
+  
+  stream._meta = {
+    stream: [{
+      name: 'sendHttp',
+      args: ['object', 'string']
+    }]
+  }
+  
+  module.exports = stream
+
+/***/ },
+/* 78 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var sender = __webpack_require__(19)
+  var modal = __webpack_require__(79)
+  
+  var msg = {
+  
+    // duration: default is 0.8 seconds.
+    toast: function (config) {
+      modal.toast(config.message, config.duration)
+    },
+  
+    // config:
+    //  - message: string
+    //  - okTitle: title of ok button
+    //  - callback
+    alert: function (config, callbackId) {
+      var sender =  this.sender
+      config.callback = function () {
+        sender.performCallback(callbackId)
+      }
+      modal.alert(config)
+    },
+  
+    // config:
+    //  - message: string
+    //  - okTitle: title of ok button
+    //  - cancelTitle: title of cancel button
+    //  - callback
+    confirm: function (config, callbackId) {
+      var sender =  this.sender
+      config.callback = function (val) {
+        sender.performCallback(callbackId, val)
+      }
+      modal.confirm(config)
+    },
+  
+    // config:
+    //  - message: string
+    //  - okTitle: title of ok button
+    //  - cancelTitle: title of cancel button
+    //  - callback
+    prompt: function (config, callbackId) {
+      var sender =  this.sender
+      config.callback = function (val) {
+        sender.performCallback(callbackId, val)
+      }
+      modal.prompt(config)
+    }
+  
+  }
+  
+  msg._meta = {
+    modal: [{
+      name: 'toast',
+      args: ['object']
+    }, {
+      name: 'alert',
+      args: ['object', 'string']
+    }, {
+      name: 'confirm',
+      args: ['object', 'string']
+    }, {
+      name: 'prompt',
+      args: ['object', 'string']
+    }]
+  }
+  
+  module.exports = msg
+
+
+/***/ },
+/* 79 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Alert = __webpack_require__(80)
+  var Confirm = __webpack_require__(86)
+  var Prompt = __webpack_require__(89)
+  var toast = __webpack_require__(92)
+  
+  var modal = {
+  
+    toast: function (msg, duration) {
+      toast.push(msg, duration)
+    },
+  
+    alert: function (config) {
+      new Alert(config).show()
+    },
+  
+    prompt: function (config) {
+      new Prompt(config).show()
+    },
+  
+    confirm: function (config) {
+      new Confirm(config).show()
+    }
+  
+  }
+  
+  !window.lib && (window.lib = {})
+  window.lib.modal = modal
+  
+  module.exports = modal
+
+/***/ },
+/* 80 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Modal = __webpack_require__(81)
+  __webpack_require__(84)
+  
+  var CONTENT_CLASS = 'content'
+  var MSG_CLASS = 'content-msg'
+  var BUTTON_GROUP_CLASS = 'btn-group'
+  var BUTTON_CLASS = 'btn'
+  
+  function Alert(config) {
+    this.msg = config.message || ''
+    this.callback = config.callback
+    this.okTitle = config.okTitle || 'OK'
+    Modal.call(this)
+    this.node.classList.add('amfe-alert')
+  }
+  
+  Alert.prototype = Object.create(Modal.prototype)
+  
+  Alert.prototype.createNodeContent = function () {
+    var content = document.createElement('div')
+    content.classList.add(CONTENT_CLASS)
+    this.node.appendChild(content)
+  
+    var msg = document.createElement('div')
+    msg.classList.add(MSG_CLASS)
+    msg.appendChild(document.createTextNode(this.msg))
+    content.appendChild(msg)
+  
+    var buttonGroup = document.createElement('div')
+    buttonGroup.classList.add(BUTTON_GROUP_CLASS)
+    this.node.appendChild(buttonGroup)
+    var button = document.createElement('div')
+    button.classList.add(BUTTON_CLASS, 'alert-ok')
+    button.appendChild(document.createTextNode(this.okTitle))
+    buttonGroup.appendChild(button)
+  }
+  
+  Alert.prototype.bindEvents = function () {
+    Modal.prototype.bindEvents.call(this)
+    var button = this.node.querySelector('.' + BUTTON_CLASS)
+    button.addEventListener('click', function () {
+      this.destroy()
+      this.callback && this.callback()
+    }.bind(this))
+  }
+  
+  module.exports = Alert
+
+
+/***/ },
+/* 81 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  __webpack_require__(82)
+  
+  // there will be only one instance of modal.
+  var MODAL_WRAP_CLASS = 'amfe-modal-wrap'
+  var MODAL_NODE_CLASS = 'amfe-modal-node'
+  
+  function Modal() {
+    this.wrap = document.querySelector(MODAL_WRAP_CLASS)
+    this.node = document.querySelector(MODAL_NODE_CLASS)
+    if (!this.wrap) {
+      this.createWrap()
+    }
+    if (!this.node) {
+      this.createNode()
+    }
+    this.clearNode()
+    this.createNodeContent()
+    this.bindEvents()
+  }
+  
+  Modal.prototype = {
+  
+    show: function () {
+      this.wrap.style.display = 'block'
+      this.node.classList.remove('hide')
+    },
+  
+    destroy: function () {
+      document.body.removeChild(this.wrap)
+      document.body.removeChild(this.node)
+      this.wrap = null
+      this.node = null
+    },
+  
+    createWrap: function () {
+      this.wrap = document.createElement('div')
+      this.wrap.className = MODAL_WRAP_CLASS
+      document.body.appendChild(this.wrap)
+    },
+  
+    createNode: function () {
+      this.node = document.createElement('div')
+      this.node.classList.add(MODAL_NODE_CLASS, 'hide')
+      document.body.appendChild(this.node)
+    },
+  
+    clearNode: function () {
+      this.node.innerHTML = ''
+    },
+  
+    createNodeContent: function () {
+  
+      // do nothing.
+      // child classes can override this method.
+    },
+  
+    bindEvents: function () {
+      this.wrap.addEventListener('click', function (e) {
+        e.preventDefault()
+        e.stopPropagation()
+      })
+    }
+  }
+  
+  module.exports = Modal
+
+
+/***/ },
+/* 82 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(83);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./modal.scss", function() {
+        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./modal.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 83 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".amfe-modal-wrap {\n  display: none;\n  position: fixed;\n  z-index: 999999999;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-color: #000;\n  opacity: 0.5; }\n\n.amfe-modal-node {\n  position: fixed;\n  z-index: 9999999999;\n  top: 50%;\n  left: 50%;\n  width: 6.666667rem;\n  min-height: 2.666667rem;\n  border-radius: 0.066667rem;\n  -webkit-transform: translate(-50%, -50%);\n  transform: translate(-50%, -50%);\n  background-color: #fff; }\n  .amfe-modal-node.hide {\n    display: none; }\n  .amfe-modal-node .content {\n    width: 100%;\n    min-height: 1.866667rem;\n    box-sizing: border-box;\n    font-size: 0.32rem;\n    line-height: 0.426667rem;\n    padding: 0.213333rem;\n    border-bottom: 1px solid #ddd; }\n  .amfe-modal-node .btn-group {\n    width: 100%;\n    height: 0.8rem;\n    font-size: 0.373333rem;\n    text-align: center; }\n    .amfe-modal-node .btn-group .btn {\n      box-sizing: border-box;\n      height: 0.8rem;\n      line-height: 0.8rem; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/modal.scss"],"names":[],"mappings":"AAAA;EACE,cAAc;EACd,gBAAgB;EAChB,mBAAmB;EACnB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,aAAa;EACb,uBAAuB;EACvB,aAAa,EAEd;;AAED;EACE,gBAAgB;EAChB,oBAAoB;EACpB,SAAS;EACT,UAAU;EACV,mBAAmB;EACnB,wBAAwB;EACxB,2BAA2B;EAC3B,yCAA4B;EAC5B,iCAAoB;EACpB,uBAAuB,EA4BxB;EAtCD;IAaI,cACD,EAAC;EAdJ;IAiBI,YAAY;IACZ,wBAAwB;IACxB,uBAAuB;IACvB,mBAAmB;IACnB,yBAAyB;IACzB,qBAAqB;IACrB,8BAA8B,EAC/B;EAxBH;IA2BI,YAAY;IACZ,eAAe;IACf,uBAAuB;IACvB,mBAAmB,EAOpB;IArCH;MAiCM,uBAAuB;MACvB,eAAe;MACf,oBAAoB,EACrB","file":"modal.scss","sourcesContent":[".amfe-modal-wrap {\n  display: none;\n  position: fixed;\n  z-index: 999999999;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-color: #000;\n  opacity: 0.5;\n\n}\n\n.amfe-modal-node {\n  position: fixed;\n  z-index: 9999999999;\n  top: 50%;\n  left: 50%;\n  width: 6.666667rem; // 500px\n  min-height: 2.666667rem; // 200px\n  border-radius: 0.066667rem; // 5px\n  -webkit-transform: translate(-50%, -50%);\n  transform: translate(-50%, -50%);\n  background-color: #fff;\n\n  &.hide {\n    display: none\n  }\n\n  .content {\n    width: 100%;\n    min-height: 1.866667rem; // 140px\n    box-sizing: border-box;\n    font-size: 0.32rem; // 24px\n    line-height: 0.426667rem; // 32px\n    padding: 0.213333rem; // 16px\n    border-bottom: 1px solid #ddd;\n  }\n\n  .btn-group {\n    width: 100%;\n    height: 0.8rem; // 60px\n    font-size: 0.373333rem; // 28px\n    text-align: center;\n\n    .btn {\n      box-sizing: border-box;\n      height: 0.8rem; // 60px\n      line-height: 0.8rem; // 60px\n    }\n  }\n}\n"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 84 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(85);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./alert.scss", function() {
+        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./alert.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 85 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".amfe-alert .amfe-alert-ok {\n  width: 100%; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/alert.scss"],"names":[],"mappings":"AAAA;EAGI,YAAY,EACb","file":"alert.scss","sourcesContent":[".amfe-alert {\n\n  .amfe-alert-ok {\n    width: 100%;\n  }\n}\n"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 86 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Modal = __webpack_require__(81)
+  __webpack_require__(87)
+  
+  var CONTENT_CLASS = 'content'
+  var MSG_CLASS = 'content-msg'
+  var BUTTON_GROUP_CLASS = 'btn-group'
+  var BUTTON_CLASS = 'btn'
+  
+  function Confirm(config) {
+    this.msg = config.message || ''
+    this.callback = config.callback
+    this.okTitle = config.okTitle || 'OK'
+    this.cancelTitle = config.cancelTitle || 'Cancel'
+    Modal.call(this)
+    this.node.classList.add('amfe-confirm')
+  }
+  
+  Confirm.prototype = Object.create(Modal.prototype)
+  
+  Confirm.prototype.createNodeContent = function () {
+    var content = document.createElement('div')
+    content.classList.add(CONTENT_CLASS)
+    this.node.appendChild(content)
+  
+    var msg = document.createElement('div')
+    msg.classList.add(MSG_CLASS)
+    msg.appendChild(document.createTextNode(this.msg))
+    content.appendChild(msg)
+  
+    var buttonGroup = document.createElement('div')
+    buttonGroup.classList.add(BUTTON_GROUP_CLASS)
+    this.node.appendChild(buttonGroup)
+    var btnOk = document.createElement('div')
+    btnOk.appendChild(document.createTextNode(this.okTitle))
+    btnOk.classList.add('btn-ok', BUTTON_CLASS)
+    var btnCancel = document.createElement('div')
+    btnCancel.appendChild(document.createTextNode(this.cancelTitle))
+    btnCancel.classList.add('btn-cancel', BUTTON_CLASS)
+    buttonGroup.appendChild(btnOk)
+    buttonGroup.appendChild(btnCancel)
+    this.node.appendChild(buttonGroup)
+  }
+  
+  Confirm.prototype.bindEvents = function () {
+    Modal.prototype.bindEvents.call(this)
+    var btnOk = this.node.querySelector('.' + BUTTON_CLASS + '.btn-ok')
+    var btnCancel = this.node.querySelector('.' + BUTTON_CLASS + '.btn-cancel')
+    btnOk.addEventListener('click', function () {
+      this.destroy()
+      this.callback && this.callback(this.okTitle)
+    }.bind(this))
+    btnCancel.addEventListener('click', function () {
+      this.destroy()
+      this.callback && this.callback(this.cancelTitle)
+    }.bind(this))
+  }
+  
+  module.exports = Confirm
+
+
+/***/ },
+/* 87 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(88);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./confirm.scss", function() {
+        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./confirm.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 88 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".amfe-confirm .btn-group .btn {\n  float: left;\n  width: 50%; }\n  .amfe-confirm .btn-group .btn.btn-ok {\n    border-right: 1px solid #ddd; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/confirm.scss"],"names":[],"mappings":"AAAA;EAKM,YAAY;EACZ,WAAW,EAKZ;EAXL;IASO,6BAA6B,EAC7B","file":"confirm.scss","sourcesContent":[".amfe-confirm {\n\n  .btn-group {\n\n    .btn {\n      float: left;\n      width: 50%;\n\n      &.btn-ok {\n      \tborder-right: 1px solid #ddd;\n      }\n    }\n  }\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 89 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Modal = __webpack_require__(81)
+  __webpack_require__(90)
+  
+  var CONTENT_CLASS = 'content'
+  var MSG_CLASS = 'content-msg'
+  var BUTTON_GROUP_CLASS = 'btn-group'
+  var BUTTON_CLASS = 'btn'
+  var INPUT_WRAP_CLASS = 'input-wrap'
+  var INPUT_CLASS = 'input'
+  
+  function Prompt(config) {
+    this.msg = config.message || ''
+    this.defaultMsg = config.default || ''
+    this.callback = config.callback
+    this.okTitle = config.okTitle || 'OK'
+    this.cancelTitle = config.cancelTitle || 'Cancel'
+    Modal.call(this)
+    this.node.classList.add('amfe-prompt')
+  }
+  
+  Prompt.prototype = Object.create(Modal.prototype)
+  
+  Prompt.prototype.createNodeContent = function () {
+  
+    var content = document.createElement('div')
+    content.classList.add(CONTENT_CLASS)
+    this.node.appendChild(content)
+  
+    var msg = document.createElement('div')
+    msg.classList.add(MSG_CLASS)
+    msg.appendChild(document.createTextNode(this.msg))
+    content.appendChild(msg)
+  
+    var inputWrap = document.createElement('div')
+    inputWrap.classList.add(INPUT_WRAP_CLASS)
+    content.appendChild(inputWrap)
+    var input = document.createElement('input')
+    input.classList.add(INPUT_CLASS)
+    input.type = 'text'
+    input.autofocus = true
+    input.placeholder = this.defaultMsg
+    inputWrap.appendChild(input)
+  
+    var buttonGroup = document.createElement('div')
+    buttonGroup.classList.add(BUTTON_GROUP_CLASS)
+    var btnOk = document.createElement('div')
+    btnOk.appendChild(document.createTextNode(this.okTitle))
+    btnOk.classList.add('btn-ok', BUTTON_CLASS)
+    var btnCancel = document.createElement('div')
+    btnCancel.appendChild(document.createTextNode(this.cancelTitle))
+    btnCancel.classList.add('btn-cancel', BUTTON_CLASS)
+    buttonGroup.appendChild(btnOk)
+    buttonGroup.appendChild(btnCancel)
+    this.node.appendChild(buttonGroup)
+  }
+  
+  Prompt.prototype.bindEvents = function () {
+    Modal.prototype.bindEvents.call(this)
+    var btnOk = this.node.querySelector('.' + BUTTON_CLASS + '.btn-ok')
+    var btnCancel = this.node.querySelector('.' + BUTTON_CLASS + '.btn-cancel')
+    var that = this
+    btnOk.addEventListener('click', function () {
+      var val = document.querySelector('input').value
+      this.destroy()
+      this.callback && this.callback({
+        result: that.okTitle,
+        data: val
+      })
+    }.bind(this))
+    btnCancel.addEventListener('click', function () {
+      var val = document.querySelector('input').value
+      this.destroy()
+      this.callback && this.callback({
+        result: that.cancelTitle
+      })
+    }.bind(this))
+  }
+  
+  module.exports = Prompt
+
+
+/***/ },
+/* 90 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(91);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./prompt.scss", function() {
+        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./prompt.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 91 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".amfe-prompt .input-wrap {\n  box-sizing: border-box;\n  width: 100%;\n  padding: 0.24rem 0.213333rem 0.213333rem;\n  height: 0.96rem; }\n  .amfe-prompt .input-wrap .input {\n    box-sizing: border-box;\n    width: 100%;\n    height: 0.56rem;\n    line-height: 0.56rem;\n    font-size: 0.32rem; }\n\n.amfe-prompt .btn-group .btn {\n  float: left;\n  width: 50%; }\n  .amfe-prompt .btn-group .btn.btn-ok {\n    border-right: 1px solid #ddd; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/prompt.scss"],"names":[],"mappings":"AAAA;EAGI,uBAAuB;EACvB,YAAY;EACZ,yCAAyC;EACzC,gBAAgB,EASjB;EAfH;IASM,uBAAuB;IACvB,YAAY;IACZ,gBAAgB;IAChB,qBAAqB;IACrB,mBAAmB,EACpB;;AAdL;EAoBM,YAAY;EACZ,WAAW,EAKZ;EA1BL;IAwBQ,6BAA6B,EAC9B","file":"prompt.scss","sourcesContent":[".amfe-prompt {\n\n  .input-wrap {\n    box-sizing: border-box;\n    width: 100%;\n    padding: 0.24rem 0.213333rem 0.213333rem; // 18px 16px 16px\n    height: 0.96rem; // 74px\n\n    .input {\n      box-sizing: border-box;\n      width: 100%;\n      height: 0.56rem; // 42px\n      line-height: 0.56rem; // 42px\n      font-size: 0.32rem; // 24px\n    }\n  }\n\n  .btn-group {\n\n    .btn {\n      float: left;\n      width: 50%;\n\n      &.btn-ok {\n        border-right: 1px solid #ddd;\n      }\n    }\n  }\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 92 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  __webpack_require__(93)
+  
+  var queue = []
+  var timer
+  var isProcessing = false
+  var toastWin
+  var TOAST_WIN_CLASS_NAME = 'amfe-toast'
+  
+  var DEFAULT_DURATION = 0.8
+  
+  function showToastWindow(msg, callback) {
+    var handleTransitionEnd = function () {
+      toastWin.removeEventListener('transitionend', handleTransitionEnd)
+      callback && callback()
+    }
+    if (!toastWin) {
+      toastWin = document.createElement('div')
+      toastWin.classList.add(TOAST_WIN_CLASS_NAME, 'hide')
+      document.body.appendChild(toastWin)
+    }
+    toastWin.innerHTML = msg
+    toastWin.addEventListener('transitionend', handleTransitionEnd)
+    setTimeout(function () {
+      toastWin.classList.remove('hide')
+    }, 0)
+  }
+  
+  function hideToastWindow(callback) {
+    var handleTransitionEnd = function () {
+      toastWin.removeEventListener('transitionend', handleTransitionEnd)
+      callback && callback()
+    }
+    if (!toastWin) {
+      return
+    }
+    toastWin.addEventListener('transitionend', handleTransitionEnd)
+    toastWin.classList.add('hide')
+  }
+  
+  var toast = {
+  
+    push: function (msg, duration) {
+      queue.push({
+        msg: msg,
+        duration: duration || DEFAULT_DURATION
+      })
+      this.show()
+    },
+  
+    show: function () {
+      var that = this
+  
+      // All messages had been toasted already, so remove the toast window,
+      if (!queue.length) {
+        toastWin && toastWin.parentNode.removeChild(toastWin)
+        toastWin = null
+        return
+      }
+  
+      // the previous toast is not ended yet.
+      if (isProcessing) {
+        return
+      }
+      isProcessing = true
+  
+      var toastInfo = queue.shift()
+      showToastWindow(toastInfo.msg, function () {
+        timer = setTimeout(function () {
+          timer = null
+          hideToastWindow(function () {
+            isProcessing = false
+            that.show()
+          })
+        }, toastInfo.duration * 1000)
+      })
+    }
+  
+  }
+  
+  module.exports = {
+    push: toast.push.bind(toast)
+  }
+
+
+/***/ },
+/* 93 */
+/***/ function(module, exports, __webpack_require__) {
+
+  // style-loader: Adds some css to the DOM by adding a <style> tag
+  
+  // load the styles
+  var content = __webpack_require__(94);
+  if(typeof content === 'string') content = [[module.id, content, '']];
+  // add the styles to the DOM
+  var update = __webpack_require__(4)(content, {});
+  if(content.locals) module.exports = content.locals;
+  // Hot Module Replacement
+  if(false) {
+    // When the styles change, update the <style> tags
+    if(!content.locals) {
+      module.hot.accept("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./toast.scss", function() {
+        var newContent = require("!!./../../css-loader/index.js?sourceMap!./../../sass-loader/index.js?sourceMap!./toast.scss");
+        if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
+        update(newContent);
+      });
+    }
+    // When the module is disposed, remove the <style> tags
+    module.hot.dispose(function() { update(); });
+  }
+
+/***/ },
+/* 94 */
+/***/ function(module, exports, __webpack_require__) {
+
+  exports = module.exports = __webpack_require__(3)();
+  // imports
+  
+  
+  // module
+  exports.push([module.id, ".amfe-toast {\n  font-size: 0.32rem;\n  line-height: 0.426667rem;\n  position: fixed;\n  box-sizing: border-box;\n  max-width: 80%;\n  bottom: 2.666667rem;\n  left: 50%;\n  padding: 0.213333rem;\n  background-color: #000;\n  color: #fff;\n  text-align: center;\n  opacity: 0.6;\n  transition: all 0.4s ease-in-out;\n  border-radius: 0.066667rem;\n  -webkit-transform: translateX(-50%);\n  transform: translateX(-50%); }\n\n.amfe-toast.hide {\n  opacity: 0; }\n", "", {"version":3,"sources":["/./node_modules/modals/node_modules/modals/styles/toast.scss"],"names":[],"mappings":"AAAA;EACC,mBAAmB;EACnB,yBAAyB;EACzB,gBAAgB;EAChB,uBAAuB;EACvB,eAAe;EACf,oBAAoB;EACpB,UAAU;EACV,qBAAqB;EACrB,uBAAuB;EACvB,YAAY;EACZ,mBAAmB;EACnB,aAAa;EACb,iCAAiC;EACjC,2BAA2B;EAC3B,oCAA6B;EAC5B,4BAAqB,EACtB;;AAED;EACC,WAAW,EACX","file":"toast.scss","sourcesContent":[".amfe-toast {\n\tfont-size: 0.32rem; // 24px\n\tline-height: 0.426667rem; // 32px\n\tposition: fixed;\n\tbox-sizing: border-box;\n\tmax-width: 80%;\n\tbottom: 2.666667rem; // 200px\n\tleft: 50%;\n\tpadding: 0.213333rem; // 16px\n\tbackground-color: #000;\n\tcolor: #fff;\n\ttext-align: center;\n\topacity: 0.6;\n\ttransition: all 0.4s ease-in-out;\n\tborder-radius: 0.066667rem; // 5px\n\t-webkit-transform: translateX(-50%);\n  transform: translateX(-50%);\n}\n\n.amfe-toast.hide {\n\topacity: 0;\n}"],"sourceRoot":"webpack://"}]);
+  
+  // exports
+
+
+/***/ },
+/* 95 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict'
+  
+  var Sender = __webpack_require__(19)
+  
+  var _data = {}
+  
+  var animation = {
+  
+    /**
+     * transition
+     * @param  {string} ref        [description]
+     * @param  {obj} config     [description]
+     * @param  {string} callbackId [description]
+     */
+    transition: function (ref, config, callbackId) {
+      var refData = _data[ref]
+      var stylesKey = JSON.stringify(config.styles)
+      var weexInstance = this
+      // If the same component perform a animation with exactly the same
+      // styles in a sequence with so short interval that the prev animation
+      // is still in playing, then the next animation should be ignored.
+      if (refData && refData[stylesKey]) {
+        return
+      }
+      if (!refData) {
+        refData = _data[ref] = {}
+      }
+      refData[stylesKey] = true
+      return this.getComponentManager().transition(ref, config, function () {
+        // Remove the stylesKey in refData so that the same animation
+        // can be played again after current animation is already finished.
+        delete refData[stylesKey]
+        weexInstance.sender.performCallback(callbackId)
+      })
+    }
+  
+  }
+  
+  animation._meta = {
+    animation: [{
+      name: 'transition',
+      args: ['string', 'object', 'string']
+    }]
+  }
+  
+  module.exports = animation
+
+
+/***/ },
+/* 96 */
+/***/ function(module, exports) {
+
+  (typeof window === 'undefined') && (window = {ctrl: {}, lib: {}});!window.ctrl && (window.ctrl = {});!window.lib && (window.lib = {});!function(a,b){function c(a){Object.defineProperty(this,"val",{value:a.toString(),enumerable:!0}),this.gt=function(a){return c.compare(this,a)>0},this.gte=function(a){return c.compare(this,a)>=0},this.lt=function(a){return c.compare(this,a)<0},this.lte=function(a){return c.compare(this,a)<=0},this.eq=function(a){return 0===c.compare(this,a)}}b.env=b.env||{},c.prototype.toString=function(){return this.val},c.prototype.valueOf=function(){for(var a=this.val.split("."),b=[],c=0;c<a.length;c++){var d=parseInt(a[c],10);isNaN(d)&&(d=0);var e=d.toString();e.length<5&&(e=Array(6-e.length).join("0")+e),b.push(e),1===b.length&&b.push(".")}return parseFloat(b.join(""))},c.compare=function(a,b){a=a.toString().split("."),b=b.toString().split(".");for(var c=0;c<a.length||c<b.length;c++){var d=parseInt(a[c],10),e=parseInt(b[c],10);if(window.isNaN(d)&&(d=0),window.isNaN(e)&&(e=0),e>d)return-1;if(d>e)return 1}return 0},b.version=function(a){return new c(a)}}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c=a.location.search.replace(/^\?/,"");if(b.env.params={},c)for(var d=c.split("&"),e=0;e<d.length;e++){d[e]=d[e].split("=");try{b.env.params[d[e][0]]=decodeURIComponent(d[e][1])}catch(f){b.env.params[d[e][0]]=d[e][1]}}}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c,d=a.navigator.userAgent;if(c=d.match(/Windows\sPhone\s(?:OS\s)?([\d\.]+)/))b.env.os={name:"Windows Phone",isWindowsPhone:!0,version:c[1]};else if(d.match(/Safari/)&&(c=d.match(/Android[\s\/]([\d\.]+)/)))b.env.os={version:c[1]},d.match(/Mobile\s+Safari/)?(b.env.os.name="Android",b.env.os.isAndroid=!0):(b.env.os.name="AndroidPad",b.env.os.isAndroidPad=!0);else if(c=d.match(/(iPhone|iPad|iPod)/)){var e=c[1];c=d.match(/OS ([\d_\.]+) like Mac OS X/),b.env.os={name:e,isIPhone:"iPhone"===e||"iPod"===e,isIPad:"iPad"===e,isIOS:!0,version:c[1].split("_").join(".")}}else b.env.os={name:"unknown",version:"0.0.0"};b.version&&(b.env.os.version=b.version(b.env.os.version))}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c,d=a.navigator.userAgent;(c=d.match(/(?:UCWEB|UCBrowser\/)([\d\.]+)/))?b.env.browser={name:"UC",isUC:!0,version:c[1]}:(c=d.match(/MQQBrowser\/([\d\.]+)/))?b.env.browser={name:"QQ",isQQ:!0,version:c[1]}:(c=d.match(/Firefox\/([\d\.]+)/))?b.env.browser={name:"Firefox",isFirefox:!0,version:c[1]}:(c=d.match(/MSIE\s([\d\.]+)/))||(c=d.match(/IEMobile\/([\d\.]+)/))?(b.env.browser={version:c[1]},d.match(/IEMobile/)?(b.env.browser.name="IEMobile",b.env.browser.isIEMobile=!0):(b.env.browser.name="IE",b.env.browser.isIE=!0),d.match(/Android|iPhone/)&&(b.env.browser.isIELikeWebkit=!0)):(c=d.match(/(?:Chrome|CriOS)\/([\d\.]+)/))?(b.env.browser={name:"Chrome",isChrome:!0,version:c[1]},d.match(/Version\/[\d+\.]+\s*Chrome/)&&(b.env.browser.name="Chrome Webview",b.env.browser.isWebview=!0)):d.match(/Safari/)&&(c=d.match(/Android[\s\/]([\d\.]+)/))?b.env.browser={name:"Android",isAndroid:!0,version:c[1]}:d.match(/iPhone|iPad|iPod/)?d.match(/Safari/)?(c=d.match(/Version\/([\d\.]+)/),b.env.browser={name:"Safari",isSafari:!0,version:c[1]}):(c=d.match(/OS ([\d_\.]+) like Mac OS X/),b.env.browser={name:"iOS Webview",isWebview:!0,version:c[1].replace(/\_/g,".")}):b.env.browser={name:"unknown",version:"0.0.0"},b.version&&(b.env.browser.version=b.version(b.env.browser.version))}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c=a.navigator.userAgent;c.match(/Weibo/i)?b.env.thirdapp={appname:"Weibo",isWeibo:!0}:c.match(/MicroMessenger/i)?b.env.thirdapp={appname:"Weixin",isWeixin:!0}:b.env.thirdapp=!1}(window,window.lib||(window.lib={})),function(a,b){b.env=b.env||{};var c,d,e=a.navigator.userAgent;(d=e.match(/WindVane[\/\s]([\d\.\_]+)/))&&(c=d[1]);var f=!1,g="",h="",i="";(d=e.match(/AliApp\(([A-Z\-]+)\/([\d\.]+)\)/i))&&(f=!0,g=d[1],i=d[2],h=g.indexOf("-PD")>0?b.env.os.isIOS?"iPad":b.env.os.isAndroid?"AndroidPad":b.env.os.name:b.env.os.name),!g&&e.indexOf("TBIOS")>0&&(g="TB"),f?b.env.aliapp={windvane:b.version(c||"0.0.0"),appname:g||"unkown",version:b.version(i||"0.0.0"),platform:h||b.env.os.name}:b.env.aliapp=!1,b.env.taobaoApp=b.env.aliapp}(window,window.lib||(window.lib={}));;module.exports = window.lib['env'];
+
+/***/ }
+/******/ ]);
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgOTZlMGFmY2M2NTc2OTAzNzZlNTQiLCJ3ZWJwYWNrOi8vLy4vc3JjL3dlZXguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3N0eWxlcy9iYXNlLnNjc3M/YzJlZSIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL2Jhc2Uuc2NzcyIsIndlYnBhY2s6Ly8vLi9+L2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzIiwid2VicGFjazovLy8uL34vc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29uZmlnLmpzIiwid2VicGFjazovLy8uL3NyYy9sb2FkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3V0aWxzLmpzIiwid2VicGFjazovLy8uL3NyYy9wcm90b2NvbC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50TWFuYWdlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvZnJhbWVVcGRhdGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9hcHBlYXJXYXRjaGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9sYXp5TG9hZC5qcyIsIndlYnBhY2s6Ly8vLi9+L2xhenlpbWcvYnVpbGQvaW1nLmNvbW1vbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2FwcGVhcmpzL2J1aWxkL2FwcGVhci5jb21tb24uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FuaW1hdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9jb21wb25lbnQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2ZsZXhib3guanMiLCJ3ZWJwYWNrOi8vLy4vfi9maXhlZHN0aWNreS9idWlsZC9zdGlja3kuY29tbW9uLmpzIiwid2VicGFjazovLy8uL3NyYy9icmlkZ2Uvc2VuZGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9icmlkZ2UvcmVjZWl2ZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvcm9vdC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9jb250YWluZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3N0eWxlcy9jb250YWluZXIuc2Nzcz9kNmI0Iiwid2VicGFjazovLy8uL3NyYy9zdHlsZXMvY29udGFpbmVyLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvaW1hZ2UuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvYXRvbWljLmpzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL3RleHQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvbGlzdC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL2xpc3Quc2Nzcz9iZDk2Iiwid2VicGFjazovLy8uL3NyYy9zdHlsZXMvbGlzdC5zY3NzIiwid2VicGFjazovLy8uL34vc2Nyb2xsanMvYnVpbGQvc2Nyb2xsLmNvbW1vbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2FuaW1hdGlvbmpzL2J1aWxkL2FuaW1hdGlvbi5jb21tb24uanMiLCJ3ZWJwYWNrOi8vLy4vfi9jdWJpY2Jlemllci9idWlsZC9jdWJpY2Jlemllci5jb21tb24uanMiLCJ3ZWJwYWNrOi8vLy4vfi9nZXN0dXJlanMvYnVpbGQvZ2VzdHVyZWpzLmNvbW1vbi5qcyIsIndlYnBhY2s6Ly8vLi9+L21vdGlvbmpzL2J1aWxkL21vdGlvbi5jb21tb24uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvY291bnRkb3duLmpzIiwid2VicGFjazovLy8uL34va291bnRkb3duL2J1aWxkL2NvdW50ZG93bi5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9tYXJxdWVlLmpzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL3NsaWRlci5qcyIsIndlYnBhY2s6Ly8vLi9+L2NhcnJvdXNlbC9idWlsZC9jYXJyb3VzZWwuY29tbW9uLmpzIiwid2VicGFjazovLy8uL3NyYy9zdHlsZXMvc2xpZGVyLnNjc3M/NDM0YSIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3NsaWRlci5zY3NzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL2luZGljYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL2luZGljYXRvci5zY3NzPzQ0NmYiLCJ3ZWJwYWNrOi8vLy4vc3JjL3N0eWxlcy9pbmRpY2F0b3Iuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy90YWJoZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL21lc3NhZ2VRdWV1ZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3RhYmhlYWRlci5zY3NzP2Y1YTgiLCJ3ZWJwYWNrOi8vLy4vc3JjL3N0eWxlcy90YWJoZWFkZXIuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9zY3JvbGxlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3Njcm9sbGVyLnNjc3M/NjYzZCIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3Njcm9sbGVyLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvaW5wdXQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvc2VsZWN0LmpzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL2RhdGVwaWNrZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvdGltZXBpY2tlci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWRlby5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3ZpZGVvLnNjc3M/YjFmYSIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3ZpZGVvLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvc3dpdGNoLmpzIiwid2VicGFjazovLy8uL3NyYy9zdHlsZXMvc3dpdGNoLnNjc3M/ZjY5OCIsIndlYnBhY2s6Ly8vLi9zcmMvc3R5bGVzL3N3aXRjaC5zY3NzIiwid2VicGFjazovLy8uL3NyYy9jb21wb25lbnRzL2EuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NvbXBvbmVudHMvZW1iZWQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwaS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBpL2RvbS5qcyIsIndlYnBhY2s6Ly8vLi9+L3Njcm9sbC10by9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvbXBvbmVudC10d2Vlbi9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvbXBvbmVudC1lbWl0dGVyL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vY29tcG9uZW50LWNsb25lL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vY29tcG9uZW50LXR5cGUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9lYXNlLWNvbXBvbmVudC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvbXBvbmVudC1yYWYvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2FwaS9ldmVudC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXBpL3BhZ2VJbmZvLmpzIiwid2VicGFjazovLy8uL3NyYy9hcGkvc3RyZWFtLmpzIiwid2VicGFjazovLy8uL3NyYy9hcGkvbW9kYWwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9tb2RhbHMvc3JjL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3NyYy9hbGVydC5qcyIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zcmMvbW9kYWwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9tb2RhbHMvc3R5bGVzL21vZGFsLnNjc3M/ZGE0OCIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zdHlsZXMvbW9kYWwuc2NzcyIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zdHlsZXMvYWxlcnQuc2Nzcz81NzgyIiwid2VicGFjazovLy8uL34vbW9kYWxzL3N0eWxlcy9hbGVydC5zY3NzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3NyYy9jb25maXJtLmpzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3N0eWxlcy9jb25maXJtLnNjc3M/ZDY0YSIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zdHlsZXMvY29uZmlybS5zY3NzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3NyYy9wcm9tcHQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9tb2RhbHMvc3R5bGVzL3Byb21wdC5zY3NzPzdlMWMiLCJ3ZWJwYWNrOi8vLy4vfi9tb2RhbHMvc3R5bGVzL3Byb21wdC5zY3NzIiwid2VicGFjazovLy8uL34vbW9kYWxzL3NyYy90b2FzdC5qcyIsIndlYnBhY2s6Ly8vLi9+L21vZGFscy9zdHlsZXMvdG9hc3Quc2Nzcz9hNjBmIiwid2VicGFjazovLy8uL34vbW9kYWxzL3N0eWxlcy90b2FzdC5zY3NzIiwid2VicGFjazovLy8uL3NyYy9hcGkvYW5pbWF0aW9uLmpzIiwid2VicGFjazovLy8uL34vZW52ZC9idWlsZC9lbnZkLmNvbW1vbi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVCQUFlO0FBQ2Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7QUN0Q0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0EsSUFBRzs7QUFFSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTCxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTCxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUTs7QUFFUixJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBQzs7QUFFRDtBQUNBO0FBQ0E7O0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDakdBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBc0MsT0FBTztBQUM3QztBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsZ0JBQWU7O0FBRWY7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQSxJQUFHO0FBQ0gsRUFBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSCxFQUFDOztBQUVE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Q0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esc0JBQXFCLHFCQUFxQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDaFpBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0wsSUFBRzs7QUFFSDtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUMvQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1B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Q0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBcUIscUJBQXFCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTCxnQ0FBK0IsT0FBTztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW1DLE9BQU87QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0EsVUFBUztBQUNU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d0I7Ozs7OztBQ25EQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7Ozs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRCOzs7Ozs7QUM3Q0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7Ozs7Ozs7QUN4Q0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7Ozs7Ozs7QUNiQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFtRjtBQUNuRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLGlDQUFnQyxVQUFVLEVBQUU7QUFDNUMsRTs7Ozs7O0FDcEJBO0FBQ0E7OztBQUdBO0FBQ0EsNENBQTJDLDJCQUEyQix5QkFBeUIsMEJBQTBCLGtCQUFrQixpQ0FBaUMsbUNBQW1DLDJCQUEyQix1QkFBdUIsMEJBQTBCLGNBQWMsZUFBZSxFQUFFLG1CQUFtQiwyQkFBMkIsdUJBQXVCLEVBQUUsVUFBVSx1RkFBdUYsWUFBWSxhQUFhLGFBQWEsV0FBVyxZQUFZLGFBQWEsYUFBYSxhQUFhLGFBQWEsV0FBVyxnQkFBZ0IsS0FBSyxZQUFZLGdGQUFnRiwwQkFBMEIsd0JBQXdCLHlCQUF5QixpQkFBaUIsZ0NBQWdDLGtDQUFrQywwQkFBMEIsc0JBQXNCLHlCQUF5QixhQUFhLGdCQUFnQixtQkFBbUIsMkJBQTJCLHVCQUF1QixHQUFHLDZCQUE2Qjs7QUFFeGpDOzs7Ozs7O0FDUEE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDeERBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQzVCQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXFDO0FBQ3JDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFtQztBQUNuQztBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHVCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxFQUFDOztBQUVEOzs7Ozs7O0FDdkZBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQSxNQUFLO0FBQ0wsSUFBRzs7QUFFSDtBQUNBO0FBQ0EsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0gsa0NBQWlDLE9BQU87QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWlDLE9BQU87QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDdkhBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQW1GO0FBQ25GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0EsaUNBQWdDLFVBQVUsRUFBRTtBQUM1QyxFOzs7Ozs7QUNwQkE7QUFDQTs7O0FBR0E7QUFDQSx1Q0FBc0MsbUJBQW1CLHFCQUFxQixFQUFFLG1CQUFtQixpQ0FBaUMsbUNBQW1DLDJCQUEyQixFQUFFLFVBQVUsa0ZBQWtGLFVBQVUsbUJBQW1CLEtBQUssWUFBWSxhQUFhLHNFQUFzRSxtQkFBbUIscUJBQXFCLEdBQUcsbUJBQW1CLGlDQUFpQyxtQ0FBbUMsMkJBQTJCLEdBQUcsNkJBQTZCOztBQUU5bEI7Ozs7Ozs7QUNQQSwrQ0FBOEMsUUFBUSxVQUFVLEVBQUUsaUNBQWlDLEVBQUUsK0JBQStCLEVBQUUsd0JBQXVCLHdCQUF1Qix3QkFBcUIsd0JBQW9CLGlCQUFpQixhQUFhLGdFQUFnRSxjQUFjLGdDQUFnQyxPQUFPLElBQUkscUZBQXFGLHlCQUF5QixFQUFFLDBEQUEwRCwrQ0FBK0MsU0FBUyxjQUFjLHdDQUF3QyxjQUFjLDBDQUEwQywwQ0FBMEMsNkJBQTZCLHVEQUF1RCxnQkFBZ0IsOEZBQThGLGdCQUFnQiw0RkFBNEYsa0JBQWtCLDBCQUEwQixrQ0FBa0MsaUVBQWlFLHVEQUF1RCxjQUFjLFNBQVMsUUFBUSw4Q0FBOEMseURBQXlELEdBQUcsc0NBQXNDLEVBQUUsd0NBQXdDLEVBQUUsa0ZBQWtGLGdCQUFnQixrSUFBa0ksa0JBQWtCLCtHQUErRyxnQkFBZ0IsWUFBWSw0RkFBNEYsZ0JBQWdCLGNBQWMsMkRBQTJELGNBQWMsNEJBQTRCLHlDQUF5Qyx5REFBeUQsTUFBTSxnQkFBZ0IsK0NBQStDLHdDQUF3QyxhQUFhLGNBQWMsdUJBQXVCLHFDQUFxQyx1RUFBdUUsb0JBQW9CLFNBQVMsY0FBYyx5REFBeUQsS0FBSyxXQUFXLDBDQUEwQyxjQUFjLFNBQVMsNEJBQTRCLE1BQU0sYUFBYSx3QkFBd0IsVUFBVSx5REFBeUQseUJBQXlCLHdCQUF3QixzQkFBc0IsS0FBSyxtQkFBbUIsdUVBQXVFLDRFQUE0RSxFQUFFLG9HQUFvRyxhQUFhLGNBQWMsOEpBQThKLGNBQWMsU0FBUyw2Q0FBNkMsbURBQW1ELElBQUksa0NBQWtDLGtLQUFrSyxhQUFhLGtGQUFrRiwyQkFBMkIsc0VBQXNFLGNBQWMsc0JBQXNCLGNBQWMsS0FBSyxzQ0FBc0MsZUFBZSxhQUFhLE9BQU8scUNBQXFDLGdCQUFnQiwySEFBMkgsU0FBUyxnQkFBZ0IsYUFBYSxNQUFNLGtHQUFrRyw2QkFBNkIsUUFBUSw4QkFBOEIsOENBQThDLFNBQVMsZ0JBQWdCLHdCQUF3QiwyREFBMkQsMkRBQTJELGlEQUFpRCxZQUFZLG1DQUFtQyxjQUFjLEVBQUUsc0JBQXNCLEtBQUssbUJBQW1CLHFGQUFxRixTQUFTLDhGQUE4RixrQ0FBa0MscURBQXFELFlBQVksbUNBQW1DLGNBQWMsRUFBRSxxQkFBcUIsY0FBYywrQkFBK0Isd0NBQXdDLFlBQVksbUNBQW1DLGNBQWMsRUFBRSx1QkFBdUIsV0FBVyxLQUFLLG1CQUFtQixnRUFBZ0UsMkRBQTJELG1CQUFtQixtQ0FBbUMsU0FBUyw2QkFBNkIsU0FBUyxLQUFLLGdCQUFnQiw4QkFBOEIsd0JBQXdCLDJEQUEyRCxpREFBaUQseUJBQXlCLHdCQUF3QixjQUFjLEVBQUUsc0JBQXNCLEtBQUssbUJBQW1CLHNGQUFzRiw4REFBOEQsbUNBQW1DLGNBQWMsOENBQThDLEdBQUcsYUFBYSx1Q0FBdUMsd0ZBQXdGLE1BQU0sV0FBVyxVQUFVLGdEQUFnRCxxaEJBQXFoQiw2Q0FBNkMsMkJBQTJCLDRXQUE0VyxLQUFLLHdEQUF3RCxLQUFLLDZCQUE2QixRQUFRLHNEQUFzRCxpREFBaUQsS0FBSyxNQUFNLDZGQUE2Rix3QkFBd0IsTUFBTSx3Q0FBd0MsZUFBZSxVQUFVLEVBQUUsS0FBSyxVQUFVLG1FQUFtRSxNQUFNLFFBQVEsMkRBQTJELEtBQUssR0FBRyxLQUFLLFlBQVksMENBQTBDLGVBQWUsV0FBVyxFQUFFLFNBQVMsZ0JBQWdCLDBEQUEwRCxtQkFBbUIsNEJBQTRCLG9CQUFvQixtQkFBbUIsc0dBQXNHLDBEQUEwRCxPQUFPLDJCQUEyQiw2QkFBNkIsNEJBQTRCLDhCQUE4QiwwQkFBMEIsMENBQTBDLHlCQUF5QiwwQ0FBMEMsNkJBQTZCLGtEQUFrRCw0QkFBNEIsa0RBQWtELDhCQUE4QiwrQ0FBK0Msb0JBQW9CLDBEQUEwRCx5REFBeUQsOEVBQThFLCtCQUErQixtREFBbUQsd0lBQXdJLEtBQUssS0FBSyxxQ0FBcUMsd0JBQXdCLEtBQUssZ0RBQWdELDRCQUE0QiwrREFBK0QsaU5BQWlOLG9CQUFvQiw2QkFBNkIsb0JBQW9CLE9BQU8saUhBQWlILHdCQUF3QixLQUFLLE9BQU8sb0hBQW9ILHVCQUF1QixTQUFTLHFCQUFxQiw4QkFBOEIsb0JBQW9CLE9BQU8sd0ZBQXdGLHdCQUF3QixLQUFLLE9BQU8sMkZBQTJGLHVCQUF1QixTQUFTLHNCQUFzQixvREFBb0Qsb0ZBQW9GLHdCQUF3QixXQUFXLGFBQWEsd0dBQXdHLDRCQUE0Qix5REFBeUQseUJBQXlCLHdCQUF3QixzQkFBc0IsNEVBQTRFLDRFQUE0RSxFQUFFLDJEQUEyRCxZQUFZLCtCQUErQixxQkFBcUIsNERBQTRELHlCQUF5Qiw4QkFBOEIsMEJBQTBCLCtCQUErQixnQ0FBZ0MsV0FBVywrREFBK0Qsa0NBQWtDLHdDQUF3QyxFQUFFLFVBQVUsOEJBQThCLFdBQVcsNkRBQTZELGtDQUFrQywwREFBMEQsRUFBRSxVQUFVLG1DQUFtQyxXQUFXLCtEQUErRCxZQUFZLFVBQVUsaUNBQWlDLFdBQVcsNkRBQTZELFlBQVksVUFBVSxpQ0FBaUMsV0FBVyw2REFBNkQsWUFBWSxVQUFVLHVDQUF1QyxXQUFXLDJEQUEyRCxZQUFZLEtBQUssa0NBQWtDLFdBQVcsNENBQTRDLFlBQVksTUFBTSxtQ0FBbUMsV0FBVywrQ0FBK0MsWUFBWSxFQUFFLDRCQUE0QixXQUFXLHVEQUF1RCwwQkFBMEIsNEJBQTRCLFNBQVMsNkNBQTZDLEtBQUssMEhBQTBILGlFQUFpRSxxTEFBcUwsMkNBQTJDLG9DQUFvQyw0QkFBNEIsbUhBQW1ILEtBQUssc0RBQXNELGlDQUFpQyxtREFBbUQsdUZBQXVGLE1BQU0sMEdBQTBHLCtCQUErQixvREFBb0QsT0FBTyxTQUFTLGtDQUFrQyxJQUFJLHNDOzs7Ozs7QUNBcnVhLCtDQUE4QyxRQUFRLFVBQVUsRUFBRSxpQ0FBaUMsRUFBRSwrQkFBK0IsRUFBRSxlQUFlLGNBQWMsdUJBQXVCLGNBQWMsZ0JBQWdCLGFBQWEsUUFBUSx1QkFBdUIsdUJBQXVCLEVBQUUscUJBQXFCLGdCQUFnQiwyQ0FBMkMsZ0JBQWdCLGdDQUFnQyxJQUFJLGNBQWMsYUFBYSx3QkFBd0IsS0FBSyxnQkFBZ0IsOENBQThDLDhCQUE4QixPQUFPLHdCQUF3QixpREFBaUQsdUJBQXVCLGlCQUFpQixnQkFBZ0IsMEJBQTBCLElBQUksRUFBRSwwREFBMEQsbUJBQW1CLE1BQU0sSUFBSSxLQUFLLGlCQUFpQixzQkFBc0IsY0FBYyxpREFBaUQsNkNBQTZDLFNBQVMsY0FBYyxNQUFNLHVRQUF1USxrQkFBa0Isb0NBQW9DLGtEQUFrRCxTQUFTLHFCQUFxQixhQUFhLGlDQUFpQywwREFBMEQsbUVBQW1FLGFBQWEsRUFBRSx3REFBd0Qsc0JBQXNCLGlEQUFpRCx3VUFBd1Usc0RBQXNELG9CQUFvQiwrQkFBK0IsZ0JBQWdCLHNDQUFzQyxlQUFlLG9CQUFvQixrQ0FBa0MsSUFBSSx5Qzs7Ozs7O0FDQS90RSwrQ0FBOEMsUUFBUSxVQUFVLEVBQUUsaUNBQWlDLEVBQUUsK0JBQStCLEVBQUUsZUFBZSxvQkFBb0IsY0FBYyxzQkFBc0IsY0FBYyxzQkFBc0IsY0FBYyxzQkFBc0IsY0FBYyxvQkFBb0IsSUFBSSxLQUFLLG1DQUFtQyw4QkFBOEIsT0FBTyxZQUFZLFFBQVEsSUFBSSxFQUFFLG1DQUFtQyxzQkFBc0IsU0FBUyxjQUFjLGVBQWUsbUVBQW1FLFNBQVMsK0xBQStMLGtDQUFrQyxJQUFJLDJDOzs7Ozs7QUNBbHpCLCtDQUE4QyxRQUFRLFVBQVUsRUFBRSxpQ0FBaUMsRUFBRSwrQkFBK0IsRUFBRSxhQUFhLGFBQWEsZ0JBQWdCLFlBQVksRUFBRSxFQUFFLGdDQUFnQyxlQUFlLFlBQVksa0JBQWtCLGtDQUFrQyxvRUFBb0UsbUJBQW1CLDRCQUE0Qix1TUFBdU0sT0FBTyxzSEFBc0gsY0FBYyw2SUFBNkksWUFBWSwwQkFBMEIsS0FBSywrQkFBK0IseUJBQXlCLE9BQU8sMkhBQTJILGtCQUFrQiw0REFBNEQsdUVBQXVFLDJEQUEyRCxtREFBbUQsa0JBQWtCLDZCQUE2QixTQUFTLG9DQUFvQyxpQ0FBaUMsdUNBQXVDLEdBQUcsY0FBYyxZQUFZLDBCQUEwQixLQUFLLDRDQUE0QyxhQUFhLGtLQUFrSyx5R0FBeUcseUxBQXlMLG1DQUFtQyxzQkFBc0IsK0dBQStHLHlJQUF5SSwrRkFBK0YsaUVBQWlFLHFCQUFxQixzRUFBc0UsK0hBQStILDhDQUE4QyxxQ0FBcUMsbUNBQW1DLHFDQUFxQyxHQUFHLDZCQUE2Qiw2QkFBNkIsbUJBQW1CLEtBQUsscUNBQXFDLGtGQUFrRixvQ0FBb0MsaUdBQWlHLDJDQUEyQyxHQUFHLGNBQWMsNkJBQTZCLFNBQVMsb0NBQW9DLCtCQUErQix1Q0FBdUMsRUFBRSxZQUFZLDBCQUEwQixLQUFLLGdEQUFnRCxNQUFNLGdKQUFnSixxQkFBcUIsMkRBQTJELHFCQUFxQiw2QkFBNkIsb1FBQW9RLGlNQUFpTSxpSUFBaUksK0NBQStDLHFCQUFxQixlQUFlLHNKQUFzSixjQUFjLDZCQUE2QixTQUFTLG9DQUFvQywrQkFBK0IsdUNBQXVDLEVBQUUsWUFBWSwwQkFBMEIsS0FBSyxnREFBZ0QsNEhBQTRILHVFQUF1RSxpREFBaUQscUJBQXFCLGVBQWUsc0pBQXNKLGlFQUFpRSxRQUFRLHNDQUFzQyxVQUFVLHlDOzs7Ozs7QUNBLzJLLCtDQUE4QyxRQUFRLFVBQVUsRUFBRSxpQ0FBaUMsRUFBRSwrQkFBK0IsRUFBRSxlQUFlLGdCQUFnQixvSEFBb0gsY0FBYywwTEFBMEwsS0FBSywySEFBMkgscUJBQXFCLDBFQUEwRSwyQ0FBMkMsNkNBQTZDLFlBQVksa0NBQWtDLElBQUksc0M7Ozs7OztBQ0ExMEI7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDNURBLGdCQUFlLGNBQWMsTUFBTSx3Q0FBd0MsNEJBQTRCLHNDQUFzQyxTQUFTLHVEQUF1RCxpQkFBaUIsMkJBQTJCLHFHQUFxRyw0QkFBNEIsZ0JBQWdCLDhDQUE4Qyw2QkFBNkIsc0NBQXNDLGdGQUFnRixnREFBZ0QsRUFBRSx3Q0FBd0MsNENBQTRDLGtCQUFrQixRQUFRLDBCQUEwQix1REFBdUQsd01BQXdNLHFDQUFxQyxhQUFhLGlCQUFpQixXQUFXLG1FQUFtRSxZQUFZLGdCQUFnQixvQkFBb0IsMElBQTBJLDRRQUE0USxpQkFBaUIsV0FBVywwRUFBMEUsd0JBQXdCLFdBQVcseUJBQXlCLHlCQUF5QixpQkFBaUIsa0NBQWtDLEc7Ozs7OztBQ0F6MEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdCQUFlLHFCQUFxQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnQkFBZSwyQkFBMkI7QUFDMUMsYUFBWSxnQ0FBZ0M7QUFDNUMsaUJBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7O0FBRUE7QUFDQTtBQUNBLGdCQUFlO0FBQ2YsYUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFtQjtBQUNuQixvQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0EsaUJBQWdCO0FBQ2hCLGlCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUN4UkE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0JBQW1CLHFCQUFxQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUFzQyxPQUFPO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvQkFBbUIscUJBQXFCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVCxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFvQyxPQUFPO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEscUNBQW9DLGVBQWU7QUFDbkQsTUFBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDclNBLCtDQUE4QyxRQUFRLFVBQVUsRUFBRSxpQ0FBaUMsRUFBRSwrQkFBK0IsRUFBRSx3QkFBdUIsd0JBQXVCLHdCQUFxQixZQUFZLGtDQUFrQyxrQkFBa0Isa0NBQWtDLDhCQUE4QiwwQkFBMEIsb0NBQW9DLHdIQUF3SCxTQUFTLGNBQWMsU0FBUyxlQUFlLEdBQUcsaUJBQWlCLGNBQWMsU0FBUyxRQUFRLHNDQUFzQyx5REFBeUQsR0FBRyxzQ0FBc0MsRUFBRSx3Q0FBd0MsRUFBRSxrRkFBa0YsZ0JBQWdCLGtJQUFrSSxjQUFjLGlCQUFpQixnQkFBZ0IsZ0JBQWdCLGtDQUFrQyxtREFBbUQsbUJBQW1CLGNBQWMsS0FBSyxJQUFJLE1BQU0sS0FBSyxLQUFLLE1BQU0sU0FBUyxjQUFjLFVBQVUsbUJBQW1CLGlKQUFpSixnQ0FBZ0MsR0FBRyxxRUFBcUUsOElBQThJLHlJQUF5SSxZQUFZLG1EQUFtRCxrQkFBa0IsbUNBQW1DLDJMQUEyTCxlQUFlLFVBQVUsUUFBUSxtQkFBbUIsZUFBZSx5QkFBeUIsa0JBQWtCLG1CQUFtQixNQUFNLGVBQWUsMENBQTBDLG9FQUFvRSxJQUFJLHFDQUFxQywrREFBK0QsMEdBQTBHLHFCQUFxQixVQUFVLGFBQWEsNEJBQTRCLFVBQVUscURBQXFELGtDQUFrQyx5QkFBeUIsNENBQTRDLElBQUksbUJBQW1CLFdBQVcsbUJBQW1CLFlBQVksaURBQWlELGtJQUFrSSxlQUFlLFVBQVUsTUFBTSxzQ0FBc0MsZUFBZSxVQUFVLG9DQUFvQyxlQUFlLFVBQVUsbUNBQW1DLGVBQWUsVUFBVSxrQ0FBa0MsZUFBZSxTQUFTLGlCQUFpQixLQUFLLEVBQUUsbUJBQW1CLHFCQUFxQiwwQ0FBMEMsb0NBQW9DLEtBQUssMkNBQTJDLHNCQUFzQixzQkFBc0IsMENBQTBDLEtBQUssUUFBUSxjQUFjLHVDQUF1QyxlQUFlLFNBQVMsaUJBQWlCLDBEQUEwRCxTQUFTLGdCQUFnQiw2QkFBNkIsV0FBVyw4Q0FBOEMsZUFBZSxTQUFTLGlCQUFpQixLQUFLLHlEQUF5RCxXQUFXLDBDQUEwQyxrRkFBa0YsMkNBQTJDLDZHQUE2RywwQ0FBMEMscUtBQXFLLFNBQVMsT0FBTyw0Q0FBNEMsdURBQXVELEVBQUUsb0NBQW9DLG1DQUFtQyx3Q0FBd0Msc0NBQXNDLDRCQUE0QixvTkFBb04sY0FBYywrQ0FBK0MsSUFBSSx5Qzs7Ozs7O0FDQWo4Sjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFtRjtBQUNuRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLGlDQUFnQyxVQUFVLEVBQUU7QUFDNUMsRTs7Ozs7O0FDcEJBO0FBQ0E7OztBQUdBO0FBQ0Esb0NBQW1DLHVCQUF1QixFQUFFLGtDQUFrQyx1QkFBdUIseUJBQXlCLDBCQUEwQixrQkFBa0IsOEJBQThCLHNCQUFzQixnQ0FBZ0Msd0JBQXdCLDZCQUE2QixxQkFBcUIsb0NBQW9DLDRCQUE0QixpQkFBaUIsRUFBRSw2Q0FBNkMseUJBQXlCLEVBQUUsc0NBQXNDLHFDQUFxQyw2QkFBNkIsa0NBQWtDLDBCQUEwQixFQUFFLHlDQUF5QyxtQ0FBbUMsMkJBQTJCLHFDQUFxQyw2QkFBNkIsRUFBRSxVQUFVLG9GQUFvRixtQkFBbUIsS0FBSyxZQUFZLGFBQWEsYUFBYSxXQUFXLFlBQVksYUFBYSxhQUFhLGFBQWEsYUFBYSxhQUFhLGFBQWEsYUFBYSxpQkFBaUIsTUFBTSxtQkFBbUIsTUFBTSxhQUFhLGFBQWEsYUFBYSxtQkFBbUIsTUFBTSxhQUFhLGFBQWEsYUFBYSxxRUFBcUUsdUJBQXVCLEdBQUcsZ0NBQWdDLHVCQUF1Qix5QkFBeUIsMEJBQTBCLGtCQUFrQiw4QkFBOEIsc0JBQXNCLGdDQUFnQyx3QkFBd0IsNkJBQTZCLHFCQUFxQixvQ0FBb0MsNEJBQTRCLGlCQUFpQixrQkFBa0IseUJBQXlCLEtBQUssYUFBYSxxQ0FBcUMsNkJBQTZCLGtDQUFrQywwQkFBMEIsS0FBSyxnQkFBZ0IsbUNBQW1DLDJCQUEyQixxQ0FBcUMsNkJBQTZCLEtBQUssS0FBSyw2QkFBNkI7O0FBRTFpRTs7Ozs7OztBQ1BBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGtCQUFpQixpQkFBaUI7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTBDLE9BQU87QUFDakQ7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMEMsT0FBTztBQUNqRDtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQ3RLQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFtRjtBQUNuRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLGlDQUFnQyxVQUFVLEVBQUU7QUFDNUMsRTs7Ozs7O0FDcEJBO0FBQ0E7OztBQUdBO0FBQ0EsNkNBQTRDLHVCQUF1Qix3QkFBd0IsRUFBRSxzQ0FBc0Msa0JBQWtCLHlCQUF5QixFQUFFLFVBQVUsdUZBQXVGLFlBQVksbUJBQW1CLEtBQUssVUFBVSxnRkFBZ0YsdUJBQXVCLHdCQUF3Qix1QkFBdUIsa0JBQWtCLHlCQUF5QixLQUFLLEtBQUssNkJBQTZCOztBQUV2aUI7Ozs7Ozs7QUNQQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBMkI7QUFDM0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0NBQWlDLGNBQWM7QUFDL0MsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsSUFBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHVEQUFzRCxPQUFPO0FBQzdELGNBQWEsVUFBVSxXQUFXOztBQUVsQztBQUNBLHNDQUFxQyxPQUFPO0FBQzVDO0FBQ0EsZ0NBQStCLFFBQVE7QUFDdkMsUUFBTztBQUNQLGdDQUErQixRQUFRO0FBQ3ZDOztBQUVBLDhCQUE2QixXQUFXOztBQUV4QztBQUNBLE1BQUs7O0FBRUw7QUFDQSxJQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7Ozs7OztBQzVYQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7Ozs7OztBQzVCQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFtRjtBQUNuRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLGlDQUFnQyxVQUFVLEVBQUU7QUFDNUMsRTs7Ozs7O0FDcEJBO0FBQ0E7OztBQUdBO0FBQ0Esd0NBQXVDLHVCQUF1QixpQkFBaUIsb0JBQW9CLGdCQUFnQixFQUFFLDZCQUE2QixzQkFBc0IsMkJBQTJCLG9CQUFvQixrQkFBa0IsMkJBQTJCLEVBQUUsOEJBQThCLDRCQUE0Qix1QkFBdUIseUJBQXlCLEVBQUUsbURBQW1ELGlCQUFpQixrQkFBa0IseUJBQXlCLEVBQUUsOEJBQThCLHlCQUF5QixtQkFBbUIsMENBQTBDLHFCQUFxQixxQkFBcUIsc0JBQXNCLDJCQUEyQix5QkFBeUIsa0JBQWtCLHNCQUFzQixFQUFFLCtCQUErQixpQ0FBaUMsYUFBYSxjQUFjLHVCQUF1QixFQUFFLGdCQUFnQixxQkFBcUIsd0JBQXdCLG9CQUFvQix5QkFBeUIsRUFBRSx5QkFBeUIsNEJBQTRCLHlCQUF5Qiw0QkFBNEIsRUFBRSx5QkFBeUIsb0JBQW9CLHFCQUFxQiwwQkFBMEIseUJBQXlCLHlCQUF5QixlQUFlLDBDQUEwQyxvQkFBb0Isc0JBQXNCLEVBQUUsZ0NBQWdDLG1CQUFtQixFQUFFLGlDQUFpQyx1REFBdUQsRUFBRSxpQ0FBaUMsb0JBQW9CLHFCQUFxQixFQUFFLCtCQUErQixtQkFBbUIsaUJBQWlCLEVBQUUsNkJBQTZCLDJCQUEyQixnQkFBZ0Isb0JBQW9CLG9CQUFvQix5QkFBeUIsRUFBRSw2QkFBNkIsb0JBQW9CLHVCQUF1QixFQUFFLG1DQUFtQyxtQkFBbUIsZ0JBQWdCLGlCQUFpQix5Q0FBeUMsRUFBRSxxQkFBcUIsa0JBQWtCLG9CQUFvQixZQUFZLFdBQVcsRUFBRSxnQkFBZ0IsOEJBQThCLDJDQUEyQyxjQUFjLHc2TkFBdzZOLEVBQUUsZUFBZSxxQ0FBcUMsb0JBQW9CLHVCQUF1Qix3Q0FBd0MscUNBQXFDLHVDQUF1QyxFQUFFLGtDQUFrQyxvQkFBb0IsRUFBRSxrQ0FBa0Msb0JBQW9CLEVBQUUsMENBQTBDLG9CQUFvQixFQUFFLDBDQUEwQyxvQkFBb0IsRUFBRSwrQ0FBK0Msb0JBQW9CLEVBQUUsK0NBQStDLG9CQUFvQixFQUFFLFVBQVUsc0hBQXNILFlBQVksV0FBVyxZQUFZLGlCQUFpQixNQUFNLFlBQVksYUFBYSxXQUFXLFVBQVUsa0JBQWtCLEtBQUssWUFBWSxhQUFhLG1CQUFtQixNQUFNLFdBQVcsVUFBVSxrQkFBa0IsTUFBTSxhQUFhLFdBQVcsWUFBWSxXQUFXLFVBQVUsWUFBWSxhQUFhLGFBQWEsV0FBVyxrQkFBa0IsTUFBTSxhQUFhLFdBQVcsVUFBVSxtQkFBbUIsS0FBSyxZQUFZLGFBQWEsYUFBYSxvQkFBb0IsTUFBTSxZQUFZLGFBQWEsbUJBQW1CLEtBQUssVUFBVSxVQUFVLFlBQVksYUFBYSxhQUFhLFdBQVcsWUFBWSxXQUFXLG1CQUFtQixLQUFLLGlCQUFpQixLQUFLLG1CQUFtQixLQUFLLFlBQVksb0JBQW9CLEtBQUssV0FBVyxnQkFBZ0IsTUFBTSxhQUFhLFdBQVcsWUFBWSxhQUFhLG9CQUFvQixNQUFNLGFBQWEsb0JBQW9CLE1BQU0sV0FBVyxVQUFVLFVBQVUsbUJBQW1CLEtBQUssVUFBVSxZQUFZLFdBQVcsZ0JBQWdCLEtBQUssWUFBWSxxQkFBcUIsT0FBTyxZQUFZLGFBQWEsYUFBYSxhQUFhLGFBQWEsb0JBQW9CLE1BQU0sb0JBQW9CLE1BQU0sb0JBQW9CLE1BQU0sb0JBQW9CLE1BQU0sb0JBQW9CLE1BQU0sb0JBQW9CLE1BQU0sK0lBQStJLHVCQUF1QixpQkFBaUIsb0JBQW9CLGdCQUFnQixtQkFBbUIsc0JBQXNCLDJCQUEyQixvQkFBb0Isa0JBQWtCLDJCQUEyQixLQUFLLHNCQUFzQiw0QkFBNEIsdUJBQXVCLHlCQUF5Qiw4QkFBOEIsaUJBQWlCLGtCQUFrQix5QkFBeUIsT0FBTyxLQUFLLG9CQUFvQix5QkFBeUIsbUJBQW1CLDBDQUEwQyxxQkFBcUIscUJBQXFCLHNCQUFzQiwyQkFBMkIseUJBQXlCLGtCQUFrQixzQkFBc0IsS0FBSyx1QkFBdUIsaUNBQWlDLGFBQWEsY0FBYyx1QkFBdUIsS0FBSyxLQUFLLGdCQUFnQixxQkFBcUIsd0JBQXdCLG9CQUFvQix5QkFBeUIsZ0JBQWdCLDRCQUE0Qix5QkFBeUIsNEJBQTRCLEtBQUssZ0JBQWdCLG9CQUFvQixxQkFBcUIsMEJBQTBCLHlCQUF5Qix5QkFBeUIsZUFBZSwwQ0FBMEMsb0JBQW9CLHNCQUFzQixLQUFLLEtBQUssb0JBQW9CLG1CQUFtQixxQkFBcUIsS0FBSyxvQkFBb0IseURBQXlELEtBQUssb0JBQW9CLHNCQUFzQix1QkFBdUIsS0FBSyxrQkFBa0IscUJBQXFCLG1CQUFtQixLQUFLLGdCQUFnQiw2QkFBNkIsa0JBQWtCLHNCQUFzQixzQkFBc0IsMkJBQTJCLEtBQUssZ0JBQWdCLHNCQUFzQix5QkFBeUIsS0FBSyx3QkFBd0IscUJBQXFCLGtCQUFrQixtQkFBbUIsMkNBQTJDLEtBQUssR0FBRyxxQkFBcUIsa0JBQWtCLG9CQUFvQixZQUFZLFdBQVcsR0FBRyxnQkFBZ0IsOEJBQThCLDJDQUEyQyxjQUFjLHc2TkFBdzZOLEdBQUcsZUFBZSxxQ0FBcUMsb0JBQW9CLHVCQUF1Qix3Q0FBd0MscUNBQXFDLHVDQUF1QyxHQUFHLGtDQUFrQyxvQkFBb0IsR0FBRyxrQ0FBa0Msb0JBQW9CLEdBQUcsMENBQTBDLG9CQUFvQixHQUFHLDBDQUEwQyxvQkFBb0IsR0FBRywrQ0FBK0Msb0JBQW9CLEdBQUcsK0NBQStDLG9CQUFvQixHQUFHLGdCQUFnQix1QkFBdUIsaUJBQWlCLG9CQUFvQixnQkFBZ0IsRUFBRSw2QkFBNkIsc0JBQXNCLDJCQUEyQixvQkFBb0Isa0JBQWtCLDJCQUEyQixFQUFFLDhCQUE4Qiw0QkFBNEIsdUJBQXVCLHlCQUF5QixFQUFFLG1EQUFtRCxpQkFBaUIsa0JBQWtCLHlCQUF5QixFQUFFLDhCQUE4Qix5QkFBeUIsbUJBQW1CLDBDQUEwQyxxQkFBcUIscUJBQXFCLHNCQUFzQiwyQkFBMkIseUJBQXlCLGtCQUFrQixzQkFBc0IsRUFBRSwrQkFBK0IsaUNBQWlDLGFBQWEsY0FBYyx1QkFBdUIsRUFBRSxnQkFBZ0IscUJBQXFCLHdCQUF3QixvQkFBb0IseUJBQXlCLEVBQUUseUJBQXlCLDRCQUE0Qix5QkFBeUIsNEJBQTRCLEVBQUUseUJBQXlCLG9CQUFvQixxQkFBcUIsMEJBQTBCLHlCQUF5Qix5QkFBeUIsZUFBZSwwQ0FBMEMsb0JBQW9CLHNCQUFzQixFQUFFLGdDQUFnQyxtQkFBbUIsRUFBRSxpQ0FBaUMsdURBQXVELEVBQUUsaUNBQWlDLG9CQUFvQixxQkFBcUIsRUFBRSwrQkFBK0IsbUJBQW1CLGlCQUFpQixFQUFFLDZCQUE2QiwyQkFBMkIsZ0JBQWdCLG9CQUFvQixvQkFBb0IseUJBQXlCLEVBQUUsNkJBQTZCLG9CQUFvQix1QkFBdUIsRUFBRSxtQ0FBbUMsbUJBQW1CLGdCQUFnQixpQkFBaUIseUNBQXlDLEVBQUUscUJBQXFCLGtCQUFrQixvQkFBb0IsWUFBWSxXQUFXLEVBQUUsZ0JBQWdCLDhCQUE4QiwyQ0FBMkMsY0FBYyx3Nk5BQXc2TixFQUFFLGVBQWUscUNBQXFDLG9CQUFvQix1QkFBdUIsd0NBQXdDLHFDQUFxQyx1Q0FBdUMsRUFBRSxrQ0FBa0Msb0JBQW9CLEVBQUUsa0NBQWtDLG9CQUFvQixFQUFFLDBDQUEwQyxvQkFBb0IsRUFBRSwwQ0FBMEMsb0JBQW9CLEVBQUUsK0NBQStDLG9CQUFvQixFQUFFLCtDQUErQyxvQkFBb0IsRUFBRSwrQkFBK0I7O0FBRW5yOEI7Ozs7Ozs7QUNQQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBLE1BQUs7QUFDTCxJQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0gsa0NBQWlDLE9BQU87QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFpQyxPQUFPO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDcEpBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQW1GO0FBQ25GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0EsaUNBQWdDLFVBQVUsRUFBRTtBQUM1QyxFOzs7Ozs7QUNwQkE7QUFDQTs7O0FBR0E7QUFDQSx5Q0FBd0MsbUJBQW1CLHFCQUFxQixFQUFFLGdDQUFnQyxtQ0FBbUMsZ0NBQWdDLHdCQUF3QixFQUFFLDhCQUE4QixpQ0FBaUMsbUNBQW1DLDJCQUEyQixFQUFFLFVBQVUsc0ZBQXNGLFVBQVUsbUJBQW1CLEtBQUssWUFBWSxhQUFhLG9CQUFvQixLQUFLLFlBQVksYUFBYSw0RUFBNEUsbUJBQW1CLHFCQUFxQixHQUFHLHFCQUFxQixrQkFBa0IscUNBQXFDLGtDQUFrQywwQkFBMEIsS0FBSyxnQkFBZ0IsbUNBQW1DLHFDQUFxQyw2QkFBNkIsS0FBSyxHQUFHLDZCQUE2Qjs7QUFFejdCOzs7Ozs7O0FDUEE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBc0Q7QUFDdEQsc0NBQXFDLE9BQU87QUFDNUMsa0RBQWlEO0FBQ2pELDBCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUM3RUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBa0MsT0FBTztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUNsRkE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUNwQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUNwQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWE7QUFDYixpQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDcEdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQW1GO0FBQ25GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0EsaUNBQWdDLFVBQVUsRUFBRTtBQUM1QyxFOzs7Ozs7QUNwQkE7QUFDQTs7O0FBR0E7QUFDQSx3Q0FBdUMsMkJBQTJCLEVBQUUsVUFBVSxtRkFBbUYsdUVBQXVFLDJCQUEyQixHQUFHLDZCQUE2Qjs7QUFFblM7Ozs7Ozs7QUNQQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUCxNQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE1BQUs7O0FBRUw7Ozs7Ozs7QUMxTUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBbUY7QUFDbkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQSxpQ0FBZ0MsVUFB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QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBLElBQUc7QUFDSDtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDektBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDakNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDs7QUFFQSx1Qjs7Ozs7O0FDcEJBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDs7QUFFQSwwQjs7Ozs7O0FDcEJBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsZUFBYyxJQUFJO0FBQ2xCO0FBQ0E7QUFDQSxlQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDs7QUFFQSx3Qjs7Ozs7O0FDL0VBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0EsSUFBRztBQUNIOztBQUVBOzs7Ozs7O0FDcEVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxnQ0FBK0I7QUFDL0I7O0FBRUEsdUI7Ozs7OztBQzlCQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIOztBQUVBOzs7Ozs7O0FDaERBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBLElBQUc7O0FBRUg7O0FBRUE7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTs7QUFFQTs7Ozs7OztBQ2xFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFzRTtBQUN0RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLGlDQUFnQyxVQUFVLEVBQUU7QUFDNUMsRTs7Ozs7O0FDcEJBO0FBQ0E7OztBQUdBO0FBQ0EsNkNBQTRDLGtCQUFrQixvQkFBb0IsdUJBQXVCLFdBQVcsWUFBWSxnQkFBZ0IsaUJBQWlCLDJCQUEyQixpQkFBaUIsRUFBRSxzQkFBc0Isb0JBQW9CLHdCQUF3QixhQUFhLGNBQWMsdUJBQXVCLDRCQUE0QiwrQkFBK0IsNkNBQTZDLHFDQUFxQywyQkFBMkIsRUFBRSwyQkFBMkIsb0JBQW9CLEVBQUUsK0JBQStCLGtCQUFrQiw4QkFBOEIsNkJBQTZCLHlCQUF5QiwrQkFBK0IsMkJBQTJCLG9DQUFvQyxFQUFFLGlDQUFpQyxrQkFBa0IscUJBQXFCLDZCQUE2Qix5QkFBeUIsRUFBRSx3Q0FBd0MsK0JBQStCLHVCQUF1Qiw0QkFBNEIsRUFBRSxVQUFVLG1IQUFtSCxVQUFVLFlBQVksYUFBYSxXQUFXLFVBQVUsVUFBVSxVQUFVLFlBQVksaUJBQWlCLEtBQUssWUFBWSxhQUFhLFdBQVcsVUFBVSxZQUFZLGFBQWEsYUFBYSxhQUFhLGFBQWEsb0JBQW9CLE1BQU0sZUFBZSxLQUFLLFdBQVcsWUFBWSxhQUFhLGFBQWEsYUFBYSxhQUFhLG1CQUFtQixNQUFNLFdBQVcsVUFBVSxZQUFZLG1CQUFtQixNQUFNLGFBQWEsV0FBVyw0RUFBNEUsa0JBQWtCLG9CQUFvQix1QkFBdUIsV0FBVyxZQUFZLGdCQUFnQixpQkFBaUIsMkJBQTJCLGlCQUFpQixLQUFLLHNCQUFzQixvQkFBb0Isd0JBQXdCLGFBQWEsY0FBYyx1QkFBdUIscUNBQXFDLHdDQUF3QyxvREFBb0QscUNBQXFDLDJCQUEyQixjQUFjLHdCQUF3QixnQkFBZ0Isa0JBQWtCLDhCQUE4QixzQ0FBc0MseUJBQXlCLHVDQUF1QyxtQ0FBbUMsNENBQTRDLEtBQUssa0JBQWtCLGtCQUFrQixxQkFBcUIscUNBQXFDLGlDQUFpQyxjQUFjLCtCQUErQix1QkFBdUIsb0NBQW9DLGVBQWUsS0FBSyxHQUFHLCtCQUErQjs7QUFFaHFGOzs7Ozs7O0FDUEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBc0U7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQSxpQ0FBZ0MsVUFBVSxFQUFFO0FBQzVDLEU7Ozs7OztBQ3BCQTtBQUNBOzs7QUFHQTtBQUNBLHVEQUFzRCxnQkFBZ0IsRUFBRSxVQUFVLG1IQUFtSCxvRUFBb0Usc0JBQXNCLGtCQUFrQixLQUFLLEdBQUcsK0JBQStCOztBQUV4Vjs7Ozs7OztBQ1BBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7O0FBRUE7Ozs7Ozs7QUMzREE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBc0U7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQSxpQ0FBZ0MsVUFBVSxFQUFFO0FBQzVDLEU7Ozs7OztBQ3BCQTtBQUNBOzs7QUFHQTtBQUNBLDBEQUF5RCxnQkFBZ0IsZUFBZSxFQUFFLDBDQUEwQyxtQ0FBbUMsRUFBRSxVQUFVLHFIQUFxSCxVQUFVLGVBQWUsS0FBSywyRUFBMkUsa0JBQWtCLGNBQWMsb0JBQW9CLG1CQUFtQixvQkFBb0IsdUNBQXVDLFNBQVMsT0FBTyxLQUFLLEdBQUcsNkJBQTZCOztBQUV4a0I7Ozs7Ozs7QUNQQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTCxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTCxJQUFHO0FBQ0g7O0FBRUE7Ozs7Ozs7QUNoRkE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBc0U7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQSxpQ0FBZ0MsVUFBVSxFQUFFO0FBQzVDLEU7Ozs7OztBQ3BCQTtBQUNBOzs7QUFHQTtBQUNBLHFEQUFvRCwyQkFBMkIsZ0JBQWdCLDZDQUE2QyxvQkFBb0IsRUFBRSxxQ0FBcUMsNkJBQTZCLGtCQUFrQixzQkFBc0IsMkJBQTJCLHlCQUF5QixFQUFFLGtDQUFrQyxnQkFBZ0IsZUFBZSxFQUFFLHlDQUF5QyxtQ0FBbUMsRUFBRSxVQUFVLG9IQUFvSCxZQUFZLFdBQVcsWUFBWSxtQkFBbUIsS0FBSyxZQUFZLFdBQVcsWUFBWSxhQUFhLG9CQUFvQixLQUFLLFdBQVcsZUFBZSxNQUFNLDBFQUEwRSxtQkFBbUIsNkJBQTZCLGtCQUFrQiwrQ0FBK0Msd0NBQXdDLHdCQUF3QiwrQkFBK0Isb0JBQW9CLHdCQUF3QixxQ0FBcUMsbUNBQW1DLGVBQWUsS0FBSyxrQkFBa0IsY0FBYyxvQkFBb0IsbUJBQW1CLG9CQUFvQix1Q0FBdUMsU0FBUyxPQUFPLEtBQUssR0FBRyw2QkFBNkI7O0FBRTkwQzs7Ozs7OztBQ1BBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0EsSUFBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNULFFBQU87QUFDUCxNQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDbkZBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQXNFO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0EsaUNBQWdDLFVBQVUsRUFBRTtBQUM1QyxFOzs7Ozs7QUNwQkE7QUFDQTs7O0FBR0E7QUFDQSx3Q0FBdUMsdUJBQXVCLDZCQUE2QixvQkFBb0IsMkJBQTJCLG1CQUFtQix3QkFBd0IsY0FBYyx5QkFBeUIsMkJBQTJCLGdCQUFnQix1QkFBdUIsaUJBQWlCLHFDQUFxQywrQkFBK0Isd0NBQXdDLGdDQUFnQyxFQUFFLHNCQUFzQixlQUFlLEVBQUUsVUFBVSxtSEFBbUgsWUFBWSxhQUFhLGFBQWEsYUFBYSxXQUFXLFlBQVksV0FBVyxZQUFZLGFBQWEsV0FBVyxZQUFZLFdBQVcsWUFBWSxhQUFhLGFBQWEsb0JBQW9CLEtBQUssb0VBQW9FLHVCQUF1QixxQ0FBcUMsNEJBQTRCLDJCQUEyQixtQkFBbUIsd0JBQXdCLHVCQUF1Qix5QkFBeUIsbUNBQW1DLGdCQUFnQix1QkFBdUIsaUJBQWlCLHFDQUFxQywrQkFBK0IsK0NBQStDLGdDQUFnQyxHQUFHLHNCQUFzQixlQUFlLEdBQUcsNkJBQTZCOztBQUV4M0M7Ozs7Ozs7QUNQQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsZUFBYyxPQUFPO0FBQ3JCLGVBQWMsSUFBSTtBQUNsQixlQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDs7QUFFQTs7Ozs7OztBQzdDQSwrQ0FBOEMsUUFBUSxVQUFVLEVBQUUsaUNBQWlDLEVBQUUsK0JBQStCLEVBQUUsZUFBZSxjQUFjLGtDQUFrQyxpQ0FBaUMsc0JBQXNCLDJCQUEyQixzQkFBc0IsNEJBQTRCLHFCQUFxQiwyQkFBMkIsc0JBQXNCLDRCQUE0QixxQkFBcUIsOEJBQThCLGVBQWUsaUNBQWlDLGdCQUFnQixnQ0FBZ0MsdUNBQXVDLFdBQVcsS0FBSyx3QkFBd0IsZ0JBQWdCLG1CQUFtQixrRkFBa0YsOEJBQThCLHlCQUF5QixvREFBb0QsWUFBWSx1QkFBdUIsS0FBSyw0Q0FBNEMsOERBQThELGdCQUFnQixTQUFTLHVCQUF1QixpQkFBaUIsa0NBQWtDLGlCQUFpQixnQkFBZ0IsMENBQTBDLGtCQUFrQiw4QkFBOEIsV0FBVyxLQUFLLHFCQUFxQixJQUFJLGtEQUFrRCxTQUFTLGdDQUFnQyxrQ0FBa0MsaUJBQWlCLGdCQUFnQiw4QkFBOEIsNkRBQTZELHFEQUFxRCwyRUFBMkUsYUFBYSxrSUFBa0kseUNBQXlDLFdBQVcsbURBQW1ELHVHQUF1RyxlQUFlLGdDQUFnQywwREFBMEQsa0NBQWtDLGlCQUFpQixnQkFBZ0IsOEJBQThCLDZEQUE2RCwrQkFBK0IscURBQXFELCtCQUErQixrREFBa0QseUNBQXlDLG9GQUFvRixhQUFhLDBQQUEwUCx1Q0FBdUMsa0xBQWtMLHlDQUF5QywrRkFBK0YsdUNBQXVDLDJEQUEyRCxnRUFBZ0UsaUJBQWlCLCtCQUErQixxRUFBcUUsa0NBQWtDLGlCQUFpQixnQkFBZ0IsNEJBQTRCLGtDQUFrQywyQkFBMkIsNENBQTRDLDZCQUE2QixtQkFBbUIsa0NBQWtDLGlCQUFpQixnQkFBZ0IsZ0NBQWdDLG1EQUFtRCx3QkFBd0IsZ09BQWdPLDJHQUEyRyw4Q0FBOEMsa0NBQWtDLElBQUksbUMiLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcblxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0ZXhwb3J0czoge30sXG4gXHRcdFx0aWQ6IG1vZHVsZUlkLFxuIFx0XHRcdGxvYWRlZDogZmFsc2VcbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIHdlYnBhY2svYm9vdHN0cmFwIDk2ZTBhZmNjNjU3NjkwMzc2ZTU0XG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnJlcXVpcmUoJy4vc3R5bGVzL2Jhc2Uuc2NzcycpXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZycpXG52YXIgTG9hZGVyID0gcmVxdWlyZSgnLi9sb2FkZXInKVxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpXG52YXIgcHJvdG9jb2wgPSByZXF1aXJlKCcuL3Byb3RvY29sJylcbnZhciBDb21wb25lbnRNYW5hZ2VyID0gcmVxdWlyZSgnLi9jb21wb25lbnRNYW5hZ2VyJylcbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvY29tcG9uZW50JylcbnZhciBTZW5kZXIgPSByZXF1aXJlKCcuL2JyaWRnZS9zZW5kZXInKVxudmFyIHJlY2VpdmVyID0gcmVxdWlyZSgnLi9icmlkZ2UvcmVjZWl2ZXInKVxuXG4vLyBDb21wb25lbnRzIGFuZCBhcGlzLlxudmFyIGNvbXBvbmVudHMgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMnKVxudmFyIGFwaSA9IHJlcXVpcmUoJy4vYXBpJylcbnJlcXVpcmUoJ2VudmQnKVxuXG52YXIgV0VBUFBfU1RZTEVfSUQgPSAnd2VhcHAtc3R5bGUnXG5cbnZhciBERUZBVUxUX0RFU0lHTl9XSURUSCA9IDc1MFxudmFyIERFRkFVTFRfUk9PVF9JRCA9ICd3ZWV4J1xudmFyIERFRkFVTFRfSlNPTl9DQUxMQkFDS19OQU1FID0gJ3dlZXhKc29ucENhbGxiYWNrJ1xuXG4vLyBjb25maWcuc2NhbGUgPSB3aW5kb3cuaW5uZXJXaWR0aCAvIERFRkFVTFRfREVTSUdOX1dJRFRIXG5cbndpbmRvdy5XWEVudmlyb25tZW50ID0ge1xuICB3ZWV4VmVyc2lvbjogY29uZmlnLndlZXhWZXJzaW9uLFxuICBhcHBOYW1lOiBsaWIuZW52LmFsaWFwcCA/IGxpYi5lbnYuYWxpYXBwLmFwcG5hbWUgOiBudWxsLFxuICBhcHBWZXJzaW9uOiBsaWIuZW52LmFsaWFwcCA/IGxpYi5lbnYuYWxpYXBwLnZlcnNpb24udmFsIDogbnVsbCxcbiAgcGxhdGZvcm06IGxpYi5lbnYub3MgPyBsaWIuZW52Lm9zLm5hbWUgOiBudWxsLFxuICBvc1ZlcnNpb246IGxpYi5lbnYub3MgPyBsaWIuZW52Lm9zLnZlcnNpb24udmFsIDogbnVsbCxcbiAgZGV2aWNlSGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQgLyBjb25maWcuc2NhbGVcbn1cblxudmFyIF9pbnN0YW5jZU1hcCA9IHt9XG5cbmZ1bmN0aW9uIFdlZXgob3B0aW9ucykge1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBXZWV4KSkge1xuICAgIHJldHVybiBuZXcgV2VleChvcHRpb25zKVxuICB9XG5cbiAgLy8gV2lkdGggb2YgdGhlIHJvb3QgY29udGFpbmVyLiBEZWZhdWx0IGlzIHdpbmRvdy5pbm5lcldpZHRoLlxuICB0aGlzLndpZHRoID0gb3B0aW9ucy53aWR0aCB8fCB3aW5kb3cuaW5uZXJXaWR0aFxuICB0aGlzLmJ1bmRsZVVybCA9IG9wdGlvbnMuYnVuZGxlVXJsIHx8IGxvY2F0aW9uLmhyZWZcbiAgdGhpcy5pbnN0YW5jZUlkID0gb3B0aW9ucy5hcHBJZFxuICB0aGlzLnJvb3RJZCA9IG9wdGlvbnMucm9vdElkIHx8IChERUZBVUxUX1JPT1RfSUQgKyB1dGlscy5nZXRSYW5kb20oMTApKVxuICB0aGlzLmRlc2lnbldpZHRoID0gb3B0aW9ucy5kZXNpZ25XaWR0aCB8fCBERUZBVUxUX0RFU0lHTl9XSURUSFxuICB0aGlzLmpzb25wQ2FsbGJhY2sgPSBvcHRpb25zLmpzb25wQ2FsbGJhY2sgfHwgREVGQVVMVF9KU09OX0NBTExCQUNLX05BTUVcbiAgdGhpcy5zb3VyY2UgPSBvcHRpb25zLnNvdXJjZVxuICB0aGlzLmxvYWRlciA9IG9wdGlvbnMubG9hZGVyXG5cbiAgdGhpcy5kYXRhID0gb3B0aW9ucy5kYXRhXG5cbiAgdGhpcy5pbml0U2NhbGUoKVxuICB0aGlzLmluaXRDb21wb25lbnRNYW5hZ2VyKClcbiAgdGhpcy5pbml0QnJpZGdlKClcbiAgV2VleC5hZGRJbnN0YW5jZSh0aGlzKVxuXG4gIHByb3RvY29sLmluamVjdFdlZXhJbnN0YW5jZSh0aGlzKVxuXG4gIHRoaXMubG9hZEJ1bmRsZShmdW5jdGlvbiAoZXJyLCBhcHBDb2RlKSB7XG4gICAgaWYgKCFlcnIpIHtcbiAgICAgIHRoaXMuY3JlYXRlQXBwKGNvbmZpZywgYXBwQ29kZSlcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcignbG9hZCBidW5kbGUgZXJyOicsIGVycilcbiAgICB9XG4gIH0uYmluZCh0aGlzKSlcblxufVxuXG5XZWV4LmluaXQgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICBpZiAodXRpbHMuaXNBcnJheShvcHRpb25zKSkge1xuICAgIG9wdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAoY29uZmlnKSB7XG4gICAgICBuZXcgV2VleChjb25maWcpXG4gICAgfSlcbiAgfSBlbHNlIGlmIChcbiAgICAgIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvcHRpb25zKS5zbGljZSg4LCAtMSkgPT09ICdPYmplY3QnXG4gICAgKSB7XG4gICAgbmV3IFdlZXgob3B0aW9ucylcbiAgfVxufVxuXG5XZWV4LmFkZEluc3RhbmNlID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7XG4gIF9pbnN0YW5jZU1hcFtpbnN0YW5jZS5pbnN0YW5jZUlkXSA9IGluc3RhbmNlXG59XG5cbldlZXguZ2V0SW5zdGFuY2UgPSBmdW5jdGlvbiAoaW5zdGFuY2VJZCkge1xuICByZXR1cm4gX2luc3RhbmNlTWFwW2luc3RhbmNlSWRdXG59XG5cbldlZXgucHJvdG90eXBlID0ge1xuXG4gIGluaXRCcmlkZ2U6IGZ1bmN0aW9uICgpIHtcbiAgICByZWNlaXZlci5pbml0KHRoaXMpXG4gICAgdGhpcy5zZW5kZXIgPSBuZXcgU2VuZGVyKHRoaXMpXG4gIH0sXG5cbiAgbG9hZEJ1bmRsZTogZnVuY3Rpb24gKGNiKSB7XG4gICAgTG9hZGVyLmxvYWQoe1xuICAgICAganNvbnBDYWxsYmFjazogdGhpcy5qc29ucENhbGxiYWNrLFxuICAgICAgc291cmNlOiB0aGlzLnNvdXJjZSxcbiAgICAgIGxvYWRlcjogdGhpcy5sb2FkZXJcbiAgICB9LCBjYilcbiAgfSxcblxuICBjcmVhdGVBcHA6IGZ1bmN0aW9uIChjb25maWcsIGFwcENvZGUpIHtcbiAgICB2YXIgcm9vdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyMnICsgdGhpcy5yb290SWQpXG4gICAgaWYgKCFyb290KSB7XG4gICAgICByb290ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgIHJvb3QuaWQgPSB0aGlzLnJvb3RJZFxuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChyb290KVxuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gd2luZG93LmNyZWF0ZUluc3RhbmNlKFxuICAgICAgdGhpcy5pbnN0YW5jZUlkXG4gICAgICAsIGFwcENvZGVcbiAgICAgICwge1xuICAgICAgICBidW5kbGVVcmw6IHRoaXMuYnVuZGxlVXJsLFxuICAgICAgICBkZWJ1ZzogY29uZmlnLmRlYnVnXG4gICAgICB9XG4gICAgICAsIHRoaXMuZGF0YVxuICAgIClcblxuICAgIGlmIChQcm9taXNlICYmIHByb21pc2UgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICBwcm9taXNlLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBXZWV4Ll9pbnN0YW5jZXNbdGhpcy5pbnN0YW5jZUlkXSA9IHRoaXMucm9vdFxuICAgICAgfS5iaW5kKHRoaXMpKS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIgJiYgY29uZmlnLmRlYnVnKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuXG4gICAgLy8gRG8gbm90IGRlc3Ryb3kgaW5zdGFuY2UgaGVyZSwgYmVjYXVzZSBpbiBtb3N0IGJyb3dzZXJcbiAgICAvLyBwcmVzcyBiYWNrIGJ1dHRvbiB0byBiYWNrIHRvIHRoaXMgcGFnZSB3aWxsIG5vdCByZWZyZXNoXG4gICAgLy8gdGhlIHdpbmRvdyBhbmQgdGhlIGluc3RhbmNlIHdpbGwgbm90IGJlIHJlY3JlYXRlZCB0aGVuLlxuICAgIC8vIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdiZWZvcmV1bmxvYWQnLCBmdW5jdGlvbiAoZSkge1xuICAgIC8vIH0pXG5cbiAgfSxcblxuICBpbml0U2NhbGU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNjYWxlID0gdGhpcy53aWR0aCAvIHRoaXMuZGVzaWduV2lkdGhcbiAgfSxcblxuICBpbml0Q29tcG9uZW50TWFuYWdlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX2NvbXBvbmVudE1hbmFnZXIgPSBuZXcgQ29tcG9uZW50TWFuYWdlcih0aGlzKVxuICB9LFxuXG4gIGdldENvbXBvbmVudE1hbmFnZXI6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29tcG9uZW50TWFuYWdlclxuICB9XG59XG5cbldlZXguYXBwZW5kU3R5bGUgPSBmdW5jdGlvbiAoY3NzKSB7XG4gIHV0aWxzLmFwcGVuZFN0eWxlKGNzcywgV0VBUFBfU1RZTEVfSUQpXG59LFxuXG4vLyBSZWdpc3RlciBhIG5ldyBjb21wb25lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuXG5XZWV4LnJlZ2lzdGVyQ29tcG9uZW50ID0gZnVuY3Rpb24gKG5hbWUsIGNvbXApIHtcbiAgQ29tcG9uZW50TWFuYWdlci5yZWdpc3RlckNvbXBvbmVudChuYW1lLCBjb21wKVxufSxcblxuLy8gUmVnaXN0ZXIgYSBuZXcgYXBpIG1vZHVsZS5cbi8vIElmIHRoZSBtb2R1bGUgYWxyZWFkeSBleGlzdHMsIGp1c3QgYWRkIG1ldGhvZHMgZnJvbSB0aGVcbi8vIG5ldyBtb2R1bGUgdG8gdGhlIG9sZCBvbmUuXG5XZWV4LnJlZ2lzdGVyQXBpTW9kdWxlID0gZnVuY3Rpb24gKG5hbWUsIG1vZHVsZSwgbWV0YSkge1xuICBpZiAoIXByb3RvY29sLmFwaU1vZHVsZVtuYW1lXSkge1xuICAgIHByb3RvY29sLmFwaU1vZHVsZVtuYW1lXSA9IG1vZHVsZVxuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGtleSBpbiBtb2R1bGUpIHtcbiAgICAgIGlmIChtb2R1bGUuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICBwcm90b2NvbC5hcGlNb2R1bGVbbmFtZV1ba2V5XSA9IG1vZHVsZVtrZXldXG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIHJlZ2lzdGVyIEFQSSBtb2R1bGUncyBtZXRhIGluZm8gdG8ganNmcmFtZXdvcmtcbiAgaWYgKG1ldGEpIHtcbiAgICBwcm90b2NvbC5zZXRBcGlNb2R1bGVNZXRhKG1ldGEpXG4gICAgd2luZG93LnJlZ2lzdGVyTW9kdWxlcyhwcm90b2NvbC5nZXRBcGlNb2R1bGVNZXRhKG5hbWUpLCB0cnVlKVxuICB9XG59LFxuXG4vLyBSZWdpc3RlciBhIG5ldyBhcGkgbWV0aG9kIGZvciB0aGUgc3BlY2lmaWVkIG1vZHVsZS5cbi8vIG9wdHM6XG4vLyAgLSBhcmdzOiB0eXBlIG9mIGFyZ3VtZW50cyB0aGUgQVBJIG1ldGhvZCB0YWtlcyBzdWNoXG4vLyAgICBhcyBbJ3N0cmluZycsICdmdW5jdGlvbiddXG5XZWV4LnJlZ2lzdGVyQXBpID0gZnVuY3Rpb24gKG1vZHVsZU5hbWUsIG5hbWUsIG1ldGhvZCwgYXJncykge1xuICBpZiAodHlwZW9mIG1ldGhvZCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVyblxuICB9XG4gIGlmICghcHJvdG9jb2wuYXBpTW9kdWxlW21vZHVsZU5hbWVdKSB7XG4gICAgcHJvdG9jb2wuYXBpTW9kdWxlW21vZHVsZU5hbWVdID0ge31cbiAgICBwcm90b2NvbC5fbWV0YVttb2R1bGVOYW1lXSA9IFtdXG4gIH1cbiAgcHJvdG9jb2wuYXBpTW9kdWxlW21vZHVsZU5hbWVdW25hbWVdID0gbWV0aG9kXG4gIGlmICghYXJncykge1xuICAgIHJldHVyblxuICB9XG4gIC8vIHJlZ2lzdGVyIEFQSSBtZXRhIGluZm8gdG8ganNmcmFtZXdvcmtcbiAgcHJvdG9jb2wuc2V0QXBpTWV0YShtb2R1bGVOYW1lLCB7XG4gICAgbmFtZTogbmFtZSxcbiAgICBhcmdzOiBhcmdzXG4gIH0pXG4gIHdpbmRvdy5yZWdpc3Rlck1vZHVsZXMocHJvdG9jb2wuZ2V0QXBpTW9kdWxlTWV0YShtb2R1bGVOYW1lLCBtZXRhKSwgdHJ1ZSlcbn0sXG5cbi8vIFJlZ2lzdGVyIGEgbmV3IHdlZXgtYnVuZGxlLWxvYWRlci5cbldlZXgucmVnaXN0ZXJMb2FkZXIgPSBmdW5jdGlvbiAobmFtZSwgbG9hZGVyRnVuYykge1xuICBMb2FkZXIucmVnaXN0ZXJMb2FkZXIobmFtZSwgbG9hZGVyRnVuYylcbn1cblxuLy8gVG8gaW5zdGFsbCBjb21wb25lbnRzIGFuZCBwbHVnaW5zLlxuV2VleC5pbnN0YWxsID0gZnVuY3Rpb24gKG1vZCkge1xuICBtb2QuaW5pdChXZWV4KVxufVxuXG5XZWV4LnN0b3BUaGVXb3JsZCA9IGZ1bmN0aW9uICgpIHtcbiAgZm9yICh2YXIgaW5zdGFuY2VJZCBpbiBfaW5zdGFuY2VNYXApIHtcbiAgICBpZiAoX2luc3RhbmNlTWFwLmhhc093blByb3BlcnR5KGluc3RhbmNlSWQpKSB7XG4gICAgICB3aW5kb3cuZGVzdHJveUluc3RhbmNlKGluc3RhbmNlSWQpXG4gICAgfVxuICB9XG59XG5cbihmdW5jdGlvbiBzdGFydFJlZnJlc2hDb250cm9sbGVyKCkge1xuICBpZiAobG9jYXRpb24uc2VhcmNoLmluZGV4T2YoJ2hvdC1yZWxvYWRfY29udHJvbGxlcicpID09PSAtMSkgIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoIXdpbmRvdy5XZWJTb2NrZXQpIHtcbiAgICBjb25zb2xlLmluZm8oJ2F1dG8gcmVmcmVzaCBuZWVkIFdlYlNvY2tldCBzdXBwb3J0JylcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgaG9zdCA9IGxvY2F0aW9uLmhvc3RuYW1lXG4gIHZhciBwb3J0ID0gODA4MlxuICB2YXIgY2xpZW50ID0gbmV3IFdlYlNvY2tldCgnd3M6Ly8nICsgaG9zdCArICc6JyArIHBvcnQgKyAnLycsXG4gICAgJ2VjaG8tcHJvdG9jb2wnXG4gIClcbiAgY2xpZW50Lm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5sb2coJ3JlZnJlc2ggY29udHJvbGxlciB3ZWJzb2NrZXQgY29ubmVjdGlvbiBlcnJvcicpXG4gIH1cbiAgY2xpZW50Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgY29uc29sZS5sb2coJ1JlY2VpdmVkOiBcXCcnICsgZS5kYXRhICsgJ1xcJycpXG4gICAgaWYgKGUuZGF0YSAgPT09ICdyZWZyZXNoJykge1xuICAgICAgbG9jYXRpb24ucmVsb2FkKClcbiAgICB9XG4gIH1cbn0oKSlcblxuLy8gV2VleC5pbnN0YWxsKHJlcXVpcmUoJ3dlZXgtY29tcG9uZW50cycpKVxuV2VleC5pbnN0YWxsKGNvbXBvbmVudHMpXG5XZWV4Lmluc3RhbGwoYXBpKVxuXG5XZWV4LkNvbXBvbmVudCA9IENvbXBvbmVudFxuV2VleC5Db21wb25lbnRNYW5hZ2VyID0gQ29tcG9uZW50TWFuYWdlclxuV2VleC51dGlscyA9IHV0aWxzXG5XZWV4LmNvbmZpZyA9IGNvbmZpZ1xuXG5nbG9iYWwud2VleCA9IFdlZXhcbm1vZHVsZS5leHBvcnRzID0gV2VleFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy93ZWV4LmpzXG4gKiogbW9kdWxlIGlkID0gMFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2Jhc2Uuc2Nzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2Jhc2Uuc2Nzc1wiLCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vYmFzZS5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy9iYXNlLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSAxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIioge1xcbiAgbWFyZ2luOiAwO1xcbiAgcGFkZGluZzogMDtcXG4gIHRleHQtc2l6ZS1hZGp1c3Q6IG5vbmU7IH1cXG5cXG51bCwgb2wge1xcbiAgbGlzdC1zdHlsZTogbm9uZTsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9iYXNlLnNjc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7RUFDRSxVQUFTO0VBQ1QsV0FBVTtFQUNWLHVCQUNELEVBQUM7O0FBQ0Y7RUFDRSxpQkFDRCxFQUFDXCIsXCJmaWxlXCI6XCJiYXNlLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiKiB7XFxuICBtYXJnaW46MDtcXG4gIHBhZGRpbmc6MDtcXG4gIHRleHQtc2l6ZS1hZGp1c3Q6bm9uZVxcbn1cXG51bCxvbCB7XFxuICBsaXN0LXN0eWxlOm5vbmVcXG59XCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vc3JjL3N0eWxlcy9iYXNlLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSAyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKlxyXG5cdE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXHJcblx0QXV0aG9yIFRvYmlhcyBLb3BwZXJzIEBzb2tyYVxyXG4qL1xyXG4vLyBjc3MgYmFzZSBjb2RlLCBpbmplY3RlZCBieSB0aGUgY3NzLWxvYWRlclxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciBsaXN0ID0gW107XHJcblxyXG5cdC8vIHJldHVybiB0aGUgbGlzdCBvZiBtb2R1bGVzIGFzIGNzcyBzdHJpbmdcclxuXHRsaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XHJcblx0XHR2YXIgcmVzdWx0ID0gW107XHJcblx0XHRmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgaXRlbSA9IHRoaXNbaV07XHJcblx0XHRcdGlmKGl0ZW1bMl0pIHtcclxuXHRcdFx0XHRyZXN1bHQucHVzaChcIkBtZWRpYSBcIiArIGl0ZW1bMl0gKyBcIntcIiArIGl0ZW1bMV0gKyBcIn1cIik7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0cmVzdWx0LnB1c2goaXRlbVsxXSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiByZXN1bHQuam9pbihcIlwiKTtcclxuXHR9O1xyXG5cclxuXHQvLyBpbXBvcnQgYSBsaXN0IG9mIG1vZHVsZXMgaW50byB0aGUgbGlzdFxyXG5cdGxpc3QuaSA9IGZ1bmN0aW9uKG1vZHVsZXMsIG1lZGlhUXVlcnkpIHtcclxuXHRcdGlmKHR5cGVvZiBtb2R1bGVzID09PSBcInN0cmluZ1wiKVxyXG5cdFx0XHRtb2R1bGVzID0gW1tudWxsLCBtb2R1bGVzLCBcIlwiXV07XHJcblx0XHR2YXIgYWxyZWFkeUltcG9ydGVkTW9kdWxlcyA9IHt9O1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGlkID0gdGhpc1tpXVswXTtcclxuXHRcdFx0aWYodHlwZW9mIGlkID09PSBcIm51bWJlclwiKVxyXG5cdFx0XHRcdGFscmVhZHlJbXBvcnRlZE1vZHVsZXNbaWRdID0gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdGZvcihpID0gMDsgaSA8IG1vZHVsZXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGl0ZW0gPSBtb2R1bGVzW2ldO1xyXG5cdFx0XHQvLyBza2lwIGFscmVhZHkgaW1wb3J0ZWQgbW9kdWxlXHJcblx0XHRcdC8vIHRoaXMgaW1wbGVtZW50YXRpb24gaXMgbm90IDEwMCUgcGVyZmVjdCBmb3Igd2VpcmQgbWVkaWEgcXVlcnkgY29tYmluYXRpb25zXHJcblx0XHRcdC8vICB3aGVuIGEgbW9kdWxlIGlzIGltcG9ydGVkIG11bHRpcGxlIHRpbWVzIHdpdGggZGlmZmVyZW50IG1lZGlhIHF1ZXJpZXMuXHJcblx0XHRcdC8vICBJIGhvcGUgdGhpcyB3aWxsIG5ldmVyIG9jY3VyIChIZXkgdGhpcyB3YXkgd2UgaGF2ZSBzbWFsbGVyIGJ1bmRsZXMpXHJcblx0XHRcdGlmKHR5cGVvZiBpdGVtWzBdICE9PSBcIm51bWJlclwiIHx8ICFhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2l0ZW1bMF1dKSB7XHJcblx0XHRcdFx0aWYobWVkaWFRdWVyeSAmJiAhaXRlbVsyXSkge1xyXG5cdFx0XHRcdFx0aXRlbVsyXSA9IG1lZGlhUXVlcnk7XHJcblx0XHRcdFx0fSBlbHNlIGlmKG1lZGlhUXVlcnkpIHtcclxuXHRcdFx0XHRcdGl0ZW1bMl0gPSBcIihcIiArIGl0ZW1bMl0gKyBcIikgYW5kIChcIiArIG1lZGlhUXVlcnkgKyBcIilcIjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0bGlzdC5wdXNoKGl0ZW0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fTtcclxuXHRyZXR1cm4gbGlzdDtcclxufTtcclxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcbiAqKiBtb2R1bGUgaWQgPSAzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKlxyXG5cdE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXHJcblx0QXV0aG9yIFRvYmlhcyBLb3BwZXJzIEBzb2tyYVxyXG4qL1xyXG52YXIgc3R5bGVzSW5Eb20gPSB7fSxcclxuXHRtZW1vaXplID0gZnVuY3Rpb24oZm4pIHtcclxuXHRcdHZhciBtZW1vO1xyXG5cdFx0cmV0dXJuIGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0aWYgKHR5cGVvZiBtZW1vID09PSBcInVuZGVmaW5lZFwiKSBtZW1vID0gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuXHRcdFx0cmV0dXJuIG1lbW87XHJcblx0XHR9O1xyXG5cdH0sXHJcblx0aXNPbGRJRSA9IG1lbW9pemUoZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gL21zaWUgWzYtOV1cXGIvLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSk7XHJcblx0fSksXHJcblx0Z2V0SGVhZEVsZW1lbnQgPSBtZW1vaXplKGZ1bmN0aW9uICgpIHtcclxuXHRcdHJldHVybiBkb2N1bWVudC5oZWFkIHx8IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaGVhZFwiKVswXTtcclxuXHR9KSxcclxuXHRzaW5nbGV0b25FbGVtZW50ID0gbnVsbCxcclxuXHRzaW5nbGV0b25Db3VudGVyID0gMCxcclxuXHRzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcCA9IFtdO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihsaXN0LCBvcHRpb25zKSB7XHJcblx0aWYodHlwZW9mIERFQlVHICE9PSBcInVuZGVmaW5lZFwiICYmIERFQlVHKSB7XHJcblx0XHRpZih0eXBlb2YgZG9jdW1lbnQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBFcnJvcihcIlRoZSBzdHlsZS1sb2FkZXIgY2Fubm90IGJlIHVzZWQgaW4gYSBub24tYnJvd3NlciBlbnZpcm9ubWVudFwiKTtcclxuXHR9XHJcblxyXG5cdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG5cdC8vIEZvcmNlIHNpbmdsZS10YWcgc29sdXRpb24gb24gSUU2LTksIHdoaWNoIGhhcyBhIGhhcmQgbGltaXQgb24gdGhlICMgb2YgPHN0eWxlPlxyXG5cdC8vIHRhZ3MgaXQgd2lsbCBhbGxvdyBvbiBhIHBhZ2VcclxuXHRpZiAodHlwZW9mIG9wdGlvbnMuc2luZ2xldG9uID09PSBcInVuZGVmaW5lZFwiKSBvcHRpb25zLnNpbmdsZXRvbiA9IGlzT2xkSUUoKTtcclxuXHJcblx0Ly8gQnkgZGVmYXVsdCwgYWRkIDxzdHlsZT4gdGFncyB0byB0aGUgYm90dG9tIG9mIDxoZWFkPi5cclxuXHRpZiAodHlwZW9mIG9wdGlvbnMuaW5zZXJ0QXQgPT09IFwidW5kZWZpbmVkXCIpIG9wdGlvbnMuaW5zZXJ0QXQgPSBcImJvdHRvbVwiO1xyXG5cclxuXHR2YXIgc3R5bGVzID0gbGlzdFRvU3R5bGVzKGxpc3QpO1xyXG5cdGFkZFN0eWxlc1RvRG9tKHN0eWxlcywgb3B0aW9ucyk7XHJcblxyXG5cdHJldHVybiBmdW5jdGlvbiB1cGRhdGUobmV3TGlzdCkge1xyXG5cdFx0dmFyIG1heVJlbW92ZSA9IFtdO1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgaXRlbSA9IHN0eWxlc1tpXTtcclxuXHRcdFx0dmFyIGRvbVN0eWxlID0gc3R5bGVzSW5Eb21baXRlbS5pZF07XHJcblx0XHRcdGRvbVN0eWxlLnJlZnMtLTtcclxuXHRcdFx0bWF5UmVtb3ZlLnB1c2goZG9tU3R5bGUpO1xyXG5cdFx0fVxyXG5cdFx0aWYobmV3TGlzdCkge1xyXG5cdFx0XHR2YXIgbmV3U3R5bGVzID0gbGlzdFRvU3R5bGVzKG5ld0xpc3QpO1xyXG5cdFx0XHRhZGRTdHlsZXNUb0RvbShuZXdTdHlsZXMsIG9wdGlvbnMpO1xyXG5cdFx0fVxyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IG1heVJlbW92ZS5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgZG9tU3R5bGUgPSBtYXlSZW1vdmVbaV07XHJcblx0XHRcdGlmKGRvbVN0eWxlLnJlZnMgPT09IDApIHtcclxuXHRcdFx0XHRmb3IodmFyIGogPSAwOyBqIDwgZG9tU3R5bGUucGFydHMubGVuZ3RoOyBqKyspXHJcblx0XHRcdFx0XHRkb21TdHlsZS5wYXJ0c1tqXSgpO1xyXG5cdFx0XHRcdGRlbGV0ZSBzdHlsZXNJbkRvbVtkb21TdHlsZS5pZF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRTdHlsZXNUb0RvbShzdHlsZXMsIG9wdGlvbnMpIHtcclxuXHRmb3IodmFyIGkgPSAwOyBpIDwgc3R5bGVzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHR2YXIgaXRlbSA9IHN0eWxlc1tpXTtcclxuXHRcdHZhciBkb21TdHlsZSA9IHN0eWxlc0luRG9tW2l0ZW0uaWRdO1xyXG5cdFx0aWYoZG9tU3R5bGUpIHtcclxuXHRcdFx0ZG9tU3R5bGUucmVmcysrO1xyXG5cdFx0XHRmb3IodmFyIGogPSAwOyBqIDwgZG9tU3R5bGUucGFydHMubGVuZ3RoOyBqKyspIHtcclxuXHRcdFx0XHRkb21TdHlsZS5wYXJ0c1tqXShpdGVtLnBhcnRzW2pdKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRmb3IoOyBqIDwgaXRlbS5wYXJ0cy5sZW5ndGg7IGorKykge1xyXG5cdFx0XHRcdGRvbVN0eWxlLnBhcnRzLnB1c2goYWRkU3R5bGUoaXRlbS5wYXJ0c1tqXSwgb3B0aW9ucykpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR2YXIgcGFydHMgPSBbXTtcclxuXHRcdFx0Zm9yKHZhciBqID0gMDsgaiA8IGl0ZW0ucGFydHMubGVuZ3RoOyBqKyspIHtcclxuXHRcdFx0XHRwYXJ0cy5wdXNoKGFkZFN0eWxlKGl0ZW0ucGFydHNbal0sIG9wdGlvbnMpKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRzdHlsZXNJbkRvbVtpdGVtLmlkXSA9IHtpZDogaXRlbS5pZCwgcmVmczogMSwgcGFydHM6IHBhcnRzfTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxpc3RUb1N0eWxlcyhsaXN0KSB7XHJcblx0dmFyIHN0eWxlcyA9IFtdO1xyXG5cdHZhciBuZXdTdHlsZXMgPSB7fTtcclxuXHRmb3IodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xyXG5cdFx0dmFyIGl0ZW0gPSBsaXN0W2ldO1xyXG5cdFx0dmFyIGlkID0gaXRlbVswXTtcclxuXHRcdHZhciBjc3MgPSBpdGVtWzFdO1xyXG5cdFx0dmFyIG1lZGlhID0gaXRlbVsyXTtcclxuXHRcdHZhciBzb3VyY2VNYXAgPSBpdGVtWzNdO1xyXG5cdFx0dmFyIHBhcnQgPSB7Y3NzOiBjc3MsIG1lZGlhOiBtZWRpYSwgc291cmNlTWFwOiBzb3VyY2VNYXB9O1xyXG5cdFx0aWYoIW5ld1N0eWxlc1tpZF0pXHJcblx0XHRcdHN0eWxlcy5wdXNoKG5ld1N0eWxlc1tpZF0gPSB7aWQ6IGlkLCBwYXJ0czogW3BhcnRdfSk7XHJcblx0XHRlbHNlXHJcblx0XHRcdG5ld1N0eWxlc1tpZF0ucGFydHMucHVzaChwYXJ0KTtcclxuXHR9XHJcblx0cmV0dXJuIHN0eWxlcztcclxufVxyXG5cclxuZnVuY3Rpb24gaW5zZXJ0U3R5bGVFbGVtZW50KG9wdGlvbnMsIHN0eWxlRWxlbWVudCkge1xyXG5cdHZhciBoZWFkID0gZ2V0SGVhZEVsZW1lbnQoKTtcclxuXHR2YXIgbGFzdFN0eWxlRWxlbWVudEluc2VydGVkQXRUb3AgPSBzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcFtzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcC5sZW5ndGggLSAxXTtcclxuXHRpZiAob3B0aW9ucy5pbnNlcnRBdCA9PT0gXCJ0b3BcIikge1xyXG5cdFx0aWYoIWxhc3RTdHlsZUVsZW1lbnRJbnNlcnRlZEF0VG9wKSB7XHJcblx0XHRcdGhlYWQuaW5zZXJ0QmVmb3JlKHN0eWxlRWxlbWVudCwgaGVhZC5maXJzdENoaWxkKTtcclxuXHRcdH0gZWxzZSBpZihsYXN0U3R5bGVFbGVtZW50SW5zZXJ0ZWRBdFRvcC5uZXh0U2libGluZykge1xyXG5cdFx0XHRoZWFkLmluc2VydEJlZm9yZShzdHlsZUVsZW1lbnQsIGxhc3RTdHlsZUVsZW1lbnRJbnNlcnRlZEF0VG9wLm5leHRTaWJsaW5nKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcclxuXHRcdH1cclxuXHRcdHN0eWxlRWxlbWVudHNJbnNlcnRlZEF0VG9wLnB1c2goc3R5bGVFbGVtZW50KTtcclxuXHR9IGVsc2UgaWYgKG9wdGlvbnMuaW5zZXJ0QXQgPT09IFwiYm90dG9tXCIpIHtcclxuXHRcdGhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB2YWx1ZSBmb3IgcGFyYW1ldGVyICdpbnNlcnRBdCcuIE11c3QgYmUgJ3RvcCcgb3IgJ2JvdHRvbScuXCIpO1xyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlU3R5bGVFbGVtZW50KHN0eWxlRWxlbWVudCkge1xyXG5cdHN0eWxlRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudCk7XHJcblx0dmFyIGlkeCA9IHN0eWxlRWxlbWVudHNJbnNlcnRlZEF0VG9wLmluZGV4T2Yoc3R5bGVFbGVtZW50KTtcclxuXHRpZihpZHggPj0gMCkge1xyXG5cdFx0c3R5bGVFbGVtZW50c0luc2VydGVkQXRUb3Auc3BsaWNlKGlkeCwgMSk7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVTdHlsZUVsZW1lbnQob3B0aW9ucykge1xyXG5cdHZhciBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XHJcblx0c3R5bGVFbGVtZW50LnR5cGUgPSBcInRleHQvY3NzXCI7XHJcblx0aW5zZXJ0U3R5bGVFbGVtZW50KG9wdGlvbnMsIHN0eWxlRWxlbWVudCk7XHJcblx0cmV0dXJuIHN0eWxlRWxlbWVudDtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlTGlua0VsZW1lbnQob3B0aW9ucykge1xyXG5cdHZhciBsaW5rRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJsaW5rXCIpO1xyXG5cdGxpbmtFbGVtZW50LnJlbCA9IFwic3R5bGVzaGVldFwiO1xyXG5cdGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zLCBsaW5rRWxlbWVudCk7XHJcblx0cmV0dXJuIGxpbmtFbGVtZW50O1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRTdHlsZShvYmosIG9wdGlvbnMpIHtcclxuXHR2YXIgc3R5bGVFbGVtZW50LCB1cGRhdGUsIHJlbW92ZTtcclxuXHJcblx0aWYgKG9wdGlvbnMuc2luZ2xldG9uKSB7XHJcblx0XHR2YXIgc3R5bGVJbmRleCA9IHNpbmdsZXRvbkNvdW50ZXIrKztcclxuXHRcdHN0eWxlRWxlbWVudCA9IHNpbmdsZXRvbkVsZW1lbnQgfHwgKHNpbmdsZXRvbkVsZW1lbnQgPSBjcmVhdGVTdHlsZUVsZW1lbnQob3B0aW9ucykpO1xyXG5cdFx0dXBkYXRlID0gYXBwbHlUb1NpbmdsZXRvblRhZy5iaW5kKG51bGwsIHN0eWxlRWxlbWVudCwgc3R5bGVJbmRleCwgZmFsc2UpO1xyXG5cdFx0cmVtb3ZlID0gYXBwbHlUb1NpbmdsZXRvblRhZy5iaW5kKG51bGwsIHN0eWxlRWxlbWVudCwgc3R5bGVJbmRleCwgdHJ1ZSk7XHJcblx0fSBlbHNlIGlmKG9iai5zb3VyY2VNYXAgJiZcclxuXHRcdHR5cGVvZiBVUkwgPT09IFwiZnVuY3Rpb25cIiAmJlxyXG5cdFx0dHlwZW9mIFVSTC5jcmVhdGVPYmplY3RVUkwgPT09IFwiZnVuY3Rpb25cIiAmJlxyXG5cdFx0dHlwZW9mIFVSTC5yZXZva2VPYmplY3RVUkwgPT09IFwiZnVuY3Rpb25cIiAmJlxyXG5cdFx0dHlwZW9mIEJsb2IgPT09IFwiZnVuY3Rpb25cIiAmJlxyXG5cdFx0dHlwZW9mIGJ0b2EgPT09IFwiZnVuY3Rpb25cIikge1xyXG5cdFx0c3R5bGVFbGVtZW50ID0gY3JlYXRlTGlua0VsZW1lbnQob3B0aW9ucyk7XHJcblx0XHR1cGRhdGUgPSB1cGRhdGVMaW5rLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50KTtcclxuXHRcdHJlbW92ZSA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KTtcclxuXHRcdFx0aWYoc3R5bGVFbGVtZW50LmhyZWYpXHJcblx0XHRcdFx0VVJMLnJldm9rZU9iamVjdFVSTChzdHlsZUVsZW1lbnQuaHJlZik7XHJcblx0XHR9O1xyXG5cdH0gZWxzZSB7XHJcblx0XHRzdHlsZUVsZW1lbnQgPSBjcmVhdGVTdHlsZUVsZW1lbnQob3B0aW9ucyk7XHJcblx0XHR1cGRhdGUgPSBhcHBseVRvVGFnLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50KTtcclxuXHRcdHJlbW92ZSA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KTtcclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHR1cGRhdGUob2JqKTtcclxuXHJcblx0cmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZVN0eWxlKG5ld09iaikge1xyXG5cdFx0aWYobmV3T2JqKSB7XHJcblx0XHRcdGlmKG5ld09iai5jc3MgPT09IG9iai5jc3MgJiYgbmV3T2JqLm1lZGlhID09PSBvYmoubWVkaWEgJiYgbmV3T2JqLnNvdXJjZU1hcCA9PT0gb2JqLnNvdXJjZU1hcClcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdHVwZGF0ZShvYmogPSBuZXdPYmopO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmVtb3ZlKCk7XHJcblx0XHR9XHJcblx0fTtcclxufVxyXG5cclxudmFyIHJlcGxhY2VUZXh0ID0gKGZ1bmN0aW9uICgpIHtcclxuXHR2YXIgdGV4dFN0b3JlID0gW107XHJcblxyXG5cdHJldHVybiBmdW5jdGlvbiAoaW5kZXgsIHJlcGxhY2VtZW50KSB7XHJcblx0XHR0ZXh0U3RvcmVbaW5kZXhdID0gcmVwbGFjZW1lbnQ7XHJcblx0XHRyZXR1cm4gdGV4dFN0b3JlLmZpbHRlcihCb29sZWFuKS5qb2luKCdcXG4nKTtcclxuXHR9O1xyXG59KSgpO1xyXG5cclxuZnVuY3Rpb24gYXBwbHlUb1NpbmdsZXRvblRhZyhzdHlsZUVsZW1lbnQsIGluZGV4LCByZW1vdmUsIG9iaikge1xyXG5cdHZhciBjc3MgPSByZW1vdmUgPyBcIlwiIDogb2JqLmNzcztcclxuXHJcblx0aWYgKHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0KSB7XHJcblx0XHRzdHlsZUVsZW1lbnQuc3R5bGVTaGVldC5jc3NUZXh0ID0gcmVwbGFjZVRleHQoaW5kZXgsIGNzcyk7XHJcblx0fSBlbHNlIHtcclxuXHRcdHZhciBjc3NOb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY3NzKTtcclxuXHRcdHZhciBjaGlsZE5vZGVzID0gc3R5bGVFbGVtZW50LmNoaWxkTm9kZXM7XHJcblx0XHRpZiAoY2hpbGROb2Rlc1tpbmRleF0pIHN0eWxlRWxlbWVudC5yZW1vdmVDaGlsZChjaGlsZE5vZGVzW2luZGV4XSk7XHJcblx0XHRpZiAoY2hpbGROb2Rlcy5sZW5ndGgpIHtcclxuXHRcdFx0c3R5bGVFbGVtZW50Lmluc2VydEJlZm9yZShjc3NOb2RlLCBjaGlsZE5vZGVzW2luZGV4XSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRzdHlsZUVsZW1lbnQuYXBwZW5kQ2hpbGQoY3NzTm9kZSk7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBhcHBseVRvVGFnKHN0eWxlRWxlbWVudCwgb2JqKSB7XHJcblx0dmFyIGNzcyA9IG9iai5jc3M7XHJcblx0dmFyIG1lZGlhID0gb2JqLm1lZGlhO1xyXG5cclxuXHRpZihtZWRpYSkge1xyXG5cdFx0c3R5bGVFbGVtZW50LnNldEF0dHJpYnV0ZShcIm1lZGlhXCIsIG1lZGlhKVxyXG5cdH1cclxuXHJcblx0aWYoc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQpIHtcclxuXHRcdHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0LmNzc1RleHQgPSBjc3M7XHJcblx0fSBlbHNlIHtcclxuXHRcdHdoaWxlKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKSB7XHJcblx0XHRcdHN0eWxlRWxlbWVudC5yZW1vdmVDaGlsZChzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCk7XHJcblx0XHR9XHJcblx0XHRzdHlsZUVsZW1lbnQuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY3NzKSk7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVMaW5rKGxpbmtFbGVtZW50LCBvYmopIHtcclxuXHR2YXIgY3NzID0gb2JqLmNzcztcclxuXHR2YXIgc291cmNlTWFwID0gb2JqLnNvdXJjZU1hcDtcclxuXHJcblx0aWYoc291cmNlTWFwKSB7XHJcblx0XHQvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yNjYwMzg3NVxyXG5cdFx0Y3NzICs9IFwiXFxuLyojIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2Jhc2U2NCxcIiArIGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSkgKyBcIiAqL1wiO1xyXG5cdH1cclxuXHJcblx0dmFyIGJsb2IgPSBuZXcgQmxvYihbY3NzXSwgeyB0eXBlOiBcInRleHQvY3NzXCIgfSk7XHJcblxyXG5cdHZhciBvbGRTcmMgPSBsaW5rRWxlbWVudC5ocmVmO1xyXG5cclxuXHRsaW5rRWxlbWVudC5ocmVmID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcclxuXHJcblx0aWYob2xkU3JjKVxyXG5cdFx0VVJMLnJldm9rZU9iamVjdFVSTChvbGRTcmMpO1xyXG59XHJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcbiAqKiBtb2R1bGUgaWQgPSA0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGNvbmZpZyA9IHtcblxuICB3ZWV4VmVyc2lvbjogJzEuNC4wJyxcblxuICBkZWJ1ZzogdHJ1ZVxuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gY29uZmlnXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb25maWcuanNcbiAqKiBtb2R1bGUgaWQgPSA1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxuZnVuY3Rpb24gbG9hZEJ5WEhSKGNvbmZpZywgY2FsbGJhY2spIHtcbiAgaWYgKCFjb25maWcuc291cmNlKSB7XG4gICAgY2FsbGJhY2sobmV3IEVycm9yKCd4aHIgbG9hZGVyOiBtaXNzaW5nIGNvbmZpZy5zb3VyY2UuJykpXG4gIH1cbiAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gIHhoci5vcGVuKCdHRVQnLCBjb25maWcuc291cmNlKVxuICB4aHIub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIGNhbGxiYWNrKG51bGwsIHRoaXMucmVzcG9uc2VUZXh0KVxuICB9XG4gIHhoci5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgY2FsbGJhY2soZXJyb3IpXG4gIH1cbiAgeGhyLnNlbmQoKVxufVxuXG5mdW5jdGlvbiBsb2FkQnlKc29ucChjb25maWcsIGNhbGxiYWNrKSB7XG4gIGlmICghY29uZmlnLnNvdXJjZSkge1xuICAgIGNhbGxiYWNrKG5ldyBFcnJvcignanNvbnAgbG9hZGVyOiBtaXNzaW5nIGNvbmZpZy5zb3VyY2UuJykpXG4gIH1cbiAgdmFyIGNhbGxiYWNrTmFtZSA9IGNvbmZpZy5qc29ucENhbGxiYWNrIHx8ICd3ZWV4SnNvbnBDYWxsYmFjaydcbiAgd2luZG93W2NhbGxiYWNrTmFtZV0gPSBmdW5jdGlvbiAoY29kZSkge1xuICAgIGlmIChjb2RlKSB7XG4gICAgICBjYWxsYmFjayhudWxsLCBjb2RlKVxuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjayhuZXcgRXJyb3IoJ2xvYWQgYnkganNvbnAgZXJyb3InKSlcbiAgICB9XG4gIH1cbiAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpXG4gIHNjcmlwdC5zcmMgPSBkZWNvZGVVUklDb21wb25lbnQoY29uZmlnLnNvdXJjZSlcbiAgc2NyaXB0LnR5cGUgPSAndGV4dC9qYXZhc2NyaXB0J1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHNjcmlwdClcbn1cblxuZnVuY3Rpb24gbG9hZEJ5U291cmNlQ29kZShjb25maWcsIGNhbGxiYWNrKSB7XG4gIC8vIHNyYyBpcyB0aGUganNidW5kbGUuXG4gIC8vIG5vIG5lZWQgdG8gZmV0Y2ggZnJvbSBhbnl3aGVyZS5cbiAgaWYgKGNvbmZpZy5zb3VyY2UpIHtcbiAgICBjYWxsYmFjayhudWxsLCBjb25maWcuc291cmNlKVxuICB9IGVsc2Uge1xuICAgIGNhbGxiYWNrKG5ldyBFcnJvcignc291cmNlIGNvZGUgbGFvZGVyOiBtaXNzaW5nIGNvbmZpZy5zb3VyY2UuJykpXG4gIH1cbn1cblxudmFyIGNhbGxiYWNrTWFwID0ge1xuICB4aHI6IGxvYWRCeVhIUixcbiAganNvbnA6IGxvYWRCeUpzb25wLFxuICBzb3VyY2U6IGxvYWRCeVNvdXJjZUNvZGVcbn1cblxuZnVuY3Rpb24gbG9hZChvcHRpb25zLCBjYWxsYmFjaykge1xuICB2YXIgbG9hZEZuID0gY2FsbGJhY2tNYXBbb3B0aW9ucy5sb2FkZXJdXG4gIGxvYWRGbihvcHRpb25zLCBjYWxsYmFjaylcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJMb2FkZXIobmFtZSwgbG9hZGVyRnVuYykge1xuICBpZiAodHlwZW9mIGxvYWRlckZ1bmMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFja01hcFtuYW1lXSA9IGxvYWRlckZ1bmNcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbG9hZDogbG9hZCxcbiAgcmVnaXN0ZXJMb2FkZXI6IHJlZ2lzdGVyTG9hZGVyXG59XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2xvYWRlci5qc1xuICoqIG1vZHVsZSBpZCA9IDZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgV0VBUFBfU1RZTEVfSUQgPSAnd2VhcHAtc3R5bGUnXG5cbnZhciBfaXNXZWJwU3VwcG9ydGVkID0gZmFsc2VcblxuOyAoZnVuY3Rpb24gaXNTdXBwb3J0V2VicCgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgd2ViUCA9IG5ldyBJbWFnZSgpXG4gICAgd2ViUC5zcmMgPSAnZGF0YTppbWFnZS93ZWJwO2Jhc2U2NCxVa2xHUmpvQUFBQlhSVUpRVmxBNElDNEFBQUN5QWdDZEEnXG4gICAgICAgICAgICAgICsgJ1NvQ0FBSUFMbWswbWswaUlpSWlJZ0JvU3lnQUJjNldXZ0FBL3ZlZmYvMFBQOGJBLy9Md1lBQUEnXG4gICAgd2ViUC5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAod2ViUC5oZWlnaHQgPT09IDIpIHtcbiAgICAgICAgX2lzV2VicFN1cHBvcnRlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBkbyBub3RoaW5nLlxuICB9XG59KSgpXG5cbmZ1bmN0aW9uIGV4dGVuZCh0bywgZnJvbSkge1xuICBmb3IgKHZhciBrZXkgaW4gZnJvbSkge1xuICAgIHRvW2tleV0gPSBmcm9tW2tleV1cbiAgfVxuICByZXR1cm4gdG9cbn1cblxuZnVuY3Rpb24gaXNBcnJheShhcnIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXlcbiAgICA/IEFycmF5LmlzQXJyYXkoYXJyKVxuICAgIDogKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcnIpID09PSAnW29iamVjdCBBcnJheV0nKVxufVxuXG5mdW5jdGlvbiBhcHBlbmRTdHlsZShjc3MsIHN0eWxlSWQsIHJlcGxhY2UpIHtcbiAgdmFyIHN0eWxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3R5bGVJZClcbiAgaWYgKHN0eWxlICYmIHJlcGxhY2UpIHtcbiAgICBzdHlsZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlKVxuICAgIHN0eWxlID0gbnVsbFxuICB9XG4gIGlmICghc3R5bGUpIHtcbiAgICBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJylcbiAgICBzdHlsZS50eXBlID0gJ3RleHQvY3NzJ1xuICAgIHN0eWxlSWQgJiYgKHN0eWxlLmlkID0gc3R5bGVJZClcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLmFwcGVuZENoaWxkKHN0eWxlKVxuICB9XG4gIHN0eWxlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpXG59XG5cbmZ1bmN0aW9uIGdldFVuaXF1ZUZyb21BcnJheShhcnIpIHtcbiAgaWYgKCFpc0FycmF5KGFycikpIHtcbiAgICByZXR1cm4gW11cbiAgfVxuICB2YXIgcmVzID0gW11cbiAgdmFyIHVuaXF1ZSA9IHt9XG4gIHZhciB2YWxcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBhcnIubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdmFsID0gYXJyW2ldXG4gICAgaWYgKHVuaXF1ZVt2YWxdKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICB1bmlxdWVbdmFsXSA9IHRydWVcbiAgICByZXMucHVzaCh2YWwpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiB0cmFuc2l0aW9uaXplKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciB0cmFuc2l0aW9ucyA9IFtdXG4gIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgIHRyYW5zaXRpb25zLnB1c2goa2V5ICsgJyAnICsgcHJvcHNba2V5XSlcbiAgfVxuICBlbGVtZW50LnN0eWxlLnRyYW5zaXRpb24gPSB0cmFuc2l0aW9ucy5qb2luKCcsICcpXG4gIGVsZW1lbnQuc3R5bGUud2Via2l0VHJhbnNpdGlvbiA9IHRyYW5zaXRpb25zLmpvaW4oJywgJylcbn1cblxuZnVuY3Rpb24gZGV0ZWN0V2VicCgpIHtcbiAgcmV0dXJuIF9pc1dlYnBTdXBwb3J0ZWRcbn1cblxuZnVuY3Rpb24gZ2V0UmFuZG9tKG51bSkge1xuICB2YXIgX2RlZmF1bHROdW0gPSAxMFxuICBpZiAodHlwZW9mIG51bSAhPT0gJ251bWJlcicgfHwgbnVtIDw9IDApIHtcbiAgICBudW0gPSBfZGVmYXVsdE51bVxuICB9XG4gIHZhciBfbWF4ID0gTWF0aC5wb3coMTAsIG51bSlcbiAgcmV0dXJuIE1hdGguZmxvb3IoRGF0ZS5ub3coKSArIE1hdGgucmFuZG9tKCkgKiBfbWF4KSAlIF9tYXhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGV4dGVuZDogZXh0ZW5kLFxuICBpc0FycmF5OiBpc0FycmF5LFxuICBhcHBlbmRTdHlsZTogYXBwZW5kU3R5bGUsXG4gIGdldFVuaXF1ZUZyb21BcnJheTogZ2V0VW5pcXVlRnJvbUFycmF5LFxuICB0cmFuc2l0aW9uaXplOiB0cmFuc2l0aW9uaXplLFxuICBkZXRlY3RXZWJwOiBkZXRlY3RXZWJwLFxuICBnZXRSYW5kb206IGdldFJhbmRvbVxufVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvdXRpbHMuanNcbiAqKiBtb2R1bGUgaWQgPSA3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGV4dGVuZCA9IHJlcXVpcmUoJy4vdXRpbHMnKS5leHRlbmRcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnLi91dGlscycpLmlzQXJyYXlcbnZhciBDb21wb25lbnRNYW5hZ2VyID0gcmVxdWlyZSgnLi9jb21wb25lbnRNYW5hZ2VyJylcblxuLy8gZm9yIGpzZnJhbWV3b3JrIHRvIHJlZ2lzdGVyIG1vZHVsZXMuXG52YXIgX3JlZ2lzdGVyTW9kdWxlcyA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgaWYgKGlzQXJyYXkoY29uZmlnKSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gY29uZmlnLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgd2luZG93LnJlZ2lzdGVyTW9kdWxlcyhjb25maWdbaV0pXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHdpbmRvdy5yZWdpc3Rlck1vZHVsZXMoY29uZmlnKVxuICB9XG59XG5cbnZhciBwcm90b2NvbCA9IHtcblxuICAvLyB3ZWV4IGluc3RhbmNlc1xuICBfaW5zdGFuY2VzOiBbXSxcblxuICAvLyBhcGkgbWV0YSBpbmZvXG4gIF9tZXRhOiBbXSxcblxuICBhcGlNb2R1bGU6IHt9LFxuXG4gIGluamVjdFdlZXhJbnN0YW5jZTogZnVuY3Rpb24gKGluc3RhbmNlKSB7XG4gICAgdGhpcy5faW5zdGFuY2VzW2luc3RhbmNlLmluc3RhbmNlSWRdID0gaW5zdGFuY2VcbiAgfSxcblxuICBnZXRXZWV4SW5zdGFuY2U6IGZ1bmN0aW9uIChpbnN0YW5jZUlkKSB7XG4gICAgcmV0dXJuIHRoaXMuX2luc3RhbmNlc1tpbnN0YW5jZUlkXVxuICB9LFxuXG4gIC8vIGdldCB0aGUgYXBpIG1ldGhvZCBtZXRhIGluZm8gYXJyYXkgZm9yIHRoZSBtb2R1bGUuXG4gIGdldEFwaU1vZHVsZU1ldGE6IGZ1bmN0aW9uIChtb2R1bGVOYW1lKSB7XG4gICAgdmFyIG1ldGFPYmogPSB7fVxuICAgIG1ldGFPYmpbbW9kdWxlTmFtZV0gPSB0aGlzLl9tZXRhW21vZHVsZU5hbWVdXG4gICAgcmV0dXJuIG1ldGFPYmpcbiAgfSxcblxuICAvLyBTZXQgbWV0YSBpbmZvIGZvciBhIGFwaSBtb2R1bGUuXG4gIC8vIElmIHRoZXJlIGlzIGEgc2FtZSBuYW1lZCBhcGksIGp1c3QgcmVwbGFjZSBpdC5cbiAgLy8gb3B0czpcbiAgLy8gLSBtZXRhT2JqOiBtZXRhIG9iamVjdCBsaWtlXG4gIC8vIHtcbiAgLy8gICAgZG9tOiBbe1xuICAvLyAgICAgIG5hbWU6ICdhZGRFbGVtZW50JyxcbiAgLy8gICAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnXVxuICAvLyAgICB9XVxuICAvLyB9XG4gIHNldEFwaU1vZHVsZU1ldGE6IGZ1bmN0aW9uIChtZXRhT2JqKSB7XG4gICAgdmFyIG1vZHVsZU5hbWVcbiAgICBmb3IgKHZhciBrIGluIG1ldGFPYmopIHtcbiAgICAgIGlmIChtZXRhT2JqLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgIG1vZHVsZU5hbWUgPSBrXG4gICAgICB9XG4gICAgfVxuICAgIHZhciBtZXRhQXJyYXkgPSB0aGlzLl9tZXRhW21vZHVsZU5hbWVdXG4gICAgaWYgKCFtZXRhQXJyYXkpIHtcbiAgICAgIHRoaXMuX21ldGFbbW9kdWxlTmFtZV0gPSBtZXRhT2JqW21vZHVsZU5hbWVdXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBuYW1lT2JqID0ge31cbiAgICAgIG1ldGFPYmpbbW9kdWxlTmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoYXBpKSB7XG4gICAgICAgIG5hbWVPYmpbYXBpLm5hbWVdID0gYXBpXG4gICAgICB9KVxuICAgICAgbWV0YUFycmF5LmZvckVhY2goZnVuY3Rpb24gKGFwaSwgaSkge1xuICAgICAgICBpZiAobmFtZU9ialthcGkubmFtZV0pIHtcbiAgICAgICAgICBtZXRhQXJyYXlbaV0gPSBuYW1lT2JqW2FwaS5uYW1lXVxuICAgICAgICAgIGRlbGV0ZSBuYW1lT2JqW2FwaS5uYW1lXVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgZm9yICh2YXIgayBpbiBtZXRhT2JqKSB7XG4gICAgICAgIGlmIChtZXRhT2JqLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgbWV0YUFycmF5LnB1c2gobWV0YU9ialtrXSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLl9tZXRhW21vZHVsZU5hbWVdID0gbWV0YU9ialttb2R1bGVOYW1lXVxuICB9LFxuXG4gIC8vIFNldCBtZXRhIGluZm8gZm9yIGEgc2luZ2xlIGFwaS5cbiAgLy8gb3B0czpcbiAgLy8gIC0gbW9kdWxlTmFtZTogYXBpIG1vZHVsZSBuYW1lLlxuICAvLyAgLSBtZXRhOiBhIG1ldGEgb2JqZWN0IGxpa2U6XG4gIC8vICB7XG4gIC8vICAgIG5hbWU6ICdhZGRFbGVtZW50JyxcbiAgLy8gICAgYXJnczogWydzdHJpbmcnLCAnb2JqZWN0J11cbiAgLy8gIH1cbiAgc2V0QXBpTWV0YTogZnVuY3Rpb24gKG1vZHVsZU5hbWUsIG1ldGEpIHtcbiAgICB2YXIgbWV0YUFycmF5ID0gdGhpcy5fbWV0YVttb2R1bGVOYW1lXVxuICAgIGlmICghbWV0YUFycmF5KSB7XG4gICAgICB0aGlzLl9tZXRhW21vZHVsZU5hbWVdID0gW21ldGFdXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBtZXRhSWR4ID0gLTFcbiAgICAgIG1ldGFBcnJheS5mb3JFYWNoKGZ1bmN0aW9uIChhcGksIGkpIHtcbiAgICAgICAgaWYgKG1ldGEubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICAgIG1ldGFJZHggPSBpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBpZiAobWV0YUlkeCAhPT0gLTEpIHtcbiAgICAgICAgbWV0YUFycmF5W21ldGFJZHhdID0gbWV0YVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWV0YUFycmF5LnB1c2gobWV0YSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuX3JlZ2lzdGVyTW9kdWxlcyhbe1xuICBtb2RhbDogW3tcbiAgICBuYW1lOiAndG9hc3QnLFxuICAgIGFyZ3M6IFsnb2JqZWN0JywgJ2Z1bmN0aW9uJ11cbiAgfSwge1xuICAgIG5hbWU6ICdhbGVydCcsXG4gICAgYXJnczogWydvYmplY3QnLCAnZnVuY3Rpb24nXVxuICB9LCB7XG4gICAgbmFtZTogJ2NvbmZpcm0nLFxuICAgIGFyZ3M6IFsnb2JqZWN0JywgJ2Z1bmN0aW9uJ11cbiAgfSwge1xuICAgIG5hbWU6ICdwcm9tcHQnLFxuICAgIGFyZ3M6IFsnb2JqZWN0JywgJ2Z1bmN0aW9uJ11cbiAgfV1cbn0sIHtcbiAgYW5pbWF0aW9uOiBbe1xuICAgIG5hbWU6ICd0cmFuc2l0aW9uJyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnLCAnZnVuY3Rpb24nXVxuICB9XVxufV0pXG5cbm1vZHVsZS5leHBvcnRzID0gcHJvdG9jb2xcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvcHJvdG9jb2wuanNcbiAqKiBtb2R1bGUgaWQgPSA4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJylcbnZhciBGcmFtZVVwZGF0ZXIgPSByZXF1aXJlKCcuL2ZyYW1lVXBkYXRlcicpXG52YXIgQXBwZWFyV2F0Y2hlciA9IHJlcXVpcmUoJy4vYXBwZWFyV2F0Y2hlcicpXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJylcbnZhciBMYXp5TG9hZCA9IHJlcXVpcmUoJy4vbGF6eUxvYWQnKVxudmFyIGFuaW1hdGlvbiA9IHJlcXVpcmUoJy4vYW5pbWF0aW9uJylcblxudmFyIFJFTkRFUklOR19JTkRFTlQgPSA4MDBcblxudmFyIF9pbnN0YW5jZU1hcCA9IHt9XG52YXIgdHlwZU1hcCA9IHt9XG52YXIgc2Nyb2xsYWJsZVR5cGVzID0gWydzY3JvbGxlcicsICdsaXN0J11cblxuZnVuY3Rpb24gQ29tcG9uZW50TWFuYWdlcihpbnN0YW5jZSkge1xuICB0aGlzLmluc3RhbmNlSWQgPSBpbnN0YW5jZS5pbnN0YW5jZUlkXG4gIHRoaXMud2VleEluc3RhbmNlID0gaW5zdGFuY2VcbiAgdGhpcy5jb21wb25lbnRNYXAgPSB7fVxuICBfaW5zdGFuY2VNYXBbdGhpcy5pbnN0YW5jZUlkXSA9IHRoaXNcbn1cblxuQ29tcG9uZW50TWFuYWdlci5nZXRJbnN0YW5jZSA9IGZ1bmN0aW9uIChpbnN0YW5jZUlkKSB7XG4gIHJldHVybiBfaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbn1cblxuQ29tcG9uZW50TWFuYWdlci5nZXRXZWV4SW5zdGFuY2UgPSBmdW5jdGlvbiAoaW5zdGFuY2VJZCkge1xuICByZXR1cm4gX2luc3RhbmNlTWFwW2luc3RhbmNlSWRdLndlZXhJbnN0YW5jZVxufVxuXG5Db21wb25lbnRNYW5hZ2VyLnJlZ2lzdGVyQ29tcG9uZW50ID0gZnVuY3Rpb24gKHR5cGUsIGRlZmluaXRpb24pIHtcbiAgdHlwZU1hcFt0eXBlXSA9IGRlZmluaXRpb25cbn1cblxuQ29tcG9uZW50TWFuYWdlci5nZXRTY3JvbGxhYmxlVHlwZXMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBzY3JvbGxhYmxlVHlwZXNcbn1cblxuQ29tcG9uZW50TWFuYWdlci5wcm90b3R5cGUgPSB7XG5cbiAgLy8gRmlyZSBhIGV2ZW50ICdyZW5kZXJiZWdpbicvJ3JlbmRlcmVuZCcgb24gYm9keSBlbGVtZW50LlxuICByZW5kZXJpbmc6IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBfcmVuZGVyaW5nRW5kKCkge1xuICAgICAgLy8gZ2V0IHdlZXggaW5zdGFuY2Ugcm9vdFxuICAgICAgd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdyZW5kZXJlbmQnKSlcbiAgICAgIHRoaXMuX3JlbmRlcmluZ1RpbWVyID0gbnVsbFxuICAgIH1cbiAgICBpZiAodGhpcy5fcmVuZGVyaW5nVGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9yZW5kZXJpbmdUaW1lcilcbiAgICAgIHRoaXMuX3JlbmRlcmluZ1RpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgX3JlbmRlcmluZ0VuZC5iaW5kKHRoaXMpLFxuICAgICAgICBSRU5ERVJJTkdfSU5ERU5UXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgncmVuZGVyYmVnaW4nKSlcbiAgICAgIHRoaXMuX3JlbmRlcmluZ1RpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgX3JlbmRlcmluZ0VuZC5iaW5kKHRoaXMpLFxuICAgICAgICBSRU5ERVJJTkdfSU5ERU5UXG4gICAgICApXG4gICAgfVxuICB9LFxuXG4gIGdldEVsZW1lbnRCeVJlZjogZnVuY3Rpb24gKHJlZikge1xuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudE1hcFtyZWZdXG4gIH0sXG5cbiAgcmVtb3ZlRWxlbWVudEJ5UmVmOiBmdW5jdGlvbiAocmVmKSB7XG4gICAgdmFyIGNtcFxuICAgIHZhciBzZWxmID0gdGhpc1xuICAgIGlmICghcmVmIHx8ICEoY21wID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXSkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICAvLyByZW1vdmUgZnJvbSB0aGlzLmNvbXBvbmVudE1hcCBjdXJzaXZlbHlcbiAgICAoZnVuY3Rpb24gX3JlbW92ZUN1cnNpdmVseShfcmVmKSB7XG4gICAgICB2YXIgY2hpbGQgPSBzZWxmLmNvbXBvbmVudE1hcFtfcmVmXVxuICAgICAgdmFyIGxpc3RlbmVycyA9IGNoaWxkLl9saXN0ZW5lcnNcbiAgICAgIHZhciBjaGlsZHJlbiA9IGNoaWxkLmRhdGEuY2hpbGRyZW5cbiAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICBfcmVtb3ZlQ3Vyc2l2ZWx5KGNoaWxkcmVuW2ldLnJlZilcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gcmVtb3ZlIGV2ZW50cyBmcm9tIF9yZWYgY29tcG9uZW50XG4gICAgICBpZiAobGlzdGVuZXJzKSB7XG4gICAgICAgIGZvciAodmFyIHR5cGUgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgY2hpbGQubm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1t0eXBlXSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZGVsZXRlIGNoaWxkLl9saXN0ZW5lcnNcbiAgICAgIGRlbGV0ZSBjaGlsZC5ub2RlLl9saXN0ZW5lcnNcbiAgICAgIC8vIHJlbW92ZSBfcmVmIGNvbXBvbmVudFxuICAgICAgZGVsZXRlIHNlbGYuY29tcG9uZW50TWFwW19yZWZdXG4gICAgfSkocmVmKVxuXG4gIH0sXG5cbiAgY3JlYXRlRWxlbWVudDogZnVuY3Rpb24gKGRhdGEsIG5vZGVUeXBlKSB7XG4gICAgdmFyIENvbXBvbmVudFR5cGUgPSB0eXBlTWFwW2RhdGEudHlwZV1cbiAgICBpZiAoIUNvbXBvbmVudFR5cGUpIHtcbiAgICAgIENvbXBvbmVudFR5cGUgPSB0eXBlTWFwWydjb250YWluZXInXVxuICAgIH1cblxuICAgIHZhciByZWYgPSBkYXRhLnJlZlxuICAgIHZhciBjb21wb25lbnQgPSBuZXcgQ29tcG9uZW50VHlwZShkYXRhLCBub2RlVHlwZSlcblxuICAgIHRoaXMuY29tcG9uZW50TWFwW3JlZl0gPSBjb21wb25lbnRcbiAgICBjb21wb25lbnQubm9kZS5zZXRBdHRyaWJ1dGUoJ2RhdGEtcmVmJywgcmVmKVxuXG4gICAgcmV0dXJuIGNvbXBvbmVudFxuICB9LFxuXG4gIC8qKlxuICAgKiBjcmVhdGVCb2R5OiBnZW5lcmF0ZSByb290IGNvbXBvbmVudFxuICAgKiBAcGFyYW0gIHtvYmplY3R9IGVsZW1lbnRcbiAgICovXG4gIGNyZWF0ZUJvZHk6IGZ1bmN0aW9uIChlbGVtZW50KSB7XG5cbiAgICAvLyBUT0RPOiBjcmVhdGJvZHkgb24gZG9jdW1lbnQuYm9keVxuICAgIC8vIG5vIG5lZWQgdG8gY3JlYXRlIGEgZXh0cmEgZGl2XG4gICAgdmFyIHJvb3QsIGJvZHksIG5vZGVUeXBlXG4gICAgaWYgKHRoaXMuY29tcG9uZW50TWFwWydfcm9vdCddKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBub2RlVHlwZSA9IGVsZW1lbnQudHlwZVxuICAgIGVsZW1lbnQudHlwZSA9ICdyb290J1xuICAgIGVsZW1lbnQucm9vdElkID0gdGhpcy53ZWV4SW5zdGFuY2Uucm9vdElkXG4gICAgZWxlbWVudC5yZWYgPSAnX3Jvb3QnXG5cbiAgICB2YXIgcm9vdCA9IHRoaXMuY3JlYXRlRWxlbWVudChlbGVtZW50LCBub2RlVHlwZSlcbiAgICBib2R5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignIycgKyB0aGlzLndlZXhJbnN0YW5jZS5yb290SWQpXG4gICAgICAgICAgfHwgZG9jdW1lbnQuYm9keVxuICAgIGJvZHkuYXBwZW5kQ2hpbGQocm9vdC5ub2RlKVxuICAgIHJvb3QuX2FwcGVuZGVkID0gdHJ1ZVxuICB9LFxuXG4gIGFwcGVuZENoaWxkOiBmdW5jdGlvbiAocGFyZW50UmVmLCBkYXRhKSB7XG4gICAgdmFyIHBhcmVudCA9IHRoaXMuY29tcG9uZW50TWFwW3BhcmVudFJlZl1cblxuICAgIGlmICh0aGlzLmNvbXBvbmVudE1hcFtkYXRhLnJlZl0gfHwgIXBhcmVudCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHBhcmVudFJlZiA9PT0gJ19yb290JyAmJiAhcGFyZW50KSB7XG4gICAgICBwYXJlbnQgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoe1xuICAgICAgICB0eXBlOiAncm9vdCcsXG4gICAgICAgIHJvb3RJZDogdGhpcy53ZWV4SW5zdGFuY2Uucm9vdElkLFxuICAgICAgICByZWY6ICdfcm9vdCdcbiAgICAgIH0pXG4gICAgICBwYXJlbnQuX2FwcGVuZGVkID0gdHJ1ZVxuICAgIH1cblxuICAgIHZhciBjaGlsZCA9IHBhcmVudC5hcHBlbmRDaGlsZChkYXRhKVxuXG4gICAgLy8gSW4gc29tZSBwYXJlbnQgY29tcG9uZW50IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RcbiAgICAvLyBhcHBlbmRDaGlsZCBkaWRuJ3QgcmV0dXJuIHRoZSBjb21wb25lbnQgYXQgYWxsLCB0aGVyZWZvclxuICAgIC8vIGNoaWxkIG1heWJlIGEgdW5kZWZpbmVkIG9iamVjdC5cbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIGNoaWxkLnBhcmVudFJlZiA9IHBhcmVudFJlZlxuICAgIH1cblxuICAgIGlmIChjaGlsZCAmJiBwYXJlbnQuX2FwcGVuZGVkKSB7XG4gICAgICB0aGlzLmhhbmRsZUFwcGVuZChjaGlsZClcbiAgICB9XG4gIH0sXG5cbiAgYXBwZW5kQ2hpbGRyZW46IGZ1bmN0aW9uIChyZWYsIGVsZW1lbnRzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5hcHBlbmRDaGlsZChyZWYsIGVsZW1lbnRzW2ldKVxuICAgIH1cbiAgfSxcblxuICByZW1vdmVFbGVtZW50OiBmdW5jdGlvbiAocmVmKSB7XG4gICAgdmFyIGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50TWFwW3JlZl1cblxuICAgIC8vIGZpcmUgZXZlbnQgZm9yIHJlbmRlcmluZyBkb20gb24gYm9keSBlbG1lbnQuXG4gICAgdGhpcy5yZW5kZXJpbmcoKVxuXG4gICAgaWYgKGNvbXBvbmVudCAmJiBjb21wb25lbnQucGFyZW50UmVmKSB7XG4gICAgICB2YXIgcGFyZW50ID0gdGhpcy5jb21wb25lbnRNYXBbY29tcG9uZW50LnBhcmVudFJlZl1cbiAgICAgIGNvbXBvbmVudC5vblJlbW92ZSAmJiBjb21wb25lbnQub25SZW1vdmUoKVxuICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKGNvbXBvbmVudClcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS53YXJuKCdyZWY6ICcsIHJlZilcbiAgICB9XG4gIH0sXG5cbiAgbW92ZUVsZW1lbnQ6IGZ1bmN0aW9uIChyZWYsIHBhcmVudFJlZiwgaW5kZXgpIHtcbiAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXVxuICAgIHZhciBuZXdQYXJlbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtwYXJlbnRSZWZdXG4gICAgdmFyIG9sZFBhcmVudFJlZiA9IGNvbXBvbmVudC5wYXJlbnRSZWZcbiAgICB2YXIgY2hpbGRyZW4sIGJlZm9yZSwgaSwgbFxuICAgIGlmICghY29tcG9uZW50IHx8ICFuZXdQYXJlbnQpIHtcbiAgICAgIGNvbnNvbGUud2FybigncmVmOiAnLCByZWYpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBmaXJlIGV2ZW50IGZvciByZW5kZXJpbmcgZG9tIG9uIGJvZHkgZWxtZW50LlxuICAgIHRoaXMucmVuZGVyaW5nKClcblxuICAgIC8vIHJlbW92ZSBmcm9tIG9sZFBhcmVudC5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKG9sZFBhcmVudFJlZiAmJiB0aGlzLmNvbXBvbmVudE1hcFtvbGRQYXJlbnRSZWZdKSB7XG4gICAgICBjaGlsZHJlbiA9IHRoaXMuY29tcG9uZW50TWFwW29sZFBhcmVudFJlZl0uZGF0YS5jaGlsZHJlblxuICAgICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICBmb3IgKGkgPSAwLCBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGNoaWxkcmVuW2ldLnJlZiA9PT0gcmVmKSB7XG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobCA+IGkpIHtcbiAgICAgICAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpbmRleCA8IC0xKSB7XG4gICAgICBpbmRleCA9IC0xXG4gICAgICBjb25zb2xlLndhcm4oJ2luZGV4IGNhbm5vdCBiZSBsZXNzIHRoYW4gLTEuJylcbiAgICB9XG5cbiAgICBjaGlsZHJlbiA9IG5ld1BhcmVudC5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKGNoaWxkcmVuXG4gICAgICAgICYmIGNoaWxkcmVuLmxlbmd0aFxuICAgICAgICAmJiBpbmRleCAhPT0gLTFcbiAgICAgICAgJiYgaW5kZXggPCBjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIGJlZm9yZSA9IHRoaXMuY29tcG9uZW50TWFwW25ld1BhcmVudC5kYXRhLmNoaWxkcmVuW2luZGV4XS5yZWZdXG4gICAgICBuZXdQYXJlbnQuaW5zZXJ0QmVmb3JlKGNvbXBvbmVudCwgYmVmb3JlKVxuICAgIH0gZWxzZSB7ICAvLyBhcHBlbmRcbiAgICAgIG5ld1BhcmVudC5pbnNlcnRCZWZvcmUoY29tcG9uZW50KVxuICAgIH1cblxuICAgIGNvbXBvbmVudC5vbk1vdmUgJiYgY29tcG9uZW50Lm9uTW92ZShwYXJlbnRSZWYsIGluZGV4KVxuXG4gIH0sXG5cbiAgaW5zZXJ0QmVmb3JlOiBmdW5jdGlvbiAocmVmLCBkYXRhKSB7XG4gICAgdmFyIGNoaWxkLCBiZWZvcmUsIHBhcmVudFxuICAgIGJlZm9yZSA9IHRoaXMuY29tcG9uZW50TWFwW3JlZl1cbiAgICBjaGlsZCA9IHRoaXMuY29tcG9uZW50TWFwW2RhdGEucmVmXVxuICAgIGJlZm9yZSAmJiAocGFyZW50ID0gdGhpcy5jb21wb25lbnRNYXBbYmVmb3JlLnBhcmVudFJlZl0pXG4gICAgaWYgKGNoaWxkIHx8ICFwYXJlbnQgfHwgIWJlZm9yZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY2hpbGQgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoZGF0YSlcbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIGNoaWxkLnBhcmVudFJlZiA9IGJlZm9yZS5wYXJlbnRSZWZcbiAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGQsIGJlZm9yZSlcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29tcG9uZW50TWFwW2JlZm9yZS5wYXJlbnRSZWZdLl9hcHBlbmRlZCkge1xuICAgICAgdGhpcy5oYW5kbGVBcHBlbmQoY2hpbGQpXG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBhZGRFbGVtZW50XG4gICAqIElmIGluZGV4IGlzIGxhcmdldCB0aGFuIGFueSBjaGlsZCdzIGluZGV4LCB0aGVcbiAgICogZWxlbWVudCB3aWxsIGJlIGFwcGVuZGVkIGJlaGluZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmVudFJlZlxuICAgKiBAcGFyYW0ge29ian0gZWxlbWVudCAoZGF0YSBvZiB0aGUgY29tcG9uZW50KVxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAgICovXG4gIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uIChwYXJlbnRSZWYsIGVsZW1lbnQsIGluZGV4KSB7XG4gICAgdmFyIHBhcmVudCwgY2hpbGRyZW4sIGJlZm9yZVxuXG4gICAgLy8gZmlyZSBldmVudCBmb3IgcmVuZGVyaW5nIGRvbSBvbiBib2R5IGVsbWVudC5cbiAgICB0aGlzLnJlbmRlcmluZygpXG5cbiAgICBwYXJlbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtwYXJlbnRSZWZdXG4gICAgaWYgKCFwYXJlbnQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjaGlsZHJlbiA9IHBhcmVudC5kYXRhLmNoaWxkcmVuXG4gICAgLy8gLTEgbWVhbnMgYXBwZW5kIGFzIHRoZSBsYXN0LlxuICAgIGlmIChpbmRleCA8IC0xKSB7XG4gICAgICBpbmRleCA9IC0xXG4gICAgICBjb25zb2xlLndhcm4oJ2luZGV4IGNhbm5vdCBiZSBsZXNzIHRoYW4gLTEuJylcbiAgICB9XG4gICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aFxuICAgICAgICAmJiBjaGlsZHJlbi5sZW5ndGggPiBpbmRleFxuICAgICAgICAmJiBpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuaW5zZXJ0QmVmb3JlKGNoaWxkcmVuW2luZGV4XS5yZWYsIGVsZW1lbnQpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQocGFyZW50UmVmLCBlbGVtZW50KVxuICAgIH1cbiAgfSxcblxuICBjbGVhckNoaWxkcmVuOiBmdW5jdGlvbiAocmVmKSB7XG4gICAgdmFyIGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50TWFwW3JlZl1cbiAgICBpZiAoY29tcG9uZW50KSB7XG4gICAgICBjb21wb25lbnQubm9kZS5pbm5lckhUTUwgPSAnJ1xuICAgICAgaWYgKGNvbXBvbmVudC5kYXRhKSB7XG4gICAgICAgIGNvbXBvbmVudC5kYXRhLmNoaWxkcmVuID0gbnVsbFxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBhZGRFdmVudDogZnVuY3Rpb24gKHJlZiwgdHlwZSkge1xuICAgIHZhciBjb21wb25lbnRcbiAgICBpZiAodHlwZW9mIHJlZiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHJlZiA9PT0gJ251bWJlcicpIHtcbiAgICAgIGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50TWFwW3JlZl1cbiAgICB9IGVsc2UgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChyZWYpLnNsaWNlKDgsIC0xKSA9PT0gJ09iamVjdCcpIHtcbiAgICAgIGNvbXBvbmVudCA9IHJlZlxuICAgICAgcmVmID0gY29tcG9uZW50LmRhdGEucmVmXG4gICAgfVxuICAgIGlmIChjb21wb25lbnQgJiYgY29tcG9uZW50Lm5vZGUpIHtcbiAgICAgIHZhciBzZW5kZXIgPSB0aGlzLndlZXhJbnN0YW5jZS5zZW5kZXJcbiAgICAgIHZhciBsaXN0ZW5lciA9IHNlbmRlci5maXJlRXZlbnQuYmluZChzZW5kZXIsIHJlZiwgdHlwZSlcbiAgICAgIHZhciBsaXN0ZW5lcnMgPSBjb21wb25lbnQuX2xpc3RlbmVyc1xuICAgICAgY29tcG9uZW50Lm5vZGUuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgZmFsc2UsIGZhbHNlKVxuICAgICAgaWYgKCFsaXN0ZW5lcnMpIHtcbiAgICAgICAgbGlzdGVuZXJzID0gY29tcG9uZW50Ll9saXN0ZW5lcnMgPSB7fVxuICAgICAgICBjb21wb25lbnQubm9kZS5fbGlzdGVuZXJzID0ge31cbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyc1t0eXBlXSA9IGxpc3RlbmVyXG4gICAgICBjb21wb25lbnQubm9kZS5fbGlzdGVuZXJzW3R5cGVdID0gbGlzdGVuZXJcbiAgICB9XG4gIH0sXG5cbiAgcmVtb3ZlRXZlbnQ6IGZ1bmN0aW9uIChyZWYsIHR5cGUpIHtcbiAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXVxuICAgIHZhciBsaXN0ZW5lciA9IGNvbXBvbmVudC5fbGlzdGVuZXJzW3R5cGVdXG4gICAgaWYgKGNvbXBvbmVudCAmJiBsaXN0ZW5lcikge1xuICAgICAgY29tcG9uZW50Lm5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcilcbiAgICAgIGNvbXBvbmVudC5fbGlzdGVuZXJzW3R5cGVdID0gbnVsbFxuICAgICAgY29tcG9uZW50Lm5vZGUuX2xpc3RlbmVyc1t0eXBlXSA9IG51bGxcbiAgICB9XG4gIH0sXG5cbiAgdXBkYXRlQXR0cnM6IGZ1bmN0aW9uIChyZWYsIGF0dHIpIHtcbiAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXVxuICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgIGNvbXBvbmVudC51cGRhdGVBdHRycyhhdHRyKVxuICAgICAgaWYgKGNvbXBvbmVudC5kYXRhLnR5cGUgPT09ICdpbWFnZScgJiYgYXR0ci5zcmMpIHtcbiAgICAgICAgTGF6eUxvYWQuc3RhcnRJZk5lZWRlZChjb21wb25lbnQpXG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZVN0eWxlOiBmdW5jdGlvbiAocmVmLCBzdHlsZSkge1xuICAgIHZhciBjb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtyZWZdXG4gICAgaWYgKGNvbXBvbmVudCkge1xuICAgICAgY29tcG9uZW50LnVwZGF0ZVN0eWxlKHN0eWxlKVxuICAgIH1cbiAgfSxcblxuICB1cGRhdGVGdWxsQXR0cnM6IGZ1bmN0aW9uIChyZWYsIGF0dHIpIHtcbiAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRNYXBbcmVmXVxuICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgIGNvbXBvbmVudC5jbGVhckF0dHIoKVxuICAgICAgY29tcG9uZW50LnVwZGF0ZUF0dHJzKGF0dHIpXG4gICAgICBpZiAoY29tcG9uZW50LmRhdGEudHlwZSA9PT0gJ2ltYWdlJyAmJiBhdHRyLnNyYykge1xuICAgICAgICBMYXp5TG9hZC5zdGFydElmTmVlZGVkKGNvbXBvbmVudClcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgdXBkYXRlRnVsbFN0eWxlOiBmdW5jdGlvbiAocmVmLCBzdHlsZSkge1xuICAgIHZhciBjb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtyZWZdXG4gICAgaWYgKGNvbXBvbmVudCkge1xuICAgICAgY29tcG9uZW50LmNsZWFyU3R5bGUoKVxuICAgICAgY29tcG9uZW50LnVwZGF0ZVN0eWxlKHN0eWxlKVxuICAgIH1cbiAgfSxcblxuICBoYW5kbGVBcHBlbmQ6IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcbiAgICBjb21wb25lbnQuX2FwcGVuZGVkID0gdHJ1ZVxuICAgIGNvbXBvbmVudC5vbkFwcGVuZCAmJiBjb21wb25lbnQub25BcHBlbmQoKVxuXG4gICAgLy8gaW52b2tlIG9uQXBwZW5kIG9uIGNoaWxkcmVuIHJlY3Vyc2l2ZWx5XG4gICAgdmFyIGNoaWxkcmVuID0gY29tcG9uZW50LmRhdGEuY2hpbGRyZW5cbiAgICBpZiAoY2hpbGRyZW4pIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5jb21wb25lbnRNYXBbY2hpbGRyZW5baV0ucmVmXVxuICAgICAgICBpZiAoY2hpbGQpIHtcbiAgICAgICAgICB0aGlzLmhhbmRsZUFwcGVuZChjaGlsZClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHdhdGNoIGFwcGVhci9kaXNhcHBlYXIgb2YgdGhlIGNvbXBvbmVudCBpZiBuZWVkZWRcbiAgICBBcHBlYXJXYXRjaGVyLndhdGNoSWZOZWVkZWQoY29tcG9uZW50KVxuXG4gICAgLy8gZG8gbGF6eWxvYWQgaWYgbmVlZGVkXG4gICAgTGF6eUxvYWQuc3RhcnRJZk5lZWRlZChjb21wb25lbnQpXG4gIH0sXG5cbiAgdHJhbnNpdGlvbjogZnVuY3Rpb24gKHJlZiwgY29uZmlnLCBjYWxsYmFjaykge1xuICAgIHZhciBjb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudE1hcFtyZWZdXG4gICAgYW5pbWF0aW9uLnRyYW5zaXRpb25PbmNlKGNvbXBvbmVudCwgY29uZmlnLCBjYWxsYmFjaylcbiAgfSxcblxuICByZW5kZXJGaW5pc2g6IGZ1bmN0aW9uICgpIHtcbiAgICBGcmFtZVVwZGF0ZXIucGF1c2UoKVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50TWFuYWdlclxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRNYW5hZ2VyLmpzXG4gKiogbW9kdWxlIGlkID0gOVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciByYWYgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgICAgd2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICAgIGZ1bmN0aW9uIChjYWxsbGJhY2spIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoY2FsbGxiYWNrLCAxNilcbiAgICAgICAgICB9XG5cbnZhciByYWZJZFxudmFyIG9ic2VydmVycyA9IFtdXG52YXIgcGF1c2VkID0gZmFsc2VcblxudmFyIEZyYW1lVXBkYXRlciA9IHtcbiAgc3RhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAocmFmSWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHJhZklkID0gcmFmKGZ1bmN0aW9uIHJ1bkxvb3AoKSB7XG4gICAgICBpZiAoIXBhdXNlZCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9ic2VydmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIG9ic2VydmVyc1tpXSgpXG4gICAgICAgIH1cbiAgICAgICAgcmFmKHJ1bkxvb3ApXG4gICAgICB9XG4gICAgfSlcbiAgfSxcblxuICBpc0FjdGl2ZTogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhcGF1c2VkXG4gIH0sXG5cbiAgcGF1c2U6IGZ1bmN0aW9uICgpIHtcbiAgICBwYXVzZWQgPSB0cnVlXG4gICAgcmFmSWQgPSB1bmRlZmluZWRcbiAgfSxcblxuICByZXN1bWU6IGZ1bmN0aW9uICgpIHtcbiAgICBwYXVzZWQgPSBmYWxzZVxuICAgIHRoaXMuc3RhcnQoKVxuICB9LFxuXG4gIGFkZFVwZGF0ZU9ic2VydmVyOiBmdW5jdGlvbiAob2JzZXJ2ZU1ldGhvZCkge1xuICAgIG9ic2VydmVycy5wdXNoKG9ic2VydmVNZXRob2QpXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBGcmFtZVVwZGF0ZXJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvZnJhbWVVcGRhdGVyLmpzXG4gKiogbW9kdWxlIGlkID0gMTBcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJylcblxudmFyIGNvbXBvbmVudHNJblNjcm9sbGVyID0gW11cbnZhciBjb21wb25lbnRzT3V0T2ZTY3JvbGxlciA9IFtdXG52YXIgbGlzdGVuZWQgPSBmYWxzZVxudmFyIGRpcmVjdGlvbiA9ICd1cCdcbnZhciBzY3JvbGxZID0gMFxuXG52YXIgQXBwZWFyV2F0Y2hlciA9IHtcbiAgd2F0Y2hJZk5lZWRlZDogZnVuY3Rpb24gKGNvbXBvbmVudCkge1xuICAgIGlmIChuZWVkV2F0Y2goY29tcG9uZW50KSkge1xuICAgICAgaWYgKGNvbXBvbmVudC5pc0luU2Nyb2xsYWJsZSgpKSB7XG4gICAgICAgIGNvbXBvbmVudHNJblNjcm9sbGVyLnB1c2goY29tcG9uZW50KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29tcG9uZW50c091dE9mU2Nyb2xsZXIucHVzaChjb21wb25lbnQpXG4gICAgICB9XG4gICAgICBpZiAoIWxpc3RlbmVkKSB7XG4gICAgICAgIGxpc3RlbmVkID0gdHJ1ZVxuICAgICAgICAvLyB2YXIgaGFuZGxlciA9IHRocm90dGxlKG9uU2Nyb2xsLCAyNSlcbiAgICAgICAgdmFyIGhhbmRsZXIgPSB0aHJvdHRsZShvblNjcm9sbCwgMTAwKVxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgaGFuZGxlciwgZmFsc2UpXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG5lZWRXYXRjaChjb21wb25lbnQpIHtcbiAgdmFyIGV2ZW50cyA9IGNvbXBvbmVudC5kYXRhLmV2ZW50XG4gIGlmIChldmVudHNcbiAgICAgICYmIChldmVudHMuaW5kZXhPZignYXBwZWFyJykgIT0gLTFcbiAgICAgICAgfHwgZXZlbnRzLmluZGV4T2YoJ2Rpc2FwcGVhcicpICE9IC0xKSkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbmZ1bmN0aW9uIG9uU2Nyb2xsKGUpIHtcbiAgLy8gSWYgdGhlIHNjcm9sbCBldmVudCBpcyBkaXNwYXRjaGVkIGZyb20gYSBzY3JvbGxhYmxlIGNvbXBvbmVudFxuICAvLyBpbXBsZW1lbnRlZCB0aHJvdWdoIHNjcm9sbGVyanMsIHRoZW4gdGhlIGFwcGVhci9kaXNhcHBlYXIgZXZlbnRzXG4gIC8vIHNob3VsZCBiZSB0cmVhdGVkIHNwZWNpYWxseSBieSBoYW5kbGVTY3JvbGxlclNjcm9sbC5cbiAgaWYgKGUub3JpZ2luYWxUeXBlID09PSAnc2Nyb2xsaW5nJykge1xuICAgIGhhbmRsZVNjcm9sbGVyU2Nyb2xsKClcbiAgfSBlbHNlIHtcbiAgICBoYW5kbGVXaW5kb3dTY3JvbGwoKVxuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZVNjcm9sbGVyU2Nyb2xsKCkge1xuICB2YXIgY21wcyA9IGNvbXBvbmVudHNJblNjcm9sbGVyXG4gIHZhciBsZW4gPSBjbXBzLmxlbmd0aFxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIGNvbXBvbmVudCA9IGNtcHNbaV1cbiAgICB2YXIgYXBwZWFyID0gaXNDb21wb25lbnRJblNjcm9sbGVyQXBwZWFyKGNvbXBvbmVudClcbiAgICBpZiAoYXBwZWFyICYmICFjb21wb25lbnQuX2FwcGVhcikge1xuICAgICAgY29tcG9uZW50Ll9hcHBlYXIgPSB0cnVlXG4gICAgICBmaXJlRXZlbnQoY29tcG9uZW50LCAnYXBwZWFyJylcbiAgICB9IGVsc2UgaWYgKCFhcHBlYXIgJiYgY29tcG9uZW50Ll9hcHBlYXIpIHtcbiAgICAgIGNvbXBvbmVudC5fYXBwZWFyID0gZmFsc2VcbiAgICAgIGZpcmVFdmVudChjb21wb25lbnQsICdkaXNhcHBlYXInKVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVXaW5kb3dTY3JvbGwoKSB7XG4gIHZhciB5ID0gd2luZG93LnNjcm9sbFlcbiAgZGlyZWN0aW9uID0geSA+PSBzY3JvbGxZID8gJ3VwJyA6ICdkb3duJ1xuICBzY3JvbGxZID0geVxuXG4gIHZhciBsZW4gPSBjb21wb25lbnRzT3V0T2ZTY3JvbGxlci5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkge1xuICAgIHJldHVyblxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgY29tcG9uZW50ID0gY29tcG9uZW50c091dE9mU2Nyb2xsZXJbaV1cbiAgICB2YXIgYXBwZWFyID0gaXNDb21wb25lbnRJbldpbmRvdyhjb21wb25lbnQpXG4gICAgaWYgKGFwcGVhciAmJiAhY29tcG9uZW50Ll9hcHBlYXIpIHtcbiAgICAgIGNvbXBvbmVudC5fYXBwZWFyID0gdHJ1ZVxuICAgICAgZmlyZUV2ZW50KGNvbXBvbmVudCwgJ2FwcGVhcicpXG4gICAgfSBlbHNlIGlmICghYXBwZWFyICYmIGNvbXBvbmVudC5fYXBwZWFyKSB7XG4gICAgICBjb21wb25lbnQuX2FwcGVhciA9IGZhbHNlXG4gICAgICBmaXJlRXZlbnQoY29tcG9uZW50LCAnZGlzYXBwZWFyJylcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNDb21wb25lbnRJblNjcm9sbGVyQXBwZWFyKGNvbXBvbmVudCkge1xuICB2YXIgcGFyZW50U2Nyb2xsZXIgPSBjb21wb25lbnQuX3BhcmVudFNjcm9sbGVyXG4gIHZhciBjbXBSZWN0ID0gY29tcG9uZW50Lm5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgaWYgKCFpc0NvbXBvbmVudEluV2luZG93KGNvbXBvbmVudCkpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICB3aGlsZSAocGFyZW50U2Nyb2xsZXIpIHtcbiAgICB2YXIgcGFyZW50UmVjdCA9IHBhcmVudFNjcm9sbGVyLm5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICBpZiAoIShjbXBSZWN0LnJpZ2h0ID4gcGFyZW50UmVjdC5sZWZ0XG4gICAgICAgICYmIGNtcFJlY3QubGVmdCA8IHBhcmVudFJlY3QucmlnaHRcbiAgICAgICAgJiYgY21wUmVjdC5ib3R0b20gPiBwYXJlbnRSZWN0LnRvcFxuICAgICAgICAmJiBjbXBSZWN0LnRvcCA8IHBhcmVudFJlY3QuYm90dG9tKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHBhcmVudFNjcm9sbGVyID0gcGFyZW50U2Nyb2xsZXIuX3BhcmVudFNjcm9sbGVyXG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuZnVuY3Rpb24gaXNDb21wb25lbnRJbldpbmRvdyhjb21wb25lbnQpIHtcbiAgdmFyIHJlY3QgPSBjb21wb25lbnQubm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICByZXR1cm4gcmVjdC5yaWdodCA+IDAgJiYgcmVjdC5sZWZ0IDwgd2luZG93LmlubmVyV2lkdGggJiZcbiAgICAgICAgIHJlY3QuYm90dG9tID4gMCAmJiByZWN0LnRvcCA8IHdpbmRvdy5pbm5lckhlaWdodFxufVxuXG5mdW5jdGlvbiBmaXJlRXZlbnQoY29tcG9uZW50LCB0eXBlKSB7XG4gIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnSFRNTEV2ZW50cycpXG4gIHZhciBkYXRhID0geyBkaXJlY3Rpb246IGRpcmVjdGlvbiB9XG4gIGV2dC5pbml0RXZlbnQodHlwZSwgZmFsc2UsIGZhbHNlKVxuICBldnQuZGF0YSA9IGRhdGFcbiAgdXRpbHMuZXh0ZW5kKGV2dCwgZGF0YSlcbiAgY29tcG9uZW50Lm5vZGUuZGlzcGF0Y2hFdmVudChldnQpXG59XG5cbmZ1bmN0aW9uIHRocm90dGxlKGZ1bmMsIHdhaXQpIHtcbiAgdmFyIGNvbnRleHQsIGFyZ3MsIHJlc3VsdFxuICB2YXIgdGltZW91dCA9IG51bGxcbiAgdmFyIHByZXZpb3VzID0gMFxuICB2YXIgbGF0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcHJldmlvdXMgPSBEYXRlLm5vdygpXG4gICAgdGltZW91dCA9IG51bGxcbiAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpXG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbm93ID0gRGF0ZS5ub3coKVxuICAgIHZhciByZW1haW5pbmcgPSB3YWl0IC0gKG5vdyAtIHByZXZpb3VzKVxuICAgIGNvbnRleHQgPSB0aGlzXG4gICAgYXJncyA9IGFyZ3VtZW50c1xuICAgIGlmIChyZW1haW5pbmcgPD0gMCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgICB0aW1lb3V0ID0gbnVsbFxuICAgICAgcHJldmlvdXMgPSBub3dcbiAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncylcbiAgICB9IGVsc2UgaWYgKCF0aW1lb3V0KSB7XG4gICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgcmVtYWluaW5nKVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBBcHBlYXJXYXRjaGVyXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9hcHBlYXJXYXRjaGVyLmpzXG4gKiogbW9kdWxlIGlkID0gMTFcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG5yZXF1aXJlKCdsYXp5aW1nJylcblxudmFyIGxhenlsb2FkVGltZXJcblxudmFyIExhenlMb2FkID0ge1xuICBtYWtlSW1hZ2VMYXp5OiBmdW5jdGlvbiAoaW1hZ2UsIHNyYykge1xuICAgIGltYWdlLnJlbW92ZUF0dHJpYnV0ZSgnaW1nLXNyYycpXG4gICAgaW1hZ2UucmVtb3ZlQXR0cmlidXRlKCdpLWxhenktc3JjJylcbiAgICBpbWFnZS5yZW1vdmVBdHRyaWJ1dGUoJ3NyYycpXG4gICAgaW1hZ2Uuc2V0QXR0cmlidXRlKCdpbWctc3JjJywgc3JjKVxuICAgIC8vIHNob3VsZCByZXBsYWNlICdzcmMnIHdpdGggJ2ltZy1zcmMnLiBidXQgZm9yIG5vdyBsaWIuaW1nLmZpcmUgaXNcbiAgICAvLyBub3Qgd29ya2luZyBmb3IgdGhlIHNpdHVhdGlvbiB0aGF0IHRoZSBhcHBlYXIgZXZlbnQgaGFzIGJlZW5cbiAgICAvLyBhbHJlYWR5IHRyaWdnZXJlZC5cbiAgICAvLyBpbWFnZS5zZXRBdHRyaWJ1dGUoJ3NyYycsIHNyYylcbiAgICAvLyBpbWFnZS5zZXRBdHRyaWJ1dGUoJ2ltZy1zcmMnLCBzcmMpXG4gICAgdGhpcy5maXJlKClcbiAgfSxcblxuICAvLyB3ZSBkb24ndCBrbm93IHdoZW4gYWxsIGltYWdlIGFyZSBhcHBlbmRlZFxuICAvLyBqdXN0IHVzZSBzZXRUaW1lb3V0IHRvIGRvIGRlbGF5IGxhenlsb2FkXG4gIC8vXG4gIC8vIC0tIGFjdHVhbGx5IGV2ZXJ5dGltZSB3ZSBhZGQgYSBlbGVtZW50IG9yIHVwZGF0ZSBzdHlsZXMsXG4gIC8vIHRoZSBjb21wb25lbnQgbWFuYWdlciB3aWxsIGNhbGwgc3RhcnRJZk5lZWQgdG8gZmlyZVxuICAvLyBsYXp5bG9hZCBvbmNlIGFnYWluIGluIHRoZSBoYW5kbGVBcHBlbmQgZnVuY3Rpb24uIHNvIHRoZXJlXG4gIC8vIGlzIG5vIHdheSB0aGF0IGFueSBpbWFnZSBlbGVtZW50IGNhbiBtaXNzIGl0LiBTZWUgc291cmNlXG4gIC8vIGNvZGUgaW4gY29tcG9uZW50TWFuZ2FnZXIuanMuXG4gIHN0YXJ0SWZOZWVkZWQ6IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcbiAgICB2YXIgdGhhdCA9IHRoaXNcbiAgICBpZiAoY29tcG9uZW50LmRhdGEudHlwZSA9PT0gJ2ltYWdlJykge1xuICAgICAgaWYgKCFsYXp5bG9hZFRpbWVyKSB7XG4gICAgICAgIGxhenlsb2FkVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aGF0LmZpcmUoKVxuICAgICAgICAgIGNsZWFyVGltZW91dChsYXp5bG9hZFRpbWVyKVxuICAgICAgICAgIGxhenlsb2FkVGltZXIgPSBudWxsXG4gICAgICAgIH0sIDE2KVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBsb2FkSWZOZWVkZWQ6IGZ1bmN0aW9uIChlbGVtZW50U2NvcGUpIHtcbiAgICB2YXIgbm90UHJlUHJvY2Vzc2VkID0gZWxlbWVudFNjb3BlLnF1ZXJ5U2VsZWN0b3JBbGwoJ1tpbWctc3JjXScpXG4gICAgdmFyIHRoYXQgPSB0aGlzXG4gICAgLy8gaW1hZ2UgZWxlbWVudHMgd2hpY2ggaGF2ZSBhdHRyaWJ1dGUgJ2ktbGF6eS1zcmMnIHdlcmUgZWxlbWVudHNcbiAgICAvLyB0aGF0IGhhZCBiZWVuIHByZXByb2Nlc3NlZCBieSBsaWItaW1nLWNvcmUsIGJ1dCBub3QgbG9hZGVkIHlldCwgYW5kXG4gICAgLy8gbXVzdCBiZSBsb2FkZWQgd2hlbiAnYXBwZWFyJyBldmVudHMgd2VyZSBmaXJlZC4gSXQgdHVybnMgb3V0IHRoZVxuICAgIC8vICdhcHBlYXInIGV2ZW50IHdhcyBub3QgZmlyZWQgY29ycmVjdGx5IGluIHRoZSBjc3MtdHJhbnNsYXRlLXRyYW5zaXRpb25cbiAgICAvLyBzaXR1YXRpb24sIHNvICdpLWxhenktc3JjJyBtdXN0IGJlIGNoZWNrZWQgYW5kIGxhenlsb2FkIG11c3QgYmVcbiAgICAvLyBmaXJlZCBtYW51YWxseS5cbiAgICB2YXIgcHJlUHJvY2Vzc2VkID0gZWxlbWVudFNjb3BlLnF1ZXJ5U2VsZWN0b3JBbGwoJ1tpLWxhenktc3JjXScpXG4gICAgaWYgKG5vdFByZVByb2Nlc3NlZC5sZW5ndGggPiAwIHx8IHByZVByb2Nlc3NlZC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGF0LmZpcmUoKVxuICAgIH1cbiAgfSxcblxuICAvLyBmaXJlIGxhenlsb2FkLlxuICBmaXJlOiBmdW5jdGlvbiAoKSB7XG4gICAgbGliLmltZy5maXJlKClcbiAgfVxuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gTGF6eUxvYWRcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvbGF6eUxvYWQuanNcbiAqKiBtb2R1bGUgaWQgPSAxMlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiXCJ1bmRlZmluZWRcIj09dHlwZW9mIHdpbmRvdyYmKHdpbmRvdz17Y3RybDp7fSxsaWI6e319KSwhd2luZG93LmN0cmwmJih3aW5kb3cuY3RybD17fSksIXdpbmRvdy5saWImJih3aW5kb3cubGliPXt9KSxmdW5jdGlvbih0LGkpe2Z1bmN0aW9uIGUodCxpKXtpJiYoXCJJTUdcIj09dC5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpP3Quc2V0QXR0cmlidXRlKFwic3JjXCIsaSk6dC5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2U9J3VybChcIicraSsnXCIpJyl9ZnVuY3Rpb24gYSgpe3I9aS5hcHBlYXIuaW5pdCh7Y2xzOlwiaW1ndG1wXCIsb25jZTohMCx4Om8ubGF6eVdpZHRoLHk6by5sYXp5SGVpZ2h0LG9uQXBwZWFyOmZ1bmN0aW9uKHQpe3ZhciBpPXRoaXM7ZShpLGkuZ2V0QXR0cmlidXRlKFwiaS1sYXp5LXNyY1wiKSksaS5yZW1vdmVBdHRyaWJ1dGUoXCJpLWxhenktc3JjXCIpfX0pfXJlcXVpcmUoXCJhcHBlYXJqc1wiKTt2YXIgcixBPXt9LG89e2RhdGFTcmM6XCJpbWctc3JjXCIsbGF6eUhlaWdodDowLGxhenlXaWR0aDowfTtBLmxvZ0NvbmZpZz1mdW5jdGlvbigpe2NvbnNvbGUubG9nKFwibGliLWltZyBDb25maWdcXG5cIixvKX0sQS5maXJlPWZ1bmN0aW9uKCl7cnx8YSgpO3ZhciB0PVwiaV9cIitEYXRlLm5vdygpJTFlNSxpPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbXCIrby5kYXRhU3JjK1wiXVwiKTtbXS5mb3JFYWNoLmNhbGwoaSxmdW5jdGlvbihpKXtcImZhbHNlXCI9PWkuZGF0YXNldC5sYXp5JiZcInRydWVcIiE9aS5kYXRhc2V0Lmxhenk/ZShpLHByb2Nlc3NTcmMoaSxpLmdldEF0dHJpYnV0ZShvLmRhdGFTcmMpKSk6KGkuY2xhc3NMaXN0LmFkZCh0KSxpLnNldEF0dHJpYnV0ZShcImktbGF6eS1zcmNcIixpLmdldEF0dHJpYnV0ZShvLmRhdGFTcmMpKSksaS5yZW1vdmVBdHRyaWJ1dGUoby5kYXRhU3JjKX0pLHIuYmluZChcIi5cIit0KSxyLmZpcmUoKX0sQS5kZWZhdWx0U3JjPVwiZGF0YTppbWFnZS9naWY7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBRUFBQUFCQ0FZQUFBQWZGY1NKQUFBQURVbEVRVlFJbVdOZ1lHQmdBQUFBQlFBQmg2Rk8xQUFBQUFCSlJVNUVya0pnZ2c9PVwiLGkuaW1nPUEsbW9kdWxlLmV4cG9ydHM9QX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSk7XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbGF6eWltZy9idWlsZC9pbWcuY29tbW9uLmpzXG4gKiogbW9kdWxlIGlkID0gMTNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIlwidW5kZWZpbmVkXCI9PXR5cGVvZiB3aW5kb3cmJih3aW5kb3c9e2N0cmw6e30sbGliOnt9fSksIXdpbmRvdy5jdHJsJiYod2luZG93LmN0cmw9e30pLCF3aW5kb3cubGliJiYod2luZG93LmxpYj17fSksZnVuY3Rpb24obixlKXtmdW5jdGlvbiBpKCl7ZD13LmNyZWF0ZUV2ZW50KFwiSFRNTEV2ZW50c1wiKSx2PXcuY3JlYXRlRXZlbnQoXCJIVE1MRXZlbnRzXCIpLGQuaW5pdEV2ZW50KFwiX2FwcGVhclwiLCExLCEwKSx2LmluaXRFdmVudChcIl9kaXNhcHBlYXJcIiwhMSwhMCl9ZnVuY3Rpb24gYSh0LG4pe3ZhciBlLGksYSxzPShEYXRlLm5vdygpLDApLG89bnVsbCxyPWZ1bmN0aW9uKCl7cz1EYXRlLm5vdygpLG89bnVsbCx0LmFwcGx5KGUsaSl9O3JldHVybiBmdW5jdGlvbigpe3ZhciBsPURhdGUubm93KCk7ZT10aGlzLGk9YXJndW1lbnRzO3ZhciBjPW4tKGwtcyk7cmV0dXJuIDA+PWN8fGM+PW4/KGNsZWFyVGltZW91dChvKSxvPW51bGwsYT10LmFwcGx5KGUsaSkpOm51bGw9PW8mJihvPXNldFRpbWVvdXQocixjKSksYX19ZnVuY3Rpb24gcyhuLGUpe3ZhciBuLGksYSxzO2lmKG4pcmV0dXJuIGV8fChlPXt4OjAseTowfSksbiE9d2luZG93PyhuPW4uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksaT1uLmxlZnQsdD1uLnRvcCxhPW4ucmlnaHQscz1uLmJvdHRvbSk6KGk9MCx0PTAsYT1pK24uaW5uZXJXaWR0aCxzPXQrbi5pbm5lckhlaWdodCkse2xlZnQ6aSx0b3A6dCxyaWdodDphK2UueCxib3R0b206cytlLnl9fWZ1bmN0aW9uIG8odCxuKXt2YXIgZT1uLnJpZ2h0PnQubGVmdCYmbi5sZWZ0PHQucmlnaHQsaT1uLmJvdHRvbT50LnRvcCYmbi50b3A8dC5ib3R0b207cmV0dXJuIGUmJml9ZnVuY3Rpb24gcih0LG4pe3ZhciBlPVwibm9uZVwiLGk9dC5sZWZ0LW4ubGVmdCxhPXQudG9wLW4udG9wO3JldHVybiAwPT1hJiYoZT0wIT1pP2k+MD9cImxlZnRcIjpcInJpZ2h0XCI6XCJub25lXCIpLDA9PWkmJihlPTAhPWE/YT4wP1widXBcIjpcImRvd25cIjpcIm5vbmVcIiksZX1mdW5jdGlvbiBsKHQsbil7Zm9yKHZhciBlIGluIG4pbi5oYXNPd25Qcm9wZXJ0eShlKSYmKHRbZV09bltlXSk7cmV0dXJuIHR9ZnVuY3Rpb24gYygpe3ZhciB0PXRoaXMsbj1hKGZ1bmN0aW9uKCl7Zi5hcHBseSh0LGFyZ3VtZW50cyl9LHRoaXMub3B0aW9ucy53YWl0KTt0aGlzLl9faGFuZGxlJiYodGhpcy5jb250YWluZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLHRoaXMuX19oYW5kbGUpLHRoaXMuX19oYW5kbGU9bnVsbCksdGhpcy5fX2hhbmRsZT1uLHRoaXMuY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIixuLCExKSx0aGlzLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsZnVuY3Rpb24obil7Zi5hcHBseSh0LGFyZ3VtZW50cyl9LCExKSx0aGlzLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwiYW5pbWF0aW9uRW5kXCIsZnVuY3Rpb24oKXtmLmFwcGx5KHQsYXJndW1lbnRzKX0sITEpLHRoaXMuY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoXCJ3ZWJraXRBbmltYXRpb25FbmRcIixmdW5jdGlvbigpe2YuYXBwbHkodCxhcmd1bWVudHMpfSwhMSksdGhpcy5jb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcihcInRyYW5zaXRpb25lbmRcIixmdW5jdGlvbigpe2YuYXBwbHkodCxhcmd1bWVudHMpfSwhMSl9ZnVuY3Rpb24gcCh0KXt2YXIgbj10aGlzLGU9dGhpcy5vcHRpb25zLmNvbnRhaW5lcjtpZihcInN0cmluZ1wiPT10eXBlb2YgZT90aGlzLmNvbnRhaW5lcj13LnF1ZXJ5U2VsZWN0b3IoZSk6dGhpcy5jb250YWluZXI9ZSx0aGlzLmNvbnRhaW5lcj09d2luZG93KXZhciBpPXcucXVlcnlTZWxlY3RvckFsbCh0KTtlbHNlIHZhciBpPXRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwodCk7dmFyIGk9W10uc2xpY2UuY2FsbChpLG51bGwpO3JldHVybiBpPWkuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwiMVwiPT10LmRhdGFzZXQuYmluZD8oZGVsZXRlIHQuX2hhc0FwcGVhcixkZWxldGUgdC5faGFzRGlzQXBwZWFyLGRlbGV0ZSB0Ll9hcHBlYXIsdC5jbGFzc0xpc3QucmVtb3ZlKG4ub3B0aW9ucy5jbHMpLCExKTohMH0pfWZ1bmN0aW9uIGgodCl7dmFyIG49dGhpczt0JiZ0Lmxlbmd0aD4wJiZbXS5mb3JFYWNoLmNhbGwodCxmdW5jdGlvbih0KXt0Ll9lbGVPZmZzZXQ9cyh0KSx0LmNsYXNzTGlzdC5yZW1vdmUobi5vcHRpb25zLmNscyksdC5kYXRhc2V0LmJpbmQ9MX0pfWZ1bmN0aW9uIGYoKXt2YXIgdD10aGlzLmNvbnRhaW5lcixuPXRoaXMuYXBwZWFyV2F0Y2hFbGVtZW50cyxlPXRoaXMub3B0aW9ucy5vbkFwcGVhcixpPXRoaXMub3B0aW9ucy5vbkRpc2FwcGVhcixhPXModCx7eDp0aGlzLm9wdGlvbnMueCx5OnRoaXMub3B0aW9ucy55fSksbD10aGlzLm9wdGlvbnMub25jZSxjPWFyZ3VtZW50c1swXXx8e307biYmbi5sZW5ndGg+MCYmW10uZm9yRWFjaC5jYWxsKG4sZnVuY3Rpb24odCxuKXt2YXIgcD1zKHQpLGg9cih0Ll9lbGVPZmZzZXQscCk7dC5fZWxlT2Zmc2V0PXA7dmFyIGY9byhhLHApLHU9dC5fYXBwZWFyLHc9dC5faGFzQXBwZWFyLEU9dC5faGFzRGlzQXBwZWFyO2QuZGF0YT17ZGlyZWN0aW9uOmh9LHYuZGF0YT17ZGlyZWN0aW9uOmh9LGYmJiF1PyhsJiYhd3x8IWwpJiYoZSYmZS5jYWxsKHQsYyksdC5kaXNwYXRjaEV2ZW50KGQpLHQuX2hhc0FwcGVhcj0hMCx0Ll9hcHBlYXI9ITApOiFmJiZ1JiYobCYmIUV8fCFsKSYmKGkmJmkuY2FsbCh0LGMpLHQuZGlzcGF0Y2hFdmVudCh2KSx0Ll9oYXNEaXNBcHBlYXI9ITAsdC5fYXBwZWFyPSExKX0pfWZ1bmN0aW9uIHUodCl7bCh0aGlzLm9wdGlvbnMsdHx8KHQ9e30pKSx0aGlzLmFwcGVhcldhdGNoRWxlbWVudHM9dGhpcy5hcHBlYXJXYXRjaEVsZW1lbnRzfHxwLmNhbGwodGhpcyxcIi5cIit0aGlzLm9wdGlvbnMuY2xzKSxoLmNhbGwodGhpcyx0aGlzLmFwcGVhcldhdGNoRWxlbWVudHMpLGMuY2FsbCh0aGlzKX12YXIgZCx2LHc9ZG9jdW1lbnQsRT1mdW5jdGlvbigpe3UuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxfPXtpbnN0YW5jZXM6W10saW5pdDpmdW5jdGlvbih0KXt2YXIgbj17b3B0aW9uczp7Y29udGFpbmVyOndpbmRvdyx3YWl0OjEwMCx4OjAseTowLGNsczpcImxpYi1hcHBlYXJcIixvbmNlOiExLG9uUmVzZXQ6ZnVuY3Rpb24oKXt9LG9uQXBwZWFyOmZ1bmN0aW9uKCl7fSxvbkRpc2FwcGVhcjpmdW5jdGlvbigpe319LGNvbnRhaW5lcjpudWxsLGFwcGVhcldhdGNoRWxlbWVudHM6bnVsbCxiaW5kOmZ1bmN0aW9uKHQpe3ZhciBuPXRoaXMub3B0aW9ucy5jbHM7aWYoXCJzdHJpbmdcIj09dHlwZW9mIHQpe3ZhciBlPXAuY2FsbCh0aGlzLHQpO1tdLmZvckVhY2guY2FsbChlLGZ1bmN0aW9uKHQsZSl7dC5jbGFzc0xpc3QuY29udGFpbnMobil8fHQuY2xhc3NMaXN0LmFkZChuKX0pfWVsc2V7aWYoMSE9dC5ub2RlVHlwZXx8IXRoaXMuY29udGFpbmVyLmNvbnRhaW5zKHQpKXJldHVybiB0aGlzO3QuY2xhc3NMaXN0LmNvbnRhaW5zKG4pfHx0LmNsYXNzTGlzdC5hZGQobil9dmFyIGk9cC5jYWxsKHRoaXMsXCIuXCIrdGhpcy5vcHRpb25zLmNscyk7cmV0dXJuIHRoaXMuYXBwZWFyV2F0Y2hFbGVtZW50cz10aGlzLmFwcGVhcldhdGNoRWxlbWVudHMuY29uY2F0KGkpLGguY2FsbCh0aGlzLGkpLHRoaXN9LHJlc2V0OmZ1bmN0aW9uKHQpe3JldHVybiB1LmNhbGwodGhpcyx0KSx0aGlzLmFwcGVhcldhdGNoRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbih0KXtkZWxldGUgdC5faGFzQXBwZWFyLGRlbGV0ZSB0Ll9oYXNEaXNBcHBlYXIsZGVsZXRlIHQuX2FwcGVhcn0pLHRoaXN9LGZpcmU6ZnVuY3Rpb24oKXt0aGlzLmFwcGVhcldhdGNoRWxlbWVudHN8fCh0aGlzLmFwcGVhcldhdGNoRWxlbWVudHM9W10pO3ZhciB0PXAuY2FsbCh0aGlzLFwiLlwiK3RoaXMub3B0aW9ucy5jbHMpO3JldHVybiB0aGlzLmFwcGVhcldhdGNoRWxlbWVudHM9dGhpcy5hcHBlYXJXYXRjaEVsZW1lbnRzLmNvbmNhdCh0KSxoLmNhbGwodGhpcyx0KSxmLmNhbGwodGhpcyksdGhpc319O0UucHJvdG90eXBlPW47dmFyIGU9bmV3IEUodCk7cmV0dXJuIHRoaXMuaW5zdGFuY2VzLnB1c2goZSksZX0sZmlyZUFsbDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuaW5zdGFuY2VzO3QuZm9yRWFjaChmdW5jdGlvbih0KXt0LmZpcmUoKX0pfX07aSgpLGUuYXBwZWFyPV99KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpO1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2FwcGVhcmpzL2J1aWxkL2FwcGVhci5jb21tb24uanNcbiAqKiBtb2R1bGUgaWQgPSAxNFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKlxuICAgKiBjb25maWc6XG4gICAqICAgLSBzdHlsZXNcbiAgICogICAtIGR1cmF0aW9uIFtOdW1iZXJdIG1pbGxpc2Vjb25kcyhtcylcbiAgICogICAtIHRpbWluZ0Z1bmN0aW9uIFtzdHJpbmddXG4gICAqICAgLSBkZWFseSBbTnVtYmVyXSBtaWxsaXNlY29uZHMobXMpXG4gICAqL1xuICB0cmFuc2l0aW9uT25jZTogZnVuY3Rpb24gKGNvbXAsIGNvbmZpZywgY2FsbGJhY2spIHtcbiAgICB2YXIgc3R5bGVzID0gY29uZmlnLnN0eWxlcyB8fCB7fVxuICAgIHZhciBkdXJhdGlvbiA9IGNvbmZpZy5kdXJhdGlvbiB8fCAxMDAwIC8vIG1zXG4gICAgdmFyIHRpbWluZ0Z1bmN0aW9uID0gY29uZmlnLnRpbWluZ0Z1bmN0aW9uIHx8ICdlYXNlJ1xuICAgIHZhciBkZWxheSA9IGNvbmZpZy5kZWxheSB8fCAwICAvLyBtc1xuICAgIHZhciB0cmFuc2l0aW9uVmFsdWUgPSAnYWxsICcgKyBkdXJhdGlvbiArICdtcyAnXG4gICAgICAgICsgdGltaW5nRnVuY3Rpb24gKyAnICcgKyBkZWxheSArICdtcydcbiAgICB2YXIgZG9tID0gY29tcC5ub2RlXG4gICAgdmFyIHRyYW5zaXRpb25FbmRIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgIGRvbS5yZW1vdmVFdmVudExpc3RlbmVyKCd3ZWJraXRUcmFuc2l0aW9uRW5kJywgdHJhbnNpdGlvbkVuZEhhbmRsZXIpXG4gICAgICBkb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHRyYW5zaXRpb25FbmRIYW5kbGVyKVxuICAgICAgZG9tLnN0eWxlLnRyYW5zaXRpb24gPSAnJ1xuICAgICAgZG9tLnN0eWxlLndlYmtpdFRyYW5zaXRpb24gPSAnJ1xuICAgICAgY2FsbGJhY2soKVxuICAgIH1cbiAgICBkb20uc3R5bGUudHJhbnNpdGlvbiA9IHRyYW5zaXRpb25WYWx1ZVxuICAgIGRvbS5zdHlsZS53ZWJraXRUcmFuc2l0aW9uID0gdHJhbnNpdGlvblZhbHVlXG4gICAgZG9tLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmtpdFRyYW5zaXRpb25FbmQnLCB0cmFuc2l0aW9uRW5kSGFuZGxlcilcbiAgICBkb20uYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHRyYW5zaXRpb25FbmRIYW5kbGVyKVxuICAgIGNvbXAudXBkYXRlU3R5bGUoc3R5bGVzKVxuICB9XG5cbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2FuaW1hdGlvbi5qc1xuICoqIG1vZHVsZSBpZCA9IDE1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpXG52YXIgQ29tcG9uZW50TWFuYWdlciA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudE1hbmFnZXInKVxudmFyIGZsZXhib3ggPSByZXF1aXJlKCcuLi9mbGV4Ym94JylcbnJlcXVpcmUoJ2ZpeGVkc3RpY2t5JylcblxuZnVuY3Rpb24gQ29tcG9uZW50KGRhdGEsIG5vZGVUeXBlKSB7XG4gIHRoaXMuZGF0YSA9IGRhdGFcbiAgdGhpcy5ub2RlID0gdGhpcy5jcmVhdGUobm9kZVR5cGUpXG5cbiAgdGhpcy5jcmVhdGVDaGlsZHJlbigpXG4gIHRoaXMudXBkYXRlQXR0cnModGhpcy5kYXRhLmF0dHIpXG4gIC8vIGlzc3VlOiB3aGVuIGFkZCBlbGVtZW50IHRvIGEgbGlzdCBpbiBsaWZldGltZSBob29rICdyZWFkeScsIHRoZVxuICAvLyBzdHlsZXMgaXMgc2V0IHRvIHRoZSBjbGFzc1N0eWxlLCBub3Qgc3R5bGUuIFRoaXMgaXMgYSBpc3N1ZVxuICAvLyB0aGF0IGpzZnJhbWV3b3JrIHNob3VsZCBkbyBzb21ldGhpbmcgYWJvdXQuXG4gIHZhciBjbGFzc1N0eWxlID0gdGhpcy5kYXRhLmNsYXNzU3R5bGVcbiAgY2xhc3NTdHlsZSAmJiB0aGlzLnVwZGF0ZVN0eWxlKHRoaXMuZGF0YS5jbGFzc1N0eWxlKVxuICB0aGlzLnVwZGF0ZVN0eWxlKHRoaXMuZGF0YS5zdHlsZSlcbiAgdGhpcy5iaW5kRXZlbnRzKHRoaXMuZGF0YS5ldmVudClcbn1cblxuQ29tcG9uZW50LnByb3RvdHlwZSA9IHtcblxuICBjcmVhdGU6IGZ1bmN0aW9uIChub2RlVHlwZSkge1xuICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChub2RlVHlwZSB8fCAnZGl2JylcbiAgICByZXR1cm4gbm9kZVxuICB9LFxuXG4gIGdldENvbXBvbmVudE1hbmFnZXI6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gQ29tcG9uZW50TWFuYWdlci5nZXRJbnN0YW5jZSh0aGlzLmRhdGEuaW5zdGFuY2VJZClcbiAgfSxcblxuICBnZXRQYXJlbnQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKCkuY29tcG9uZW50TWFwW3RoaXMucGFyZW50UmVmXVxuICB9LFxuXG4gIGlzU2Nyb2xsYWJsZTogZnVuY3Rpb24gKCkge1xuICAgIHZhciB0ID0gdGhpcy5kYXRhLnR5cGVcbiAgICByZXR1cm4gQ29tcG9uZW50TWFuYWdlci5nZXRTY3JvbGxhYmxlVHlwZXMoKS5pbmRleE9mKHQpICE9PSAtMVxuICB9LFxuXG4gIGlzSW5TY3JvbGxhYmxlOiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9pc0luU2Nyb2xsYWJsZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gdGhpcy5faXNJblNjcm9sbGFibGVcbiAgICB9XG4gICAgdmFyIHBhcmVudCA9IHRoaXMuZ2V0UGFyZW50KClcbiAgICBpZiAocGFyZW50XG4gICAgICAgICYmICh0eXBlb2YgcGFyZW50Ll9pc0luU2Nyb2xsYWJsZSAhPT0gJ2Jvb2xlYW4nKVxuICAgICAgICAmJiAhcGFyZW50LmlzU2Nyb2xsYWJsZSgpKSB7XG4gICAgICBpZiAocGFyZW50LmRhdGEudHlwZSA9PT0gJ3Jvb3QnKSB7XG4gICAgICAgIHRoaXMuX2lzSW5TY3JvbGxhYmxlID0gZmFsc2VcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgICB0aGlzLl9pc0luU2Nyb2xsYWJsZSA9IHBhcmVudC5pc0luU2Nyb2xsYWJsZSgpXG4gICAgICB0aGlzLl9wYXJlbnRTY3JvbGxlciA9IHBhcmVudC5fcGFyZW50U2Nyb2xsZXJcbiAgICAgIHJldHVybiB0aGlzLl9pc0luU2Nyb2xsYWJsZVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHBhcmVudC5faXNJblNjcm9sbGFibGUgPT09ICdib29sZWFuJykge1xuICAgICAgdGhpcy5faXNJblNjcm9sbGFibGUgPSBwYXJlbnQuX2lzSW5TY3JvbGxhYmxlXG4gICAgICB0aGlzLl9wYXJlbnRTY3JvbGxlciA9IHBhcmVudC5fcGFyZW50U2Nyb2xsZXJcbiAgICAgIHJldHVybiB0aGlzLl9pc0luU2Nyb2xsYWJsZVxuICAgIH1cbiAgICBpZiAocGFyZW50LmlzU2Nyb2xsYWJsZSgpKSB7XG4gICAgICB0aGlzLl9pc0luU2Nyb2xsYWJsZSA9IHRydWVcbiAgICAgIHRoaXMuX3BhcmVudFNjcm9sbGVyID0gcGFyZW50XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgICBpZiAoIXBhcmVudCkge1xuICAgICAgY29uc29sZSAmJiBjb25zb2xlLmVycm9yKCdpc0luU2Nyb2xsYWJsZSAtIHBhcmVudCBub3QgZXhpc3QuJylcbiAgICB9XG4gIH0sXG5cbiAgY3JlYXRlQ2hpbGRyZW46IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgICB2YXIgcGFyZW50UmVmID0gdGhpcy5kYXRhLnJlZlxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICBpZiAoY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICB2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KClcbiAgICAgIHZhciBpc0ZsZXggPSBmYWxzZVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICBjaGlsZHJlbltpXS5pbnN0YW5jZUlkID0gdGhpcy5kYXRhLmluc3RhbmNlSWRcbiAgICAgICAgY2hpbGRyZW5baV0uc2NhbGUgPSB0aGlzLmRhdGEuc2NhbGVcbiAgICAgICAgdmFyIGNoaWxkID0gY29tcG9uZW50TWFuYWdlci5jcmVhdGVFbGVtZW50KGNoaWxkcmVuW2ldKVxuICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICAgICAgICBjaGlsZC5wYXJlbnRSZWYgPSBwYXJlbnRSZWZcbiAgICAgICAgaWYgKCFpc0ZsZXhcbiAgICAgICAgICAgICYmIGNoaWxkLmRhdGEuc3R5bGVcbiAgICAgICAgICAgICYmIGNoaWxkLmRhdGEuc3R5bGUuaGFzT3duUHJvcGVydHkoJ2ZsZXgnKVxuICAgICAgICAgICkge1xuICAgICAgICAgIGlzRmxleCA9IHRydWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKGZyYWdtZW50KVxuICAgIH1cbiAgfSxcblxuICAvLyBAdG9kbzogY2hhbmdlZCBwYXJhbSBkYXRhIHRvIGNoaWxkXG4gIGFwcGVuZENoaWxkOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICB2YXIgY2hpbGQgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoZGF0YSlcbiAgICB0aGlzLm5vZGUuYXBwZW5kQ2hpbGQoY2hpbGQubm9kZSlcbiAgICAvLyB1cGRhdGUgdGhpcy5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICB0aGlzLmRhdGEuY2hpbGRyZW4gPSBbZGF0YV1cbiAgICB9IGVsc2Uge1xuICAgICAgY2hpbGRyZW4ucHVzaChkYXRhKVxuICAgIH1cblxuICAgIHJldHVybiBjaGlsZFxuICB9LFxuXG4gIGluc2VydEJlZm9yZTogZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgICB2YXIgaSA9IDBcbiAgICB2YXIgbFxuICAgIHZhciBpc0FwcGVuZCA9IGZhbHNlXG5cbiAgICAvLyB1cGRhdGUgdGhpcy5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoIHx8ICFiZWZvcmUpIHtcbiAgICAgIGlzQXBwZW5kID0gdHJ1ZVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgaWYgKGNoaWxkcmVuW2ldLnJlZiA9PT0gYmVmb3JlLmRhdGEucmVmKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGkgPT09IGwpIHtcbiAgICAgICAgaXNBcHBlbmQgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuXG5cbiAgICBpZiAoaXNBcHBlbmQpIHtcbiAgICAgIHRoaXMubm9kZS5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICAgICAgY2hpbGRyZW4ucHVzaChjaGlsZC5kYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm5vZGUuaW5zZXJ0QmVmb3JlKGNoaWxkLm5vZGUsIGJlZm9yZS5ub2RlKVxuICAgICAgY2hpbGRyZW4uc3BsaWNlKGksIDAsIGNoaWxkLmRhdGEpXG4gICAgfVxuXG4gIH0sXG5cbiAgcmVtb3ZlQ2hpbGQ6IGZ1bmN0aW9uIChjaGlsZCkge1xuICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICAgIC8vIHJlbW92ZSBmcm9tIHRoaXMuZGF0YS5jaGlsZHJlblxuICAgIHZhciBpID0gMFxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICBpZiAoY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICBmb3IgKHZhciBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmIChjaGlsZHJlbltpXS5yZWYgPT09IGNoaWxkLmRhdGEucmVmKSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGkgPCBsKSB7XG4gICAgICAgIGNoaWxkcmVuLnNwbGljZShpLCAxKVxuICAgICAgfVxuICAgIH1cbiAgICAvLyByZW1vdmUgZnJvbSBjb21wb25lbnRNYXAgcmVjdXJzaXZlbHlcbiAgICBjb21wb25lbnRNYW5hZ2VyLnJlbW92ZUVsZW1lbnRCeVJlZihjaGlsZC5kYXRhLnJlZilcbiAgICB0aGlzLm5vZGUucmVtb3ZlQ2hpbGQoY2hpbGQubm9kZSlcbiAgfSxcblxuICB1cGRhdGVBdHRyczogZnVuY3Rpb24gKGF0dHJzKSB7XG4gICAgLy8gTm90Ze+8mmF0dHIgbXVzdCBiZSBpbmplY3RlZCBpbnRvIHRoZSBkb20gZWxlbWVudCBiZWNhdXNlXG4gICAgLy8gaXQgd2lsbCBiZSBhY2Nlc3NlZCBmcm9tIHRoZSBvdXRzaWRlIGRldmVsb3BlciBieSBldmVudC50YXJnZXQuYXR0ci5cbiAgICBpZiAoIXRoaXMubm9kZS5hdHRyKSB7XG4gICAgICB0aGlzLm5vZGUuYXR0ciA9IHt9XG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiBhdHRycykge1xuICAgICAgdmFyIHZhbHVlID0gYXR0cnNba2V5XVxuICAgICAgdmFyIGF0dHJTZXR0ZXIgPSB0aGlzLmF0dHJba2V5XVxuICAgICAgaWYgKHR5cGVvZiBhdHRyU2V0dGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGF0dHJTZXR0ZXIuY2FsbCh0aGlzLCB2YWx1ZSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgIHRoaXMubm9kZVtrZXldID0gdmFsdWVcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm5vZGUuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ub2RlLmF0dHJba2V5XSA9IHZhbHVlXG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZVN0eWxlOiBmdW5jdGlvbiAoc3R5bGUpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gc3R5bGUpIHtcbiAgICAgIHZhciB2YWx1ZSA9IHN0eWxlW2tleV1cbiAgICAgIHZhciBzdHlsZVNldHRlciA9IHRoaXMuc3R5bGVba2V5XVxuXG4gICAgICBpZiAodHlwZW9mIHN0eWxlU2V0dGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHN0eWxlU2V0dGVyLmNhbGwodGhpcywgdmFsdWUpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgJiYgKGtleSAhPT0gJ2ZsZXgnICYmIGtleSAhPT0gJ29wYWNpdHknICYmIGtleSAhPT0gJ3pJbmRleCcpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZSAqIHRoaXMuZGF0YS5zY2FsZSArICdweCdcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5vZGUuc3R5bGVba2V5XSA9IHZhbHVlXG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGJpbmRFdmVudHM6IGZ1bmN0aW9uIChldnRzKSB7XG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICAgIGlmIChldnRzXG4gICAgICAgICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChldnRzKS5zbGljZSg4LCAtMSkgPT09ICdBcnJheSdcbiAgICAgICkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBldnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBjb21wb25lbnRNYW5hZ2VyLmFkZEV2ZW50KHRoaXMsIGV2dHNbaV0pXG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8vIGRpc3BhdGNoIGEgc3BlY2lmaWVkIGV2ZW50IG9uIHRoaXMubm9kZVxuICAvLyAgLSB0eXBlOiBldmVudCB0eXBlXG4gIC8vICAtIGRhdGE6IGV2ZW50IGRhdGFcbiAgLy8gIC0gY29uZmlnOiBldmVudCBjb25maWcgb2JqZWN0XG4gIC8vICAgICAtIGJ1YmJsZXNcbiAgLy8gICAgIC0gY2FuY2VsYWJsZVxuICBkaXNwYXRjaEV2ZW50OiBmdW5jdGlvbiAodHlwZSwgZGF0YSwgY29uZmlnKSB7XG4gICAgdmFyIGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0hUTUxFdmVudHMnKVxuICAgIGNvbmZpZyA9IGNvbmZpZyB8fCB7fVxuICAgIGV2ZW50LmluaXRFdmVudCh0eXBlLCBjb25maWcuYnViYmxlcyB8fCBmYWxzZSwgY29uZmlnLmNhbmNlbGFibGUgfHwgZmFsc2UpXG4gICAgIWRhdGEgJiYgKGRhdGEgPSB7fSlcbiAgICBldmVudC5kYXRhID0gdXRpbHMuZXh0ZW5kKHt9LCBkYXRhKVxuICAgIHV0aWxzLmV4dGVuZChldmVudCwgZGF0YSlcbiAgICBpZiAodHlwZSA9PT0gJ2FwcGVhcicpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdhcHBlYXInLCBkYXRhKVxuICAgIH1cbiAgICB0aGlzLm5vZGUuZGlzcGF0Y2hFdmVudChldmVudClcbiAgfSxcblxuICB1cGRhdGVSZWN1cnNpdmVBdHRyOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgIHRoaXMudXBkYXRlQXR0cnMoZGF0YS5hdHRyKVxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgICBpZiAoY2hpbGRyZW4pIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gY29tcG9uZW50TWFuYWdlci5nZXRFbGVtZW50QnlSZWYoY2hpbGRyZW5baV0ucmVmKVxuICAgICAgICBpZiAoY2hpbGQpIHtcbiAgICAgICAgICBjaGlsZC51cGRhdGVSZWN1cnNpdmVBdHRyKGRhdGEuY2hpbGRyZW5baV0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgdXBkYXRlUmVjdXJzaXZlU3R5bGU6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgdGhpcy51cGRhdGVTdHlsZShkYXRhLnN0eWxlKVxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgICBpZiAoY2hpbGRyZW4pIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gY29tcG9uZW50TWFuYWdlci5nZXRFbGVtZW50QnlSZWYoY2hpbGRyZW5baV0ucmVmKVxuICAgICAgICBpZiAoY2hpbGQpIHtcbiAgICAgICAgICBjaGlsZC51cGRhdGVSZWN1cnNpdmVTdHlsZShkYXRhLmNoaWxkcmVuW2ldKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZVJlY3Vyc2l2ZUFsbDogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICB0aGlzLnVwZGF0ZUF0dHJzKGRhdGEuYXR0cilcbiAgICB0aGlzLnVwZGF0ZVN0eWxlKGRhdGEuc3R5bGUpXG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuXG4gICAgLy8gdmFyIG9sZFJlZiA9IHRoaXMuZGF0YS5yZWZcbiAgICAvLyBpZiAoY29tcG9uZW50TWFwW29sZFJlZl0pIHtcbiAgICAvLyAgIGRlbGV0ZSBjb21wb25lbnRNYXBbb2xkUmVmXVxuICAgIC8vIH1cbiAgICAvLyB0aGlzLmRhdGEucmVmID0gZGF0YS5yZWZcbiAgICAvLyBjb21wb25lbnRNYXBbZGF0YS5yZWZdID0gdGhpc1xuXG4gICAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gICAgaWYgKGNoaWxkcmVuKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RWxlbWVudEJ5UmVmKGNoaWxkcmVuW2ldLnJlZilcbiAgICAgICAgaWYgKGNoaWxkKSB7XG4gICAgICAgICAgY2hpbGQudXBkYXRlUmVjdXJzaXZlQWxsKGRhdGEuY2hpbGRyZW5baV0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgYXR0cjoge30sIC8vIGF0dHIgc2V0dGVyc1xuXG4gIHN0eWxlOiBPYmplY3QuY3JlYXRlKGZsZXhib3gpLCAvLyBzdHlsZSBzZXR0ZXJzXG5cbiAgY2xlYXJBdHRyOiBmdW5jdGlvbiAoKSB7XG4gIH0sXG5cbiAgY2xlYXJTdHlsZTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMubm9kZS5jc3NUZXh0ID0gJydcbiAgfVxufVxuXG5Db21wb25lbnQucHJvdG90eXBlLnN0eWxlLnBvc2l0aW9uID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIC8vIFRPRE86IG1ha2UgaXQgaW4gYSBkZWNlbnQgaW1wbGVtZW50YXRpb25cbiAgaWYgKHZhbHVlID09PSAnc3RpY2t5Jykge1xuICAgIHRoaXMubm9kZS5zdHlsZS56SW5kZXggPSAxMDBcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuc3RpY2t5ID0gbmV3IGxpYi5zdGlja3kodGhpcy5ub2RlLCB7XG4gICAgICAgIHRvcDogMFxuICAgICAgfSlcbiAgICB9LmJpbmQodGhpcyksIDApXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5ub2RlLnN0eWxlLnBvc2l0aW9uID0gdmFsdWVcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBvbmVudFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2NvbXBvbmVudC5qc1xuICoqIG1vZHVsZSBpZCA9IDE2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxuLy8gRmxleGJveCBwb2x5ZmlsbFxudmFyIGZsZXhib3hTZXR0ZXJzID0gKGZ1bmN0aW9uICgpIHtcbiAgdmFyIEJPWF9BTElHTiA9IHtcbiAgICBzdHJldGNoOiAnc3RyZXRjaCcsXG4gICAgJ2ZsZXgtc3RhcnQnOiAnc3RhcnQnLFxuICAgICdmbGV4LWVuZCc6ICdlbmQnLFxuICAgIGNlbnRlcjogJ2NlbnRlcidcbiAgfVxuICB2YXIgQk9YX09SSUVOVCA9IHtcbiAgICByb3c6ICdob3Jpem9udGFsJyxcbiAgICBjb2x1bW46ICd2ZXJ0aWNhbCdcbiAgfVxuICB2YXIgQk9YX1BBQ0sgPSB7XG4gICAgJ2ZsZXgtc3RhcnQnOiAnc3RhcnQnLFxuICAgICdmbGV4LWVuZCc6ICdlbmQnLFxuICAgIGNlbnRlcjogJ2NlbnRlcicsXG4gICAgJ3NwYWNlLWJldHdlZW4nOiAnanVzdGlmeScsXG4gICAgJ3NwYWNlLWFyb3VuZCc6ICdqdXN0aWZ5JyAvLyBKdXN0IHNhbWUgYXMgYHNwYWNlLWJldHdlZW5gXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBmbGV4OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRCb3hGbGV4ID0gdmFsdWVcbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRGbGV4ID0gdmFsdWVcbiAgICAgIHRoaXMubm9kZS5zdHlsZS5mbGV4ID0gdmFsdWVcbiAgICB9LFxuICAgIGFsaWduSXRlbXM6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgdGhpcy5ub2RlLnN0eWxlLndlYmtpdEJveEFsaWduID0gQk9YX0FMSUdOW3ZhbHVlXVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLndlYmtpdEFsaWduSXRlbXMgPSB2YWx1ZVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLmFsaWduSXRlbXMgPSB2YWx1ZVxuICAgIH0sXG4gICAgYWxpZ25TZWxmOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRBbGlnblNlbGYgPSB2YWx1ZVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLmFsaWduU2VsZiA9IHZhbHVlXG4gICAgfSxcbiAgICBmbGV4RGlyZWN0aW9uOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRCb3hPcmllbnQgPSBCT1hfT1JJRU5UW3ZhbHVlXVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLndlYmtpdEZsZXhEaXJlY3Rpb24gPSB2YWx1ZVxuICAgICAgdGhpcy5ub2RlLnN0eWxlLmZsZXhEaXJlY3Rpb24gPSB2YWx1ZVxuICAgIH0sXG4gICAganVzdGlmeUNvbnRlbnQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgdGhpcy5ub2RlLnN0eWxlLndlYmtpdEJveFBhY2sgPSBCT1hfUEFDS1t2YWx1ZV1cbiAgICAgIHRoaXMubm9kZS5zdHlsZS53ZWJraXRKdXN0aWZ5Q29udGVudCA9IHZhbHVlXG4gICAgICB0aGlzLm5vZGUuc3R5bGUuanVzdGlmeUNvbnRlbnQgPSB2YWx1ZVxuICAgIH1cbiAgfVxufSkoKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZsZXhib3hTZXR0ZXJzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2ZsZXhib3guanNcbiAqKiBtb2R1bGUgaWQgPSAxN1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSAmJiAod2luZG93ID0ge2N0cmw6IHt9LCBsaWI6IHt9fSk7IXdpbmRvdy5jdHJsICYmICh3aW5kb3cuY3RybCA9IHt9KTshd2luZG93LmxpYiAmJiAod2luZG93LmxpYiA9IHt9KTshZnVuY3Rpb24oYSxiLGMpe2Z1bmN0aW9uIGQoYSl7cmV0dXJuIG51bGwhPWEmJlwib2JqZWN0XCI9PXR5cGVvZiBhJiZPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSk9PU9iamVjdC5wcm90b3R5cGV9ZnVuY3Rpb24gZShhLGIpe3ZhciBjLGQsZSxmPW51bGwsZz0wLGg9ZnVuY3Rpb24oKXtnPURhdGUubm93KCksZj1udWxsLGU9YS5hcHBseShjLGQpfTtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgaT1EYXRlLm5vdygpLGo9Yi0oaS1nKTtyZXR1cm4gYz10aGlzLGQ9YXJndW1lbnRzLDA+PWo/KGNsZWFyVGltZW91dChmKSxmPW51bGwsZz1pLGU9YS5hcHBseShjLGQpKTpmfHwoZj1zZXRUaW1lb3V0KGgsaikpLGV9fWZ1bmN0aW9uIGYoYSl7dmFyIGI9XCJcIjtyZXR1cm4gT2JqZWN0LmtleXMoYSkuZm9yRWFjaChmdW5jdGlvbihjKXtiKz1jK1wiOlwiK2FbY10rXCI7XCJ9KSxifWZ1bmN0aW9uIGcoYSxjKXshYyYmZChhKSYmKGM9YSxhPWMuZWxlbWVudCksYz1jfHx7fSxhLm5vZGVUeXBlIT1iLkVMRU1FTlRfTk9ERSYmXCJzdHJpbmdcIj09dHlwZW9mIGEmJihhPWIucXVlcnlTZWxlY3RvcihhKSk7dmFyIGU9dGhpcztlLmVsZW1lbnQ9YSxlLnRvcD1jLnRvcHx8MCxlLndpdGhpblBhcmVudD12b2lkIDA9PWMud2l0aGluUGFyZW50PyExOmMud2l0aGluUGFyZW50LGUuaW5pdCgpfXZhciBoPWEucGFyc2VJbnQsaT1uYXZpZ2F0b3IudXNlckFnZW50LGo9ISFpLm1hdGNoKC9GaXJlZm94L2kpLGs9ISFpLm1hdGNoKC9JRU1vYmlsZS9pKSxsPWo/XCItbW96LVwiOms/XCItbXMtXCI6XCItd2Via2l0LVwiLG09aj9cIk1velwiOms/XCJtc1wiOlwid2Via2l0XCIsbj1mdW5jdGlvbigpe3ZhciBhPWIuY3JlYXRlRWxlbWVudChcImRpdlwiKSxjPWEuc3R5bGU7cmV0dXJuIGMuY3NzVGV4dD1cInBvc2l0aW9uOlwiK2wrXCJzdGlja3k7cG9zaXRpb246c3RpY2t5O1wiLC0xIT1jLnBvc2l0aW9uLmluZGV4T2YoXCJzdGlja3lcIil9KCk7Zy5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOmcsaW5pdDpmdW5jdGlvbigpe3ZhciBhPXRoaXMsYj1hLmVsZW1lbnQsYz1iLnN0eWxlO2NbbStcIlRyYW5zZm9ybVwiXT1cInRyYW5zbGF0ZVooMClcIixjLnRyYW5zZm9ybT1cInRyYW5zbGF0ZVooMClcIixhLl9vcmlnaW5Dc3NUZXh0PWMuY3NzVGV4dCxuPyhjLnBvc2l0aW9uPWwrXCJzdGlja3lcIixjLnBvc2l0aW9uPVwic3RpY2t5XCIsYy50b3A9YS50b3ArXCJweFwiKTooYS5fc2ltdWxhdGVTdGlja3koKSxhLl9iaW5kUmVzaXplKCkpfSxfYmluZFJlc2l6ZTpmdW5jdGlvbigpe3ZhciBiPXRoaXMsYz0vYW5kcm9pZC9naS50ZXN0KG5hdmlnYXRvci5hcHBWZXJzaW9uKSxkPWIuX3Jlc2l6ZUV2ZW50PVwib25vcmllbnRhdGlvbmNoYW5nZVwiaW4gYT9cIm9yaWVudGF0aW9uY2hhbmdlXCI6XCJyZXNpemVcIixlPWIuX3Jlc2l6ZUhhbmRsZXI9ZnVuY3Rpb24oKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Yi5yZWZyZXNoKCl9LGM/MjAwOjApfTthLmFkZEV2ZW50TGlzdGVuZXIoZCxlLCExKX0scmVmcmVzaDpmdW5jdGlvbigpe3ZhciBhPXRoaXM7bnx8KGEuX2RldGFjaCgpLGEuX3NpbXVsYXRlU3RpY2t5KCkpfSxfYWRkUGxhY2Vob2xkZXI6ZnVuY3Rpb24oYSl7dmFyIGMsZD10aGlzLGU9ZC5lbGVtZW50LGc9YS5wb3NpdGlvbjtpZigtMSE9W1wic3RhdGljXCIsXCJyZWxhdGl2ZVwiXS5pbmRleE9mKGcpKXtjPWQuX3BsYWNlaG9sZGVyRWxlbWVudD1iLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7dmFyIGk9aChhLndpZHRoKStoKGEubWFyZ2luTGVmdCkraChhLm1hcmdpblJpZ2h0KSxqPWgoYS5oZWlnaHQpO1wiYm9yZGVyLWJveFwiIT1hLmJveFNpemluZyYmKGkrPWgoYS5ib3JkZXJMZWZ0V2lkdGgpK2goYS5ib3JkZXJSaWdodFdpZHRoKStoKGEucGFkZGluZ0xlZnQpK2goYS5wYWRkaW5nUmlnaHQpLGorPWgoYS5ib3JkZXJUb3BXaWR0aCkraChhLmJvcmRlckJvdHRvbVdpZHRoKStoKGEucGFkZGluZ1RvcCkraChhLnBhZGRpbmdCb3R0b20pKSxjLnN0eWxlLmNzc1RleHQ9Zih7ZGlzcGxheTpcIm5vbmVcIix2aXNpYmlsaXR5OlwiaGlkZGVuXCIsd2lkdGg6aStcInB4XCIsaGVpZ2h0OmorXCJweFwiLG1hcmdpbjowLFwibWFyZ2luLXRvcFwiOmEubWFyZ2luVG9wLFwibWFyZ2luLWJvdHRvbVwiOmEubWFyZ2luQm90dG9tLGJvcmRlcjowLHBhZGRpbmc6MCxcImZsb2F0XCI6YVtcImZsb2F0XCJdfHxhLmNzc0Zsb2F0fSksZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShjLGUpfXJldHVybiBjfSxfc2ltdWxhdGVTdGlja3k6ZnVuY3Rpb24oKXt2YXIgYz10aGlzLGQ9Yy5lbGVtZW50LGc9Yy50b3AsaT1kLnN0eWxlLGo9ZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxrPWdldENvbXB1dGVkU3R5bGUoZCxcIlwiKSxsPWQucGFyZW50Tm9kZSxtPWdldENvbXB1dGVkU3R5bGUobCxcIlwiKSxuPWMuX2FkZFBsYWNlaG9sZGVyKGspLG89Yy53aXRoaW5QYXJlbnQscD1jLl9vcmlnaW5Dc3NUZXh0LHE9ai50b3AtZythLnBhZ2VZT2Zmc2V0LHI9bC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5ib3R0b20taChtLnBhZGRpbmdCb3R0b20pLWgobS5ib3JkZXJCb3R0b21XaWR0aCktaChrLm1hcmdpbkJvdHRvbSktai5oZWlnaHQtZythLnBhZ2VZT2Zmc2V0LHM9cCtmKHtwb3NpdGlvbjpcImZpeGVkXCIsdG9wOmcrXCJweFwiLHdpZHRoOmsud2lkdGgsXCJtYXJnaW4tdG9wXCI6MH0pLHQ9cCtmKHtwb3NpdGlvbjpcImFic29sdXRlXCIsdG9wOnIrXCJweFwiLHdpZHRoOmsud2lkdGh9KSx1PTEsdj1jLl9zY3JvbGxIYW5kbGVyPWUoZnVuY3Rpb24oKXt2YXIgYj1hLnBhZ2VZT2Zmc2V0O3E+Yj8xIT11JiYoaS5jc3NUZXh0PXAsbiYmKG4uc3R5bGUuZGlzcGxheT1cIm5vbmVcIiksdT0xKTohbyYmYj49cXx8byYmYj49cSYmcj5iPzIhPXUmJihpLmNzc1RleHQ9cyxuJiYzIT11JiYobi5zdHlsZS5kaXNwbGF5PVwiYmxvY2tcIiksdT0yKTpvJiYzIT11JiYoaS5jc3NUZXh0PXQsbiYmMiE9dSYmKG4uc3R5bGUuZGlzcGxheT1cImJsb2NrXCIpLHU9Myl9LDEwMCk7aWYoYS5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsdiwhMSksYS5wYWdlWU9mZnNldD49cSl7dmFyIHc9Yi5jcmVhdGVFdmVudChcIkhUTUxFdmVudHNcIik7dy5pbml0RXZlbnQoXCJzY3JvbGxcIiwhMCwhMCksYS5kaXNwYXRjaEV2ZW50KHcpfX0sX2RldGFjaDpmdW5jdGlvbigpe3ZhciBiPXRoaXMsYz1iLmVsZW1lbnQ7aWYoYy5zdHlsZS5jc3NUZXh0PWIuX29yaWdpbkNzc1RleHQsIW4pe3ZhciBkPWIuX3BsYWNlaG9sZGVyRWxlbWVudDtkJiZjLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZCksYS5yZW1vdmVFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsYi5fc2Nyb2xsSGFuZGxlciwhMSl9fSxkZXN0cm95OmZ1bmN0aW9uKCl7dmFyIGI9dGhpcztiLl9kZXRhY2goKTt2YXIgYz1iLmVsZW1lbnQuc3R5bGU7Yy5yZW1vdmVQcm9wZXJ0eShsK1widHJhbnNmb3JtXCIpLGMucmVtb3ZlUHJvcGVydHkoXCJ0cmFuc2Zvcm1cIiksbnx8YS5yZW1vdmVFdmVudExpc3RlbmVyKGIuX3Jlc2l6ZUV2ZW50LGIuX3Jlc2l6ZUhhbmRsZXIsITEpfX0sYy5zdGlja3k9Z30od2luZG93LGRvY3VtZW50LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSk7O21vZHVsZS5leHBvcnRzID0gd2luZG93LmxpYlsnc3RpY2t5J107XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vZml4ZWRzdGlja3kvYnVpbGQvc3RpY2t5LmNvbW1vbi5qc1xuICoqIG1vZHVsZSBpZCA9IDE4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKVxuXG52YXIgX3NlbmRlck1hcCA9IHt9XG5cbmZ1bmN0aW9uIFNlbmRlcihpbnN0YW5jZSkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2VuZGVyKSkge1xuICAgIHJldHVybiBuZXcgU2VuZGVyKGluc3RhbmNlKVxuICB9XG4gIHRoaXMuaW5zdGFuY2VJZCA9IGluc3RhbmNlLmluc3RhbmNlSWRcbiAgdGhpcy53ZWV4SW5zdGFuY2UgPSBpbnN0YW5jZVxuICBfc2VuZGVyTWFwW3RoaXMuaW5zdGFuY2VJZF0gPSB0aGlzXG59XG5cbmZ1bmN0aW9uIF9zZW5kKGluc3RhbmNlSWQsIG1zZykge1xuICBjYWxsSlMoaW5zdGFuY2VJZCwgW21zZ10pXG59XG5cblNlbmRlci5nZXRTZW5kZXIgPSBmdW5jdGlvbiAoaW5zdGFuY2VJZCkge1xuICByZXR1cm4gX3NlbmRlck1hcFtpbnN0YW5jZUlkXVxufVxuXG5TZW5kZXIucHJvdG90eXBlID0ge1xuXG4gIC8vIHBlcmZvcm0gYSBjYWxsYmFjayB0byBqc2ZyYW1ld29yay5cbiAgcGVyZm9ybUNhbGxiYWNrOiBmdW5jdGlvbiAoY2FsbGJhY2tJZCwgZGF0YSkge1xuICAgIHZhciBhcmdzID0gW2NhbGxiYWNrSWRdXG4gICAgZGF0YSAmJiBhcmdzLnB1c2goZGF0YSlcbiAgICBfc2VuZCh0aGlzLmluc3RhbmNlSWQsIHtcbiAgICAgIG1ldGhvZDogJ2NhbGxiYWNrJyxcbiAgICAgIGFyZ3M6IGFyZ3NcbiAgICB9KVxuICB9LFxuXG4gIGZpcmVFdmVudDogZnVuY3Rpb24gKHJlZiwgdHlwZSwgZXZlbnQpIHtcbiAgICAvLyBOb3RlIHRoYXQgdGhlIGV2ZW50LnRhcmdldCBtdXN0IGJlIHRoZSBzdGFuZGFyZCBldmVudCdzXG4gICAgLy8gY3VycmVudFRhcmdldC4gVGhlcmVmb3IgYSBwcm9jZXNzIGZvciByZXBsYWNpbmcgdGFyZ2V0IG11c3RcbiAgICAvLyBiZSBkb25lIHdoZW4gYSBldmVudCBpcyBmaXJlZC5cbiAgICB2YXIgZXZ0ID0gdXRpbHMuZXh0ZW5kKHt9LCBldmVudClcbiAgICBldnQudGFyZ2V0ID0gZXZ0LmN1cnJlbnRUYXJnZXRcbiAgICBldnQudmFsdWUgPSBldmVudC50YXJnZXQudmFsdWVcbiAgICBldnQudGltZXN0YW1wID0gRGF0ZS5ub3coKVxuICAgIF9zZW5kKHRoaXMuaW5zdGFuY2VJZCwge1xuICAgICAgbWV0aG9kOiAnZmlyZUV2ZW50JyxcbiAgICAgIGFyZ3M6IFtyZWYsIHR5cGUsIGV2dF1cbiAgICB9KVxuICB9XG5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTZW5kZXJcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2JyaWRnZS9zZW5kZXIuanNcbiAqKiBtb2R1bGUgaWQgPSAxOVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKVxudmFyIHByb3RvY29sID0gcmVxdWlyZSgnLi4vcHJvdG9jb2wnKVxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKVxudmFyIEZyYW1lVXBkYXRlciA9IHJlcXVpcmUoJy4uL2ZyYW1lVXBkYXRlcicpXG52YXIgU2VuZGVyID0gcmVxdWlyZSgnLi9zZW5kZXInKVxuXG52YXIgY2FsbFF1ZXVlID0gW11cbi8vIE5lZWQgYSB0YXNrIGNvdW50ZXI/XG4vLyBXaGVuIEZyYW1lVXBkYXRlciBpcyBub3QgYWN0aXZhdGVkLCB0YXNrcyB3aWxsIG5vdCBiZSBwdXNoXG4vLyBpbnRvIGNhbGxRdWV1ZSBhbmQgdGhlcmUgd2lsbCBiZSBubyB0cmFjZSBmb3Igc2l0dWF0aW9uIG9mXG4vLyBleGVjdXRpb24gb2YgdGFza3MuXG5cbi8vIGdpdmUgMTBtcyBmb3IgY2FsbCBoYW5kbGluZywgYW5kIHJlc3QgNm1zIGZvciBvdGhlcnNcbnZhciBNQVhfVElNRV9GT1JfRUFDSF9GUkFNRSA9IDEwXG5cbi8vIGNhbGxOYXRpdmU6IGpzRnJhbWV3b3JrIHdpbGwgY2FsbCB0aGlzIG1ldGhvZCB0byB0YWxrIHRvXG4vLyB0aGlzIHJlbmRlcmVyLlxuLy8gcGFyYW1zOlxuLy8gIC0gaW5zdGFuY2VJZDogc3RyaW5nLlxuLy8gIC0gdGFza3M6IGFycmF5IG9mIG9iamVjdC5cbi8vICAtIGNhbGxiYWNrSWQ6IG51bWJlci5cbmZ1bmN0aW9uIGNhbGxOYXRpdmUoaW5zdGFuY2VJZCwgdGFza3MsIGNhbGxiYWNrSWQpIHtcbiAgdmFyIGNhbGxzID0gW11cbiAgaWYgKHR5cGVvZiB0YXNrcyA9PT0gJ3N0cmluZycpIHtcbiAgICB0cnkge1xuICAgICAgY2FsbHMgPSBKU09OLnBhcnNlKHRhc2tzKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ2ludmFsaWQgdGFza3M6JywgdGFza3MpXG4gICAgfVxuICB9IGVsc2UgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0YXNrcykuc2xpY2UoOCwgLTEpID09PSAnQXJyYXknKSB7XG4gICAgY2FsbHMgPSB0YXNrc1xuICB9XG4gIHZhciBsZW4gPSBjYWxscy5sZW5ndGhcbiAgY2FsbHNbbGVuIC0gMV0uY2FsbGJhY2tJZCA9ICghY2FsbGJhY2tJZCAmJiBjYWxsYmFja0lkICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAtMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjYWxsYmFja0lkXG4gIC8vIFRvIHNvbHZlIHRoZSBwcm9ibGVtIG9mIGNhbGxhcHAsIHRoZSB0d28td2F5IHRpbWUgbG9vcCBydWxlIG11c3RcbiAgLy8gYmUgcmVwbGFjZWQgYnkgY2FsbGluZyBkaXJlY3RseSBleGNlcHQgdGhlIHNpdHVhdGlvbiBvZiBwYWdlIGxvYWRpbmcuXG4gIC8vIDIwMTUtMTEtMDNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChGcmFtZVVwZGF0ZXIuaXNBY3RpdmUoKSkge1xuICAgICAgY2FsbFF1ZXVlLnB1c2goe1xuICAgICAgICBpbnN0YW5jZUlkOiBpbnN0YW5jZUlkLFxuICAgICAgICBjYWxsOiBjYWxsc1tpXVxuICAgICAgfSlcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBwcm9jZXNzQ2FsbChpbnN0YW5jZUlkLCBjYWxsc1tpXSlcbiAgICB9XG4gIH1cblxufVxuXG5mdW5jdGlvbiBwcm9jZXNzQ2FsbFF1ZXVlKCkge1xuICB2YXIgbGVuID0gY2FsbFF1ZXVlLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIHN0YXJ0ID0gRGF0ZS5ub3coKVxuICB2YXIgZWxhcHNlZCA9IDBcblxuICB3aGlsZSAoLS1sZW4gPj0gMCAmJiBlbGFwc2VkIDwgTUFYX1RJTUVfRk9SX0VBQ0hfRlJBTUUpIHtcbiAgICB2YXIgY2FsbE9iaiA9IGNhbGxRdWV1ZS5zaGlmdCgpXG4gICAgcHJvY2Vzc0NhbGwoY2FsbE9iai5pbnN0YW5jZUlkLCBjYWxsT2JqLmNhbGwpXG4gICAgZWxhcHNlZCA9IERhdGUubm93KCkgLSBzdGFydFxuICB9XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NDYWxsKGluc3RhbmNlSWQsIGNhbGwpIHtcbiAgdmFyIG1vZHVsZU5hbWUgPSBjYWxsLm1vZHVsZVxuICB2YXIgbWV0aG9kTmFtZSA9IGNhbGwubWV0aG9kXG4gIHZhciBtb2R1bGUsIG1ldGhvZFxuICB2YXIgYXJncyA9IGNhbGwuYXJncyB8fCBjYWxsLmFyZ3VtZW50cyB8fCBbXVxuXG4gIGlmICghKG1vZHVsZSA9IHByb3RvY29sLmFwaU1vZHVsZVttb2R1bGVOYW1lXSkpIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoIShtZXRob2QgPSBtb2R1bGVbbWV0aG9kTmFtZV0pKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBtZXRob2QuYXBwbHkocHJvdG9jb2wuZ2V0V2VleEluc3RhbmNlKGluc3RhbmNlSWQpLCBhcmdzKVxuXG4gIHZhciBjYWxsYmFja0lkID0gY2FsbC5jYWxsYmFja0lkXG4gIGlmICgoY2FsbGJhY2tJZFxuICAgIHx8IGNhbGxiYWNrSWQgPT09IDBcbiAgICB8fCBjYWxsYmFja0lkID09PSAnMCcpXG4gICAgJiYgY2FsbGJhY2tJZCAhPT0gJy0xJ1xuICAgICYmIGNhbGxiYWNrSWQgIT09IC0xKSB7XG4gICAgcGVyZm9ybU5leHRUaWNrKGluc3RhbmNlSWQsIGNhbGxiYWNrSWQpXG4gIH1cbn1cblxuZnVuY3Rpb24gcGVyZm9ybU5leHRUaWNrKGluc3RhbmNlSWQsIGNhbGxiYWNrSWQpIHtcbiAgU2VuZGVyLmdldFNlbmRlcihpbnN0YW5jZUlkKS5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZClcbn1cblxuZnVuY3Rpb24gbmF0aXZlTG9nKCkge1xuICBpZiAoY29uZmlnLmRlYnVnKSB7XG4gICAgaWYgKGFyZ3VtZW50c1swXS5tYXRjaCgvXnBlcmYvKSkge1xuICAgICAgY29uc29sZS5pbmZvLmFwcGx5KGNvbnNvbGUsIGFyZ3VtZW50cylcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zb2xlLmRlYnVnLmFwcGx5KGNvbnNvbGUsIGFyZ3VtZW50cylcbiAgfVxufVxuXG5mdW5jdGlvbiBleHBvcnRzQnJpZGdlTWV0aG9kc1RvR2xvYmFsKCkge1xuICBnbG9iYWwuY2FsbE5hdGl2ZSA9IGNhbGxOYXRpdmVcbiAgZ2xvYmFsLm5hdGl2ZUxvZyA9IG5hdGl2ZUxvZ1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cbiAgICAvLyBwcm9jZXNzIGNhbGxRdWV1ZSBldmVyeSAxNiBtaWxsaXNlY29uZHMuXG4gICAgRnJhbWVVcGRhdGVyLmFkZFVwZGF0ZU9ic2VydmVyKHByb2Nlc3NDYWxsUXVldWUpXG4gICAgRnJhbWVVcGRhdGVyLnN0YXJ0KClcblxuICAgIC8vIGV4cG9ydHMgbWV0aG9kcyB0byBnbG9iYWwod2luZG93KS5cbiAgICBleHBvcnRzQnJpZGdlTWV0aG9kc1RvR2xvYmFsKClcbiAgfVxuXG59XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2JyaWRnZS9yZWNlaXZlci5qc1xuICoqIG1vZHVsZSBpZCA9IDIwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJ2YXIgUm9vdENvbXBvbmVudCA9IHJlcXVpcmUoJy4vcm9vdCcpXG52YXIgQ29udGFpbmVyID0gcmVxdWlyZSgnLi9jb250YWluZXInKVxudmFyIEltYWdlID0gcmVxdWlyZSgnLi9pbWFnZScpXG52YXIgVGV4dCA9IHJlcXVpcmUoJy4vdGV4dCcpXG52YXIgTGlzdCA9IHJlcXVpcmUoJy4vbGlzdCcpXG52YXIgQ291bnRkb3duID0gcmVxdWlyZSgnLi9jb3VudGRvd24nKVxudmFyIE1hcnF1ZWUgPSByZXF1aXJlKCcuL21hcnF1ZWUnKVxudmFyIFNsaWRlciA9IHJlcXVpcmUoJy4vc2xpZGVyJylcbnZhciBJbmRpY2F0b3IgPSByZXF1aXJlKCcuL2luZGljYXRvcicpXG52YXIgVGFiaGVhZGVyID0gcmVxdWlyZSgnLi90YWJoZWFkZXInKVxudmFyIFNjcm9sbGVyID0gcmVxdWlyZSgnLi9zY3JvbGxlcicpXG52YXIgSW5wdXQgPSByZXF1aXJlKCcuL2lucHV0JylcbnZhciBTZWxlY3QgPSByZXF1aXJlKCcuL3NlbGVjdCcpXG52YXIgRGF0ZXBpY2tlciA9IHJlcXVpcmUoJy4vZGF0ZXBpY2tlcicpXG52YXIgVGltZXBpY2tlciA9IHJlcXVpcmUoJy4vdGltZXBpY2tlcicpXG52YXIgVmlkZW8gPSByZXF1aXJlKCcuL3ZpZGVvJylcbnZhciBTd2l0Y2ggPSByZXF1aXJlKCcuL3N3aXRjaCcpXG52YXIgQSA9IHJlcXVpcmUoJy4vYScpXG52YXIgRW1iZWQgPSByZXF1aXJlKCcuL2VtYmVkJylcblxudmFyIGNvbXBvbmVudHMgPSB7XG4gIGluaXQ6IGZ1bmN0aW9uIChXZWV4KSB7XG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgncm9vdCcsIFJvb3RDb21wb25lbnQpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgncm9vdCcsIFJvb3RDb21wb25lbnQpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnY29udGFpbmVyJywgQ29udGFpbmVyKVxuICAgIFdlZXgucmVnaXN0ZXJDb21wb25lbnQoJ2ltYWdlJywgSW1hZ2UpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgndGV4dCcsIFRleHQpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnbGlzdCcsIExpc3QpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnY291bnRkb3duJywgQ291bnRkb3duKVxuICAgIFdlZXgucmVnaXN0ZXJDb21wb25lbnQoJ21hcnF1ZWUnLCBNYXJxdWVlKVxuICAgIFdlZXgucmVnaXN0ZXJDb21wb25lbnQoJ3NsaWRlcicsIFNsaWRlcilcbiAgICBXZWV4LnJlZ2lzdGVyQ29tcG9uZW50KCdpbmRpY2F0b3InLCBJbmRpY2F0b3IpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgndGFiaGVhZGVyJywgVGFiaGVhZGVyKVxuICAgIFdlZXgucmVnaXN0ZXJDb21wb25lbnQoJ3Njcm9sbGVyJywgU2Nyb2xsZXIpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnaW5wdXQnLCBJbnB1dClcbiAgICBXZWV4LnJlZ2lzdGVyQ29tcG9uZW50KCdzZWxlY3QnLCBTZWxlY3QpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnZGF0ZXBpY2tlcicsIERhdGVwaWNrZXIpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgndGltZXBpY2tlcicsIFRpbWVwaWNrZXIpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgndmlkZW8nLCBWaWRlbylcbiAgICBXZWV4LnJlZ2lzdGVyQ29tcG9uZW50KCdzd2l0Y2gnLCBTd2l0Y2gpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnYScsIEEpXG4gICAgV2VleC5yZWdpc3RlckNvbXBvbmVudCgnZW1iZWQnLCBFbWJlZClcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvbmVudHNcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSAyMVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBDb21wb25lbnRNYW5hZ2VyID0gcmVxdWlyZSgnLi4vY29tcG9uZW50TWFuYWdlcicpXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxuXG4vLyBJZiBub2RlVHlwZSBpcyBpbiB0aGlzIFdISVRFX0xJU1QsIGp1c3QgaWdub3JlIGl0IGFuZFxuLy8gcmVwbGFjZSBpdCB3aXRoIGEgZGl2IGVsZW1lbnQuXG52YXIgV0hJVEVfTElTVCA9IFtdXG5cbmZ1bmN0aW9uIFJvb3RDb21wb25lbnQoZGF0YSwgbm9kZVR5cGUpIHtcbiAgdmFyIGlkID0gZGF0YS5yb290SWQgKyAnLXJvb3QnXG4gIHZhciBjb21wb25lbnRNYW5hZ2VyID0gQ29tcG9uZW50TWFuYWdlci5nZXRJbnN0YW5jZShkYXRhLmluc3RhbmNlSWQpXG5cbiAgLy8gUmV0dXJuIGEgTm9kZVR5cGUgaW5zdGFuY2UuXG4gIGlmIChub2RlVHlwZSAmJiBub2RlVHlwZSAhPT0gJ2RpdicgJiYgV0hJVEVfTElTVC5pbmRleE9mKG5vZGVUeXBlKSA9PT0gLTEpIHtcbiAgICBkYXRhLnR5cGUgPSBub2RlVHlwZVxuICAgIHZhciBjbXAgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoZGF0YSlcbiAgICBjbXAubm9kZS5pZCA9IGlkXG4gICAgcmV0dXJuIGNtcFxuICB9XG5cbiAgLy8gT3RoZXJ3aXNlIHJldHVybiBhIGNvbW1vbiB3ZWV4LWNvbnRhaW5lciBjb21wb25lbnQsXG4gIC8vIHdob3NlIG5vZGUgaXMgYSBkaXYgZWxlbWVudC5cbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICB0aGlzLmRhdGEgPSBkYXRhXG4gIHRoaXMubm9kZSA9IG5vZGVcblxuICB0aGlzLmNyZWF0ZUNoaWxkcmVuKClcbiAgdGhpcy51cGRhdGVBdHRycyh0aGlzLmRhdGEuYXR0cilcbiAgLy8gaXNzdWU6IHdoZW4gYWRkIGVsZW1lbnQgdG8gYSBsaXN0IGluIGxpZmV0aW1lIGhvb2sgJ3JlYWR5JywgdGhlXG4gIC8vIHN0eWxlcyBpcyBzZXQgdG8gdGhlIGNsYXNzU3R5bGUsIG5vdCBzdHlsZS4gVGhpcyBpcyBhIGlzc3VlXG4gIC8vIHRoYXQganNmcmFtZXdvcmsgc2hvdWxkIGRvIHNvbWV0aGluZyBhYm91dC5cbiAgdmFyIGNsYXNzU3R5bGUgPSB0aGlzLmRhdGEuY2xhc3NTdHlsZVxuICBjbGFzc1N0eWxlICYmIHRoaXMudXBkYXRlU3R5bGUodGhpcy5kYXRhLmNsYXNzU3R5bGUpXG4gIHRoaXMudXBkYXRlU3R5bGUodGhpcy5kYXRhLnN0eWxlKVxuICB0aGlzLmJpbmRFdmVudHModGhpcy5kYXRhLmV2ZW50KVxufVxuXG5Sb290Q29tcG9uZW50LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxubW9kdWxlLmV4cG9ydHMgPSBSb290Q29tcG9uZW50XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvcm9vdC5qc1xuICoqIG1vZHVsZSBpZCA9IDIyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxucmVxdWlyZSgnLi4vc3R5bGVzL2NvbnRhaW5lci5zY3NzJylcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcblxuZnVuY3Rpb24gQ29udGFpbmVyIChkYXRhLCBub2RlVHlwZSkge1xuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhLCBub2RlVHlwZSlcbiAgdGhpcy5ub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtY29udGFpbmVyJylcbn1cblxuQ29udGFpbmVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxubW9kdWxlLmV4cG9ydHMgPSBDb250YWluZXJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9jb250YWluZXIuanNcbiAqKiBtb2R1bGUgaWQgPSAyM1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2NvbnRhaW5lci5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vY29udGFpbmVyLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2NvbnRhaW5lci5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy9jb250YWluZXIuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDI0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi53ZWV4LWNvbnRhaW5lciB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgZGlzcGxheTogLXdlYmtpdC1ib3g7XFxuICBkaXNwbGF5OiAtd2Via2l0LWZsZXg7XFxuICBkaXNwbGF5OiBmbGV4O1xcbiAgLXdlYmtpdC1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcXG4gIC13ZWJraXQtZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICBib3JkZXI6IDAgc29saWQgYmxhY2s7XFxuICBtYXJnaW46IDA7XFxuICBwYWRkaW5nOiAwOyB9XFxuXFxuLndlZXgtZWxlbWVudCB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgcG9zaXRpb246IHJlbGF0aXZlOyB9XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL3NyYy9zcmMvc3R5bGVzL2NvbnRhaW5lci5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0UsdUJBQXNCO0VBQ3RCLHFCQUFvQjtFQUNwQixzQkFBcUI7RUFDckIsY0FBYTtFQUNiLDZCQUE0QjtFQUM1QiwrQkFBOEI7RUFDOUIsdUJBQXNCO0VBQ3RCLG1CQUFrQjtFQUNsQixzQkFBcUI7RUFDckIsVUFBUztFQUNULFdBQ0QsRUFBQzs7QUFFRjtFQUNFLHVCQUF1QjtFQUN2QixtQkFBbUIsRUFDcEJcIixcImZpbGVcIjpcImNvbnRhaW5lci5zY3NzXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi53ZWV4LWNvbnRhaW5lciB7XFxuICBib3gtc2l6aW5nOmJvcmRlci1ib3g7XFxuICBkaXNwbGF5Oi13ZWJraXQtYm94O1xcbiAgZGlzcGxheTotd2Via2l0LWZsZXg7XFxuICBkaXNwbGF5OmZsZXg7XFxuICAtd2Via2l0LWJveC1vcmllbnQ6dmVydGljYWw7XFxuICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOmNvbHVtbjtcXG4gIGZsZXgtZGlyZWN0aW9uOmNvbHVtbjtcXG4gIHBvc2l0aW9uOnJlbGF0aXZlO1xcbiAgYm9yZGVyOjAgc29saWQgYmxhY2s7XFxuICBtYXJnaW46MDtcXG4gIHBhZGRpbmc6MFxcbn1cXG5cXG4ud2VleC1lbGVtZW50IHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxufVwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Nhc3MtbG9hZGVyP3NvdXJjZU1hcCEuL3NyYy9zdHlsZXMvY29udGFpbmVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSAyNVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG52YXIgTGF6eUxvYWQgPSByZXF1aXJlKCcuLi9sYXp5TG9hZCcpXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcblxudmFyIERFRkFVTFRfU0laRSA9IDIwMFxudmFyIFJFU0laRV9NT0RFUyA9IFsnY292ZXInLCAnY29udGFpbiddIC8vIG5vdCB0ZW1wb3JhcmlseSBzdXBwb3J0ZWRcblxuLyoqXG4gKiByZXNpemU9Y292ZXJ8Y29udGFpbnxzdHJldGNoIHYxLjQgdGVtcG9yYXJpbHkgbm90IHN1cHBvcnRlZFxuICogc3JjPXVybFxuICovXG5cbmZ1bmN0aW9uIEltYWdlIChkYXRhKSB7XG4gIHRoaXMud2lkdGggPSBkYXRhLnN0eWxlICYmIGRhdGEuc3R5bGUud2lkdGhcbiAgICAgICAgICAgICAgID8gKGRhdGEuc3R5bGUud2lkdGggKyAnJykucmVwbGFjZSgvW15cXGRdL2csICcnKVxuICAgICAgICAgICAgICAgOiBERUZBVUxUX1NJWkVcbiAgdGhpcy5oZWlnaHQgPSBkYXRhLnN0eWxlICYmIGRhdGEuc3R5bGUuaGVpZ2h0XG4gICAgICAgICAgICAgICA/IChkYXRhLnN0eWxlLmhlaWdodCArICcnKS5yZXBsYWNlKC9bXlxcZF0vZywgJycpXG4gICAgICAgICAgICAgICA6IERFRkFVTFRfU0laRVxuICB0aGlzLndpZHRoICo9IGRhdGEuc2NhbGVcbiAgdGhpcy5oZWlnaHQgKj0gZGF0YS5zY2FsZVxuICB2YXIgbW9kZVxuICB2YXIgYXR0ciA9IGRhdGEuYXR0clxuICBhdHRyICYmIChtb2RlID0gYXR0ci5yZXNpemUgfHwgYXR0ci5yZXNpemVNb2RlKVxuICBpZiAoUkVTSVpFX01PREVTLmluZGV4T2YobW9kZSkgIT09IC0xKSB7XG4gICAgdGhpcy5tb2RlID0gbW9kZVxuICAgIC8vIFRPRE86IHJlc2l6ZS1tb2RlIGlzIG5vdCB0ZW1wb3JhcmlseSBzdXBwb3J0ZWQuXG4gIH1cbiAgQXRvbWljLmNhbGwodGhpcywgZGF0YSlcbn1cblxuSW1hZ2UucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5JbWFnZS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1lbGVtZW50JylcbiAgbm9kZS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJ1xuICBub2RlLnN0eWxlLm91dGxpbmUgPSAnbm9uZSdcbiAgcmV0dXJuIG5vZGVcbn1cblxuSW1hZ2UucHJvdG90eXBlLmF0dHIgPSB7XG4gIHNyYzogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgaWYgKCF0aGlzLm5vZGUuc3JjKSB7XG4gICAgICB0aGlzLm5vZGUuc3JjID0gbGliLmltZy5kZWZhdWx0U3JjXG4gICAgfVxuICAgIExhenlMb2FkLm1ha2VJbWFnZUxhenkodGhpcy5ub2RlLCB2YWx1ZSlcbiAgfVxufVxuXG5JbWFnZS5wcm90b3R5cGUuY2xlYXJBdHRyID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLm5vZGUuc3JjID0gJydcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBJbWFnZVxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2ltYWdlLmpzXG4gKiogbW9kdWxlIGlkID0gMjZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxuXG4vLyBDb21wb25lbnQgd2hpY2ggY2FuIGhhdmUgbm8gc3ViY29tcG9uZW50cy5cbi8vIFRoaXMgY29tcG9uZW50IHNob3VsZCBub3QgYmUgaW5zdGFudGlhdGVkIGRpcmVjdGx5LCBzaW5jZVxuLy8gaXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBhcyBhIGJhc2UgY2xhc3MgdG8gZXh0ZW5kIGZyb20uXG5mdW5jdGlvbiBBdG9taWMgKGRhdGEpIHtcbiAgQ29tcG9uZW50LmNhbGwodGhpcywgZGF0YSlcbn1cblxuQXRvbWljLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxuQXRvbWljLnByb3RvdHlwZS5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIC8vIGRvIG5vdGhpbmdcbiAgcmV0dXJuXG59XG5cbkF0b21pYy5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgLy8gZG8gbm90aGluZ1xuICByZXR1cm5cbn1cblxuQXRvbWljLnByb3RvdHlwZS5yZW1vdmVDaGlsZCA9IGZ1bmN0aW9uIChjaGlsZCkge1xuICAvLyBkbyBub3RoaW5nXG4gIHJldHVyblxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEF0b21pY1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2F0b21pYy5qc1xuICoqIG1vZHVsZSBpZCA9IDI3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIEF0b21pYyA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJylcblxudmFyIERFRkFVTFRfRk9OVF9TSVpFID0gMzJcblxuLy8gYXR0clxuLy8gIC0gdmFsdWU6IHRleHQgY29udGVudC5cbi8vICAtIGxpbmVzOiBtYXhpbXVtIGxpbmVzIG9mIHRoZSB0ZXh0LlxuZnVuY3Rpb24gVGV4dCAoZGF0YSkge1xuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5UZXh0LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQXRvbWljLnByb3RvdHlwZSlcblxuVGV4dC5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1jb250YWluZXInKVxuICBub2RlLnN0eWxlLmZvbnRTaXplID0gREVGQVVMVF9GT05UX1NJWkUgKiB0aGlzLmRhdGEuc2NhbGUgKyAncHgnXG4gIHRoaXMudGV4dE5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJylcbiAgLy8gR2l2ZSB0aGUgZGV2ZWxvcGVycyB0aGUgYWJpbGl0eSB0byBjb250cm9sIHNwYWNlXG4gIC8vIGFuZCBsaW5lLWJyZWFrZXJzLlxuICB0aGlzLnRleHROb2RlLnN0eWxlLndoaXRlU3BhY2UgPSAncHJlLXdyYXAnXG4gIHRoaXMudGV4dE5vZGUuc3R5bGUuZGlzcGxheSA9ICctd2Via2l0LWJveCdcbiAgdGhpcy50ZXh0Tm9kZS5zdHlsZS53ZWJraXRCb3hPcmllbnQgPSAndmVydGljYWwnXG4gIHRoaXMuc3R5bGUubGluZXMuY2FsbCh0aGlzLCB0aGlzLmRhdGEuc3R5bGUubGluZXMpXG4gIG5vZGUuYXBwZW5kQ2hpbGQodGhpcy50ZXh0Tm9kZSlcbiAgcmV0dXJuIG5vZGVcbn1cblxuVGV4dC5wcm90b3R5cGUuYXR0ciA9IHtcbiAgdmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciBzcGFuID0gdGhpcy5ub2RlLmZpcnN0Q2hpbGRcbiAgICBzcGFuLmlubmVySFRNTCA9ICcnXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHNwYW4udGV4dENvbnRlbnQgPSB2YWx1ZVxuICAgIC8qKlxuICAgICAqIERldmVsb3BlcnMgYXJlIHN1cHBvc2VkIHRvIGhhdmUgdGhlIGFiaWxpdHkgdG8gYnJlYWsgdGV4dFxuICAgICAqIGxpbmVzIG1hbnVhbGx5LiBVc2luZyBgYCZuYnNwO2BgIHRvIHJlcGxhY2UgdGV4dCBzcGFjZSBpc1xuICAgICAqIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIGBgLXdlYmtpdC1saW5lLWNsYW1wYGAuIFRoZXJlZm9yXG4gICAgICogd2UgdXNlIGBgd2hpdGUtc3BhY2U6IG5vLXdyYXBgYCBpbnN0ZWFkIChpbnN0ZWFkIG9mIHRoZVxuICAgICAqIGNvZGUgYmVsbG93KS5cblxuICAgICAgdmFyIGZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KClcbiAgICAgICAgdGV4dC5zcGxpdCgnICcpLmZvckVhY2goZnVuY3Rpb24oc3RyKSB7XG4gICAgICAgICAgdmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoc3RyKVxuICAgICAgICAgIHZhciBzcGFjZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2knKVxuICAgICAgICAgIHNwYWNlLmlubmVySFRNTCA9ICcmbmJzcDsnXG4gICAgICAgICAgZnJhZy5hcHBlbmRDaGlsZChzcGFjZSlcbiAgICAgICAgICBmcmFnLmFwcGVuZENoaWxkKHRleHROb2RlKVxuICAgICAgICB9KVxuICAgICAgICBmcmFnLnJlbW92ZUNoaWxkKGZyYWcuZmlyc3RDaGlsZClcbiAgICAgICAgc3Bhbi5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKVxuICAgICAgICBzcGFuLmFwcGVuZENoaWxkKGZyYWcpXG4gICAgICB9KVxuICAgICAgc3Bhbi5yZW1vdmVDaGlsZChzcGFuLmZpcnN0Q2hpbGQpXG4gICAgICovXG4gIH1cbn1cblxuVGV4dC5wcm90b3R5cGUuY2xlYXJBdHRyID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLm5vZGUuZmlyc3RDaGlsZC50ZXh0Q29udGVudCA9ICcnXG59XG5cblRleHQucHJvdG90eXBlLnN0eWxlID0gdXRpbHMuZXh0ZW5kKE9iamVjdC5jcmVhdGUoQXRvbWljLnByb3RvdHlwZS5zdHlsZSksIHtcblxuICBsaW5lczogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhbCA9IHBhcnNlSW50KHZhbClcbiAgICBpZiAodmFsICE9PSB2YWwpIHsgLy8gTmFOXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKHZhbCA8PSAwKSB7XG4gICAgICB0aGlzLnRleHROb2RlLnN0eWxlLnRleHRPdmVyZmxvdyA9ICcnXG4gICAgICB0aGlzLnRleHROb2RlLnN0eWxlLm92ZXJmbG93ID0gJ3Zpc2libGUnXG4gICAgICB0aGlzLnRleHROb2RlLnN0eWxlLndlYmtpdExpbmVDbGFtcCA9ICcnXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGV4dE5vZGUuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJ1xuICAgICAgdGhpcy50ZXh0Tm9kZS5zdHlsZS50ZXh0T3ZlcmZsb3cgPSAnZWxsaXBzaXMnXG4gICAgICB0aGlzLnRleHROb2RlLnN0eWxlLndlYmtpdExpbmVDbGFtcCA9IGxpbmVzXG4gICAgfVxuICB9XG5cbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gVGV4dFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL3RleHQuanNcbiAqKiBtb2R1bGUgaWQgPSAyOFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnJlcXVpcmUoJy4uL3N0eWxlcy9saXN0LnNjc3MnKVxucmVxdWlyZSgnc2Nyb2xsanMnKVxuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxudmFyIExhenlMb2FkID0gcmVxdWlyZSgnLi4vbGF6eUxvYWQnKVxuXG52YXIgREVGQVVMVF9MT0FEX01PUkVfT0ZGU0VUID0gNTAwXG5cbmZ1bmN0aW9uIExpc3QoZGF0YSwgbm9kZVR5cGUpIHtcbiAgLy8gdGhpcy5sb2FkbW9yZU9mZnNldCA9IE51bWJlcihkYXRhLmF0dHIubG9hZG1vcmVvZmZzZXQpXG4gIC8vIHRoaXMuaXNBdmFpbGFibGVUb0ZpcmVsb2FkbW9yZSA9IHRydWVcbiAgQ29tcG9uZW50LmNhbGwodGhpcywgZGF0YSwgbm9kZVR5cGUpXG59XG5cbkxpc3QucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDb21wb25lbnQucHJvdG90eXBlKVxuXG5MaXN0LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAobm9kZVR5cGUpIHtcbiAgdmFyIFNjcm9sbCA9IGxpYi5zY3JvbGxcbiAgdmFyIG5vZGUgPSBDb21wb25lbnQucHJvdG90eXBlLmNyZWF0ZS5jYWxsKHRoaXMsIG5vZGVUeXBlKVxuICBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtY29udGFpbmVyJywgJ2xpc3Qtd3JhcCcpXG4gIHRoaXMubGlzdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICB0aGlzLmxpc3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoXG4gICAgJ3dlZXgtY29udGFpbmVyJ1xuICAgICwgJ2xpc3QtZWxlbWVudCdcbiAgKVxuICBub2RlLmFwcGVuZENoaWxkKHRoaXMubGlzdEVsZW1lbnQpXG4gIHRoaXMuc2Nyb2xsZXIgPSBuZXcgU2Nyb2xsKHtcbiAgICBzY3JvbGxFbGVtZW50OiB0aGlzLmxpc3RFbGVtZW50XG4gICAgLCBkaXJlY3Rpb246ICd5J1xuICB9KVxuICB0aGlzLnNjcm9sbGVyLmluaXQoKVxuICByZXR1cm4gbm9kZVxufVxuXG5MaXN0LnByb3RvdHlwZS5iaW5kRXZlbnRzID0gZnVuY3Rpb24gKGV2dHMpIHtcbiAgQ29tcG9uZW50LnByb3RvdHlwZS5iaW5kRXZlbnRzLmNhbGwodGhpcywgZXZ0cylcbiAgLy8gdG8gZW5hYmxlIGxhenlsb2FkIGZvciBJbWFnZXMuXG4gIHRoaXMuc2Nyb2xsZXIuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsaW5nJywgZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgc28gPSBlLnNjcm9sbE9ialxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudCgnc2Nyb2xsJywge1xuICAgICAgb3JpZ2luYWxUeXBlOiAnc2Nyb2xsaW5nJyxcbiAgICAgIHNjcm9sbFRvcDogc28uZ2V0U2Nyb2xsVG9wKCksXG4gICAgICBzY3JvbGxMZWZ0OiBzby5nZXRTY3JvbGxMZWZ0KClcbiAgICB9LCB7XG4gICAgICBidWJibGVzOiB0cnVlXG4gICAgfSlcbiAgfS5iaW5kKHRoaXMpKVxuXG4gIHRoaXMuc2Nyb2xsZXIuYWRkRXZlbnRMaXN0ZW5lcigncHVsbHVwZW5kJywgZnVuY3Rpb24gKGUpIHtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ2xvYWRtb3JlJylcbiAgfS5iaW5kKHRoaXMpKVxufVxuXG5MaXN0LnByb3RvdHlwZS5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG4gIHZhciBjaGlsZCA9IGNvbXBvbmVudE1hbmFnZXIuY3JlYXRlRWxlbWVudChkYXRhKVxuICB0aGlzLmxpc3RFbGVtZW50LmFwcGVuZENoaWxkKGNoaWxkLm5vZGUpXG5cbiAgLy8gdXBkYXRlIHRoaXMuZGF0YS5jaGlsZHJlblxuICBpZiAoIWNoaWxkcmVuIHx8ICFjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICB0aGlzLmRhdGEuY2hpbGRyZW4gPSBbZGF0YV1cbiAgfSBlbHNlIHtcbiAgICBjaGlsZHJlbi5wdXNoKGRhdGEpXG4gIH1cblxuICByZXR1cm4gY2hpbGRcbn1cblxuTGlzdC5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIHZhciBpID0gMFxuICB2YXIgaXNBcHBlbmQgPSBmYWxzZVxuXG4gIC8vIHVwZGF0ZSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoIHx8ICFiZWZvcmUpIHtcbiAgICBpc0FwcGVuZCA9IHRydWVcbiAgfSBlbHNlIHtcbiAgICBmb3IgKHZhciBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBpZiAoY2hpbGRyZW5baV0ucmVmID09PSBjaGlsZC5kYXRhLnJlZikge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaSA9PT0gbCkge1xuICAgICAgaXNBcHBlbmQgPSB0cnVlXG4gICAgfVxuICB9XG5cbiAgaWYgKGlzQXBwZW5kKSB7XG4gICAgdGhpcy5saXN0RWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICAgIGNoaWxkcmVuLnB1c2goY2hpbGQuZGF0YSlcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmxpc3RFbGVtZW50Lmluc2VydEJlZm9yZShjaGlsZC5ub2RlLCBiZWZvcmUubm9kZSlcbiAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMCwgY2hpbGQuZGF0YSlcbiAgfVxufVxuXG5MaXN0LnByb3RvdHlwZS5yZW1vdmVDaGlsZCA9IGZ1bmN0aW9uIChjaGlsZCkge1xuICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgLy8gcmVtb3ZlIGZyb20gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIHZhciBpID0gMFxuICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG4gIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICBmb3IgKHZhciBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBpZiAoY2hpbGRyZW5baV0ucmVmID09PSBjaGlsZC5kYXRhLnJlZikge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaSA8IGwpIHtcbiAgICAgIGNoaWxkcmVuLnNwbGljZShpLCAxKVxuICAgIH1cbiAgfVxuICAvLyByZW1vdmUgZnJvbSBjb21wb25lbnRNYXAgcmVjdXJzaXZlbHlcbiAgY29tcG9uZW50TWFuYWdlci5yZW1vdmVFbGVtZW50QnlSZWYoY2hpbGQuZGF0YS5yZWYpXG4gIHRoaXMubGlzdEVsZW1lbnQucmVtb3ZlQ2hpbGQoY2hpbGQubm9kZSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBMaXN0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvbGlzdC5qc1xuICoqIG1vZHVsZSBpZCA9IDI5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vbGlzdC5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vbGlzdC5zY3NzXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL25vZGVfbW9kdWxlcy9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9saXN0LnNjc3NcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvc3R5bGVzL2xpc3Quc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDMwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi5saXN0LXdyYXAge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICBvdmVyZmxvdzogaGlkZGVuOyB9XFxuXFxuLmxpc3QtZWxlbWVudCB7XFxuICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xcbiAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9saXN0LnNjc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7RUFDQyxlQUFlO0VBQ2YsaUJBQWlCLEVBQ2pCOztBQUVEO0VBQ0UsNkJBQTZCO0VBQzdCLCtCQUErQjtFQUMvQix1QkFBdUIsRUFDeEJcIixcImZpbGVcIjpcImxpc3Quc2Nzc1wiLFwic291cmNlc0NvbnRlbnRcIjpbXCIubGlzdC13cmFwIHtcXG5cXHRkaXNwbGF5OiBibG9jaztcXG5cXHRvdmVyZmxvdzogaGlkZGVuO1xcbn1cXG5cXG4ubGlzdC1lbGVtZW50IHtcXG4gIC13ZWJraXQtYm94LW9yaWVudDogdmVydGljYWw7XFxuICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9zcmMvc3R5bGVzL2xpc3Quc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDMxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpICYmICh3aW5kb3cgPSB7Y3RybDoge30sIGxpYjoge319KTshd2luZG93LmN0cmwgJiYgKHdpbmRvdy5jdHJsID0ge30pOyF3aW5kb3cubGliICYmICh3aW5kb3cubGliID0ge30pO3JlcXVpcmUoJ2FuaW1hdGlvbmpzJyk7cmVxdWlyZSgnY3ViaWNiZXppZXInKTtyZXF1aXJlKCdnZXN0dXJlanMnKTtyZXF1aXJlKCdtb3Rpb25qcycpOyFmdW5jdGlvbihhLGIsYyl7ZnVuY3Rpb24gZCgpe2Iuc2Nyb2xsLm91dHB1dERlYnVnTG9nJiZjb25zb2xlLmRlYnVnLmFwcGx5KGNvbnNvbGUsYXJndW1lbnRzKX1mdW5jdGlvbiBlKGEpe3ZhciBiPWEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7aWYoIWIpe2I9e30sYi53aWR0aD1hLm9mZnNldFdpZHRoLGIuaGVpZ2h0PWEub2Zmc2V0SGVpZ2h0LGIubGVmdD1hLm9mZnNldExlZnQsYi50b3A9YS5vZmZzZXRUb3A7Zm9yKHZhciBjPWEub2Zmc2V0UGFyZW50O2M7KWIubGVmdCs9Yy5vZmZzZXRMZWZ0LGIudG9wKz1jLm9mZnNldFRvcCxjPWMub2Zmc2V0UGFyZW50O2IucmlnaHQ9Yi5sZWZ0K2Iud2lkdGgsYi5ib3R0b209Yi50b3ArYi5oZWlnaHR9cmV0dXJuIGJ9ZnVuY3Rpb24gZihhKXtyZXR1cm4gMC1hLm9wdGlvbnNbYS5heGlzK1wiUGFkZGluZ1RvcFwiXX1mdW5jdGlvbiBnKGEpe3ZhciBiPWUoYS5lbGVtZW50KSxjPWUoYS52aWV3cG9ydCksZD1mKGEpO2lmKFwieVwiPT09YS5heGlzKXZhciBnPTAtYi5oZWlnaHQrYy5oZWlnaHQ7ZWxzZSB2YXIgZz0wLWIud2lkdGgrYy53aWR0aDtyZXR1cm4gTWF0aC5taW4oZythLm9wdGlvbnNbYS5heGlzK1wiUGFkZGluZ0JvdHRvbVwiXSxkKX1mdW5jdGlvbiBoKGEsYil7cmV0dXJuIGI+YS5taW5TY3JvbGxPZmZzZXQ/Yi1hLm1pblNjcm9sbE9mZnNldDpiPGEubWF4U2Nyb2xsT2Zmc2V0P2ItYS5tYXhTY3JvbGxPZmZzZXQ6dm9pZCAwfWZ1bmN0aW9uIGkoYSxiKXtyZXR1cm4gYj5hLm1pblNjcm9sbE9mZnNldD9iPWEubWluU2Nyb2xsT2Zmc2V0OmI8YS5tYXhTY3JvbGxPZmZzZXQmJihiPWEubWF4U2Nyb2xsT2Zmc2V0KSxifWZ1bmN0aW9uIGooYSxiLGMpe2QoYS5lbGVtZW50LnNjcm9sbElkLGIsYyk7dmFyIGU9cC5jcmVhdGVFdmVudChcIkhUTUxFdmVudHNcIik7aWYoZS5pbml0RXZlbnQoYiwhMSwhMCksZS5zY3JvbGxPYmo9YSxjKWZvcih2YXIgZiBpbiBjKWVbZl09Y1tmXTthLmVsZW1lbnQuZGlzcGF0Y2hFdmVudChlKSxhLnZpZXdwb3J0LmRpc3BhdGNoRXZlbnQoZSl9ZnVuY3Rpb24gayhhKXt2YXIgYixjPXt4OjAseTowfSxkPWdldENvbXB1dGVkU3R5bGUoYS5lbGVtZW50KVt5K1wiVHJhbnNmb3JtXCJdO3JldHVyblwibm9uZVwiIT09ZCYmKGI9ZC5tYXRjaCgvXm1hdHJpeDNkXFwoKD86Wy1cXGQuXSssXFxzKil7MTJ9KFstXFxkLl0rKSxcXHMqKFstXFxkLl0rKSg/OixcXHMqWy1cXGQuXSspezJ9XFwpLyl8fGQubWF0Y2goL15tYXRyaXhcXCgoPzpbLVxcZC5dKyxcXHMqKXs0fShbLVxcZC5dKyksXFxzKihbLVxcZC5dKylcXCkkLykpJiYoYy54PXBhcnNlRmxvYXQoYlsxXSl8fDAsYy55PXBhcnNlRmxvYXQoYlsyXSl8fDApLGN9ZnVuY3Rpb24gbChhLGIpe3JldHVybiBhPXBhcnNlRmxvYXQoYSksYj1wYXJzZUZsb2F0KGIpLDAhPWEmJihhKz1cInB4XCIpLDAhPWImJihiKz1cInB4XCIpLEE/XCJ0cmFuc2xhdGUzZChcIithK1wiLCBcIitiK1wiLCAwKVwiOlwidHJhbnNsYXRlKFwiK2ErXCIsIFwiK2IrXCIpXCJ9ZnVuY3Rpb24gbShhLGIsYyl7XCJcIj09PWImJlwiXCI9PT1jP2EuZWxlbWVudC5zdHlsZVt5K1wiVHJhbnNpdGlvblwiXT1cIlwiOmEuZWxlbWVudC5zdHlsZVt5K1wiVHJhbnNpdGlvblwiXT14K1widHJhbnNmb3JtIFwiK2IrXCIgXCIrYytcIiAwc1wifWZ1bmN0aW9uIG4oYSxiKXt2YXIgYz0wLGQ9MDtcIm9iamVjdFwiPT10eXBlb2YgYj8oYz1iLngsZD1iLnkpOlwieVwiPT09YS5heGlzP2Q9YjpjPWIsYS5lbGVtZW50LnN0eWxlW3krXCJUcmFuc2Zvcm1cIl09bChjLGQpfWZ1bmN0aW9uIG8oYSxjKXtmdW5jdGlvbiBsKGEpe3JldHVybiBGfHxMPyhhLnByZXZlbnREZWZhdWx0KCksYS5zdG9wUHJvcGFnYXRpb24oKSwhMSk6ITB9ZnVuY3Rpb24gbyhhKXtGfHxMfHxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dmFyIGI9ZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJIVE1MRXZlbnRzXCIpO2IuaW5pdEV2ZW50KFwibmljZWNsaWNrXCIsITAsITApLGEudGFyZ2V0LmRpc3BhdGNoRXZlbnQoYil9LDMwMCl9ZnVuY3Rpb24gcChhLGMpe0k9bnVsbCxjbGVhclRpbWVvdXQoSiksSj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7SSYmKEk9bnVsbCxiLmFuaW1hdGlvbi5yZXF1ZXN0RnJhbWUoYSkpfSxjfHw0MDApLEk9YX1mdW5jdGlvbiBxKGEpe2lmKCFFLmVuYWJsZWQpcmV0dXJuITE7aWYoXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGEuaXNWZXJ0aWNhbCl7aWYoIShcInlcIj09PUUuYXhpcyYmYS5pc1ZlcnRpY2FsfHxcInhcIj09PUUuYXhpcyYmIWEuaXNWZXJ0aWNhbCkpcmV0dXJuITE7YS5zdG9wUHJvcGFnYXRpb24oKX1yZXR1cm4hMH1mdW5jdGlvbiB0KGEpe2lmKHEoYSkpaWYoTCYmRCgpLGMudXNlRnJhbWVBbmltYXRpb24pSCYmSC5zdG9wKCksSD1udWxsO2Vsc2V7dmFyIGI9ayhFKTtuKEUsYiksbShFLFwiXCIsXCJcIiksST1udWxsLGNsZWFyVGltZW91dChKKX19ZnVuY3Rpb24gdyhhKXtpZihxKGEpKXt2YXIgZD1rKEUpW0UuYXhpc10sZT1oKEUsZCk7aWYoZSl7dmFyIGY9aShFLGQpO2lmKGMudXNlRnJhbWVBbmltYXRpb24pe3ZhciBnPWYtZDtIPW5ldyBiLmFuaW1hdGlvbig0MDAsYi5jdWJpY2Jlemllci5lYXNlLDAsZnVuY3Rpb24oYSxiKXt2YXIgYz0oZCtnKmIpLnRvRml4ZWQoMik7bihFLGMpLGooRSxcInNjcm9sbGluZ1wiKX0pLEgub25lbmQoRCksSC5wbGF5KCl9ZWxzZXt2YXIgbD1mLnRvRml4ZWQoMCk7bShFLFwiMC40c1wiLFwiZWFzZVwiKSxuKEUsbCkscChELDQwMCksYi5hbmltYXRpb24ucmVxdWVzdEZyYW1lKGZ1bmN0aW9uKCl7TCYmRS5lbmFibGVkJiYoaihFLFwic2Nyb2xsaW5nXCIpLGIuYW5pbWF0aW9uLnJlcXVlc3RGcmFtZShhcmd1bWVudHMuY2FsbGVlKSl9KX1lPjA/aihFLFwieVwiPT09RS5heGlzP1wicHVsbGRvd25lbmRcIjpcInB1bGxyaWdodGVuZFwiKTowPmUmJmooRSxcInlcIj09PUUuYXhpcz9cInB1bGx1cGVuZFwiOlwicHVsbGxlZnRlbmRcIil9ZWxzZSBMJiZEKCl9fWZ1bmN0aW9uIHgoYSl7cShhKSYmKEUudHJhbnNmb3JtT2Zmc2V0PWsoRSksRS5taW5TY3JvbGxPZmZzZXQ9ZihFKSxFLm1heFNjcm9sbE9mZnNldD1nKEUpLEs9Mi41LE49ITAsTD0hMCxNPSExLGooRSxcInNjcm9sbHN0YXJ0XCIpLE89YVtcImRpc3BsYWNlbWVudFwiK0UuYXhpcy50b1VwcGVyQ2FzZSgpXSl9ZnVuY3Rpb24geihhKXtpZihxKGEpKXt2YXIgYj1hW1wiZGlzcGxhY2VtZW50XCIrRS5heGlzLnRvVXBwZXJDYXNlKCldO2lmKE1hdGguYWJzKGItTyk8NSlyZXR1cm4gdm9pZCBhLnN0b3BQcm9wYWdhdGlvbigpO089Yjt2YXIgYz1FLnRyYW5zZm9ybU9mZnNldFtFLmF4aXNdK2I7Yz5FLm1pblNjcm9sbE9mZnNldD8oYz1FLm1pblNjcm9sbE9mZnNldCsoYy1FLm1pblNjcm9sbE9mZnNldCkvSyxLKj0xLjAwMyk6YzxFLm1heFNjcm9sbE9mZnNldCYmKGM9RS5tYXhTY3JvbGxPZmZzZXQtKEUubWF4U2Nyb2xsT2Zmc2V0LWMpL0ssSyo9MS4wMDMpLEs+NCYmKEs9NCk7dmFyIGQ9aChFLGMpO2QmJihqKEUsZD4wP1wieVwiPT09RS5heGlzP1wicHVsbGRvd25cIjpcInB1bGxyaWdodFwiOlwieVwiPT09RS5heGlzP1wicHVsbHVwXCI6XCJwdWxsbGVmdFwiLHtib3VuZGFyeU9mZnNldDpNYXRoLmFicyhkKX0pLEUub3B0aW9ucy5ub0JvdW5jZSYmKGM9aShFLGMpKSksbihFLGMudG9GaXhlZCgyKSksaihFLFwic2Nyb2xsaW5nXCIpfX1mdW5jdGlvbiBBKGEpe3EoYSkmJmEuaXNmbGljayYmQyhhKX1mdW5jdGlvbiBDKGEpe049ITA7dmFyIGUsZixnLGksbCxvLHEscixzLHQsdix3LHgseSx6LEEsQjtpPWsoRSlbRS5heGlzXTt2YXIgQz1oKEUsaSk7aWYoIUMpe2U9YVtcInZlbG9jaXR5XCIrRS5heGlzLnRvVXBwZXJDYXNlKCldO3ZhciBGPTIsRz0uMDAxNTtjLmluZXJ0aWEmJnVbYy5pbmVydGlhXSYmKEY9dVtjLmluZXJ0aWFdWzBdLEc9dVtjLmluZXJ0aWFdWzFdKSxlPkYmJihlPUYpLC1GPmUmJihlPS1GKSxmPUcqKGUvTWF0aC5hYnMoZSkpLG89bmV3IGIubW90aW9uKHt2OmUsYTotZn0pLGc9by50LGw9aStvLnM7dmFyIEk9aChFLGwpO2lmKEkpe2QoXCLmg6/mgKforqHnrpfotoXlh7rkuobovrnnvJhcIixJKSxxPWUscj1mLEk+MD8odD1FLm1pblNjcm9sbE9mZnNldCx3PTEpOih0PUUubWF4U2Nyb2xsT2Zmc2V0LHc9LTEpLHY9bmV3IGIubW90aW9uKHt2OncqcSxhOi13KnIsczpNYXRoLmFicyh0LWkpfSkscz12LnQ7dmFyIEo9di5nZW5lcmF0ZUN1YmljQmV6aWVyKCk7eD1xLXIqcyx5PS4wMyooeC9NYXRoLmFicyh4KSksQj1uZXcgYi5tb3Rpb24oe3Y6eCxhOi15fSksej1CLnQsQT10K0IucztCLmdlbmVyYXRlQ3ViaWNCZXppZXIoKTtpZihjLm5vQm91bmNlKWlmKGQoXCLmsqHmnInlm57lvLnmlYjmnpxcIiksaSE9PXQpaWYoYy51c2VGcmFtZUFuaW1hdGlvbil7dmFyIEs9dC1pLE89Yi5jdWJpY2JlemllcihKWzBdWzBdLEpbMF1bMV0sSlsxXVswXSxKWzFdWzFdKTtIPW5ldyBiLmFuaW1hdGlvbihzLnRvRml4ZWQoMCksTywwLGZ1bmN0aW9uKGEsYil7dmFyIGM9aStLKmI7ayhFLGMudG9GaXhlZCgyKSksaihFLFwic2Nyb2xsaW5nXCIse2FmdGVyRmxpY2s6ITB9KX0pLEgub25lbmQoRCksSC5wbGF5KCl9ZWxzZXt2YXIgUD10LnRvRml4ZWQoMCk7bShFLChzLzFlMykudG9GaXhlZCgyKStcInNcIixcImN1YmljLWJlemllcihcIitKK1wiKVwiKSxuKEUsUCkscChELDFlMyoocy8xZTMpLnRvRml4ZWQoMikpfWVsc2UgRCgpO2Vsc2UgaWYoaSE9PUEpaWYoZChcIuaDr+aAp+a7muWKqFwiLFwicz1cIitBLnRvRml4ZWQoMCksXCJ0PVwiKygocyt6KS8xZTMpLnRvRml4ZWQoMikpLGMudXNlRnJhbWVBbmltYXRpb24pe3ZhciBLPUEtaSxPPWIuY3ViaWNiZXppZXIuZWFzZU91dDtIPW5ldyBiLmFuaW1hdGlvbigocyt6KS50b0ZpeGVkKDApLE8sMCxmdW5jdGlvbihhLGIpe3ZhciBjPWkrSypiO24oRSxjLnRvRml4ZWQoMikpLGooRSxcInNjcm9sbGluZ1wiLHthZnRlckZsaWNrOiEwfSl9KSxILm9uZW5kKGZ1bmN0aW9uKCl7aWYoRS5lbmFibGVkKXt2YXIgYT10LUEsYz1iLmN1YmljYmV6aWVyLmVhc2U7SD1uZXcgYi5hbmltYXRpb24oNDAwLGMsMCxmdW5jdGlvbihiLGMpe3ZhciBkPUErYSpjO24oRSxkLnRvRml4ZWQoMikpLGooRSxcInNjcm9sbGluZ1wiLHthZnRlckZsaWNrOiEwfSl9KSxILm9uZW5kKEQpLEgucGxheSgpfX0pLEgucGxheSgpfWVsc2V7dmFyIFA9QS50b0ZpeGVkKDApO20oRSwoKHMreikvMWUzKS50b0ZpeGVkKDIpK1wic1wiLFwiZWFzZS1vdXRcIiksbihFLFApLHAoZnVuY3Rpb24oYSl7aWYoRS5lbmFibGVkKWlmKGQoXCLmg6/mgKflm57lvLlcIixcInM9XCIrdC50b0ZpeGVkKDApLFwidD00MDBcIiksQSE9PXQpe3ZhciBiPXQudG9GaXhlZCgwKTttKEUsXCIwLjRzXCIsXCJlYXNlXCIpLG4oRSxiKSxwKEQsNDAwKX1lbHNlIEQoKX0sMWUzKigocyt6KS8xZTMpLnRvRml4ZWQoMikpfWVsc2UgRCgpfWVsc2V7ZChcIuaDr+aAp+iuoeeul+ayoeaciei2heWHuui+uee8mFwiKTt2YXIgUT1vLmdlbmVyYXRlQ3ViaWNCZXppZXIoKTtpZihjLnVzZUZyYW1lQW5pbWF0aW9uKXt2YXIgSz1sLWksTz1iLmN1YmljYmV6aWVyKFFbMF1bMF0sUVswXVsxXSxRWzFdWzBdLFFbMV1bMV0pO0g9bmV3IGIuYW5pbWF0aW9uKGcudG9GaXhlZCgwKSxPLDAsZnVuY3Rpb24oYSxiKXt2YXIgYz0oaStLKmIpLnRvRml4ZWQoMik7bihFLGMpLGooRSxcInNjcm9sbGluZ1wiLHthZnRlckZsaWNrOiEwfSl9KSxILm9uZW5kKEQpLEgucGxheSgpfWVsc2V7dmFyIFA9bC50b0ZpeGVkKDApO20oRSwoZy8xZTMpLnRvRml4ZWQoMikrXCJzXCIsXCJjdWJpYy1iZXppZXIoXCIrUStcIilcIiksbihFLFApLHAoRCwxZTMqKGcvMWUzKS50b0ZpeGVkKDIpKX19TT0hMCxjLnVzZUZyYW1lQW5pbWF0aW9ufHxiLmFuaW1hdGlvbi5yZXF1ZXN0RnJhbWUoZnVuY3Rpb24oKXtMJiZNJiZFLmVuYWJsZWQmJihqKEUsXCJzY3JvbGxpbmdcIix7YWZ0ZXJGbGljazohMH0pLGIuYW5pbWF0aW9uLnJlcXVlc3RGcmFtZShhcmd1bWVudHMuY2FsbGVlKSl9KX19ZnVuY3Rpb24gRCgpe0UuZW5hYmxlZCYmKE49ITEsc2V0VGltZW91dChmdW5jdGlvbigpeyFOJiZMJiYoTD0hMSxNPSExLGMudXNlRnJhbWVBbmltYXRpb24/KEgmJkguc3RvcCgpLEg9bnVsbCk6bShFLFwiXCIsXCJcIiksaihFLFwic2Nyb2xsZW5kXCIpKX0sNTApKX12YXIgRT10aGlzO2lmKGM9Y3x8e30sYy5ub0JvdW5jZT0hIWMubm9Cb3VuY2UsYy5wYWRkaW5nPWMucGFkZGluZ3x8e30sbnVsbD09Yy5pc1ByZXZlbnQ/Yy5pc1ByZXZlbnQ9ITA6Yy5pc1ByZXZlbnQ9ISFjLmlzUHJldmVudCxudWxsPT1jLmlzRml4U2Nyb2xsZW5kQ2xpY2s/Yy5pc0ZpeFNjcm9sbGVuZENsaWNrPSEwOmMuaXNGaXhTY3JvbGxlbmRDbGljaz0hIWMuaXNGaXhTY3JvbGxlbmRDbGljayxjLnBhZGRpbmc/KGMueVBhZGRpbmdUb3A9LWMucGFkZGluZy50b3B8fDAsYy55UGFkZGluZ0JvdHRvbT0tYy5wYWRkaW5nLmJvdHRvbXx8MCxjLnhQYWRkaW5nVG9wPS1jLnBhZGRpbmcubGVmdHx8MCxjLnhQYWRkaW5nQm90dG9tPS1jLnBhZGRpbmcucmlnaHR8fDApOihjLnlQYWRkaW5nVG9wPTAsYy55UGFkZGluZ0JvdHRvbT0wLGMueFBhZGRpbmdUb3A9MCxjLnhQYWRkaW5nQm90dG9tPTApLGMuZGlyZWN0aW9uPWMuZGlyZWN0aW9ufHxcInlcIixjLmluZXJ0aWE9Yy5pbmVydGlhfHxcIm5vcm1hbFwiLHRoaXMub3B0aW9ucz1jLEUuYXhpcz1jLmRpcmVjdGlvbix0aGlzLmVsZW1lbnQ9YSx0aGlzLnZpZXdwb3J0PWEucGFyZW50Tm9kZSx0aGlzLnBsdWdpbnM9e30sdGhpcy5lbGVtZW50LnNjcm9sbElkPXNldFRpbWVvdXQoZnVuY3Rpb24oKXtyW0UuZWxlbWVudC5zY3JvbGxJZCtcIlwiXT1FfSwxKSx0aGlzLnZpZXdwb3J0LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsdCwhMSksdGhpcy52aWV3cG9ydC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIix3LCExKSx0aGlzLnZpZXdwb3J0LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGNhbmNlbFwiLHcsITEpLHRoaXMudmlld3BvcnQuYWRkRXZlbnRMaXN0ZW5lcihcInBhbnN0YXJ0XCIseCwhMSksdGhpcy52aWV3cG9ydC5hZGRFdmVudExpc3RlbmVyKFwicGFubW92ZVwiLHosITEpLHRoaXMudmlld3BvcnQuYWRkRXZlbnRMaXN0ZW5lcihcInBhbmVuZFwiLEEsITEpLGMuaXNQcmV2ZW50JiYodGhpcy52aWV3cG9ydC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLGZ1bmN0aW9uKGEpe0I9ITB9LCExKSxFLnZpZXdwb3J0LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLGZ1bmN0aW9uKGEpe0I9ITF9LCExKSksYy5pc0ZpeFNjcm9sbGVuZENsaWNrKXt2YXIgRixHO3RoaXMudmlld3BvcnQuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbGluZ1wiLGZ1bmN0aW9uKCl7Rj0hMCxHJiZjbGVhclRpbWVvdXQoRyksRz1zZXRUaW1lb3V0KGZ1bmN0aW9uKGEpe0Y9ITF9LDQwMCl9LCExKSx0aGlzLnZpZXdwb3J0LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLGwsITEpLHRoaXMudmlld3BvcnQuYWRkRXZlbnRMaXN0ZW5lcihcInRhcFwiLG8sITEpfWlmKGMudXNlRnJhbWVBbmltYXRpb24pe3ZhciBIO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLFwiYW5pbWF0aW9uXCIse2dldDpmdW5jdGlvbigpe3JldHVybiBIfX0pfWVsc2V7dmFyIEksSj0wO2EuYWRkRXZlbnRMaXN0ZW5lcih2P1widHJhbnNpdGlvbmVuZFwiOnkrXCJUcmFuc2l0aW9uRW5kXCIsZnVuY3Rpb24oYSl7aWYoSSl7dmFyIGM9STtJPW51bGwsY2xlYXJUaW1lb3V0KEopLGIuYW5pbWF0aW9uLnJlcXVlc3RGcmFtZShmdW5jdGlvbigpe2MoYSl9KX19LCExKX12YXIgSyxMLE0sTjtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyxcImlzU2Nyb2xsaW5nXCIse2dldDpmdW5jdGlvbigpe3JldHVybiEhTH19KTt2YXIgTyxQPXtpbml0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZW5hYmxlKCksdGhpcy5yZWZyZXNoKCksdGhpcy5zY3JvbGxUbygwKSx0aGlzfSxlbmFibGU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lbmFibGVkPSEwLHRoaXN9LGRpc2FibGU6ZnVuY3Rpb24oKXt2YXIgYT10aGlzLmVsZW1lbnQ7cmV0dXJuIHRoaXMuZW5hYmxlZD0hMSx0aGlzLm9wdGlvbnMudXNlRnJhbWVBbmltYXRpb24/SCYmSC5zdG9wKCk6Yi5hbmltYXRpb24ucmVxdWVzdEZyYW1lKGZ1bmN0aW9uKCl7YS5zdHlsZVt5K1wiVHJhbnNmb3JtXCJdPWdldENvbXB1dGVkU3R5bGUoYSlbeStcIlRyYW5zZm9ybVwiXX0pLHRoaXN9LGdldFNjcm9sbFdpZHRoOmZ1bmN0aW9uKCl7cmV0dXJuIGUodGhpcy5lbGVtZW50KS53aWR0aH0sZ2V0U2Nyb2xsSGVpZ2h0OmZ1bmN0aW9uKCl7cmV0dXJuIGUodGhpcy5lbGVtZW50KS5oZWlnaHR9LGdldFNjcm9sbExlZnQ6ZnVuY3Rpb24oKXtyZXR1cm4tayh0aGlzKS54LXRoaXMub3B0aW9ucy54UGFkZGluZ1RvcH0sZ2V0U2Nyb2xsVG9wOmZ1bmN0aW9uKCl7cmV0dXJuLWsodGhpcykueS10aGlzLm9wdGlvbnMueVBhZGRpbmdUb3B9LGdldE1heFNjcm9sbExlZnQ6ZnVuY3Rpb24oKXtyZXR1cm4tRS5tYXhTY3JvbGxPZmZzZXQtdGhpcy5vcHRpb25zLnhQYWRkaW5nVG9wfSxnZXRNYXhTY3JvbGxUb3A6ZnVuY3Rpb24oKXtyZXR1cm4tRS5tYXhTY3JvbGxPZmZzZXQtdGhpcy5vcHRpb25zLnlQYWRkaW5nVG9wfSxnZXRCb3VuZGFyeU9mZnNldDpmdW5jdGlvbigpe3JldHVybiBNYXRoLmFicyhoKHRoaXMsayh0aGlzKVt0aGlzLmF4aXNdKXx8MCl9LHJlZnJlc2g6ZnVuY3Rpb24oKXt2YXIgYT10aGlzLmVsZW1lbnQsYj1cInlcIj09PXRoaXMuYXhpcyxjPWI/XCJoZWlnaHRcIjpcIndpZHRoXCI7aWYobnVsbCE9dGhpcy5vcHRpb25zW2NdKWEuc3R5bGVbY109dGhpcy5vcHRpb25zW2NdK1wicHhcIjtlbHNlIGlmKHRoaXMub3B0aW9ucy51c2VFbGVtZW50UmVjdClhLnN0eWxlW2NdPVwiYXV0b1wiLGEuc3R5bGVbY109ZShhKVtjXStcInB4XCI7ZWxzZSBpZihhLmNoaWxkRWxlbWVudENvdW50PjApe3ZhciBkLGgsaT1hLmZpcnN0RWxlbWVudENoaWxkLGw9YS5sYXN0RWxlbWVudENoaWxkO2lmKGRvY3VtZW50LmNyZWF0ZVJhbmdlJiYhdGhpcy5vcHRpb25zLmlnbm9yZU92ZXJmbG93JiYoZD1kb2N1bWVudC5jcmVhdGVSYW5nZSgpLGQuc2VsZWN0Tm9kZUNvbnRlbnRzKGEpLGg9ZShkKSksaClhLnN0eWxlW2NdPWhbY10rXCJweFwiO2Vsc2V7Zm9yKDtpJiYwPT09ZShpKVtjXSYmaS5uZXh0RWxlbWVudFNpYmxpbmc7KWk9aS5uZXh0RWxlbWVudFNpYmxpbmc7Zm9yKDtsJiZsIT09aSYmMD09PWUobClbY10mJmwucHJldmlvdXNFbGVtZW50U2libGluZzspbD1sLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7YS5zdHlsZVtjXT1lKGwpW2I/XCJib3R0b21cIjpcInJpZ2h0XCJdLWUoaSlbYj9cInRvcFwiOlwibGVmdFwiXStcInB4XCJ9fXJldHVybiB0aGlzLnRyYW5zZm9ybU9mZnNldD1rKHRoaXMpLHRoaXMubWluU2Nyb2xsT2Zmc2V0PWYodGhpcyksdGhpcy5tYXhTY3JvbGxPZmZzZXQ9Zyh0aGlzKSx0aGlzLnNjcm9sbFRvKC10aGlzLnRyYW5zZm9ybU9mZnNldFt0aGlzLmF4aXNdLXRoaXMub3B0aW9uc1t0aGlzLmF4aXMrXCJQYWRkaW5nVG9wXCJdKSxqKHRoaXMsXCJjb250ZW50cmVmcmVzaFwiKSx0aGlzfSxvZmZzZXQ6ZnVuY3Rpb24oYSl7dmFyIGI9ZSh0aGlzLmVsZW1lbnQpLGM9ZShhKTtpZihcInlcIj09PXRoaXMuYXhpcyl7dmFyIGQ9e3RvcDpjLnRvcC1iLnRvcC10aGlzLm9wdGlvbnMueVBhZGRpbmdUb3AsbGVmdDpjLmxlZnQtYi5sZWZ0LHJpZ2h0OmIucmlnaHQtYy5yaWdodCx3aWR0aDpjLndpZHRoLGhlaWdodDpjLmhlaWdodH07ZC5ib3R0b209ZC50b3ArZC5oZWlnaHR9ZWxzZXt2YXIgZD17dG9wOmMudG9wLWIudG9wLGJvdHRvbTpiLmJvdHRvbS1jLmJvdHRvbSxsZWZ0OmMubGVmdC1iLmxlZnQtdGhpcy5vcHRpb25zLnhQYWRkaW5nVG9wLHdpZHRoOmMud2lkdGgsaGVpZ2h0OmMuaGVpZ2h0fTtkLnJpZ2h0PWQubGVmdCtkLndpZHRofXJldHVybiBkfSxnZXRSZWN0OmZ1bmN0aW9uKGEpe3ZhciBiPWUodGhpcy52aWV3cG9ydCksYz1lKGEpO2lmKFwieVwiPT09dGhpcy5heGlzKXt2YXIgZD17dG9wOmMudG9wLWIudG9wLGxlZnQ6Yy5sZWZ0LWIubGVmdCxyaWdodDpiLnJpZ2h0LWMucmlnaHQsd2lkdGg6Yy53aWR0aCxoZWlnaHQ6Yy5oZWlnaHR9O2QuYm90dG9tPWQudG9wK2QuaGVpZ2h0fWVsc2V7dmFyIGQ9e3RvcDpjLnRvcC1iLnRvcCxib3R0b206Yi5ib3R0b20tYy5ib3R0b20sbGVmdDpjLmxlZnQtYi5sZWZ0LHdpZHRoOmMud2lkdGgsaGVpZ2h0OmMuaGVpZ2h0fTtkLnJpZ2h0PWQubGVmdCtkLndpZHRofXJldHVybiBkfSxpc0luVmlldzpmdW5jdGlvbihhKXt2YXIgYj10aGlzLmdldFJlY3QodGhpcy52aWV3cG9ydCksYz10aGlzLmdldFJlY3QoYSk7cmV0dXJuXCJ5XCI9PT10aGlzLmF4aXM/Yi50b3A8Yy5ib3R0b20mJmIuYm90dG9tPmMudG9wOmIubGVmdDxjLnJpZ2h0JiZiLnJpZ2h0PmMubGVmdH0sc2Nyb2xsVG86ZnVuY3Rpb24oYSxjKXt2YXIgZD10aGlzO3RoaXMuZWxlbWVudDtpZihhPS1hLXRoaXMub3B0aW9uc1t0aGlzLmF4aXMrXCJQYWRkaW5nVG9wXCJdLGE9aSh0aGlzLGEpLEw9ITAsYz09PSEwKWlmKHRoaXMub3B0aW9ucy51c2VGcmFtZUFuaW1hdGlvbil7dmFyIGU9ayhkKVt0aGlzLmF4aXNdLGY9YS1lO0g9bmV3IGIuYW5pbWF0aW9uKDQwMCxiLmN1YmljYmV6aWVyLmVhc2UsMCxmdW5jdGlvbihhLGIpe3ZhciBjPShlK2YqYikudG9GaXhlZCgyKTtuKGQsYyksaihkLFwic2Nyb2xsaW5nXCIpfSksSC5vbmVuZChEKSxILnBsYXkoKX1lbHNlIG0oZCxcIjAuNHNcIixcImVhc2VcIiksbihkLGEpLHAoRCw0MDApLGIuYW5pbWF0aW9uLnJlcXVlc3RGcmFtZShmdW5jdGlvbigpe0wmJmQuZW5hYmxlZCYmKGooZCxcInNjcm9sbGluZ1wiKSxiLmFuaW1hdGlvbi5yZXF1ZXN0RnJhbWUoYXJndW1lbnRzLmNhbGxlZSkpfSk7ZWxzZSB0aGlzLm9wdGlvbnMudXNlRnJhbWVBbmltYXRpb258fG0oZCxcIlwiLFwiXCIpLG4oZCxhKSxEKCk7cmV0dXJuIHRoaXN9LHNjcm9sbFRvRWxlbWVudDpmdW5jdGlvbihhLGIpe3ZhciBjPXRoaXMub2Zmc2V0KGEpO3JldHVybiBjPWNbXCJ5XCI9PT10aGlzLmF4aXM/XCJ0b3BcIjpcImxlZnRcIl0sdGhpcy5zY3JvbGxUbyhjLGIpfSxnZXRWaWV3V2lkdGg6ZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzLnZpZXdwb3J0KS53aWR0aH0sZ2V0Vmlld0hlaWdodDpmdW5jdGlvbigpe3JldHVybiBlKHRoaXMudmlld3BvcnQpLmhlaWdodH0sYWRkUHVsbGRvd25IYW5kbGVyOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7cmV0dXJuIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicHVsbGRvd25lbmRcIixmdW5jdGlvbihjKXtiLmRpc2FibGUoKSxhLmNhbGwoYixjLGZ1bmN0aW9uKCl7Yi5zY3JvbGxUbygwLCEwKSxiLnJlZnJlc2goKSxiLmVuYWJsZSgpfSl9LCExKSx0aGlzfSxhZGRQdWxsdXBIYW5kbGVyOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7cmV0dXJuIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicHVsbHVwZW5kXCIsZnVuY3Rpb24oYyl7Yi5kaXNhYmxlKCksYS5jYWxsKGIsYyxmdW5jdGlvbigpe2Iuc2Nyb2xsVG8oYi5nZXRTY3JvbGxIZWlnaHQoKSwhMCksYi5yZWZyZXNoKCksYi5lbmFibGUoKX0pfSwhMSksdGhpc30sYWRkU2Nyb2xsc3RhcnRIYW5kbGVyOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7cmV0dXJuIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsc3RhcnRcIixmdW5jdGlvbihjKXthLmNhbGwoYixjKX0sITEpLHRoaXN9LGFkZFNjcm9sbGluZ0hhbmRsZXI6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcztyZXR1cm4gdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxpbmdcIixmdW5jdGlvbihjKXthLmNhbGwoYixjKX0sITEpLHRoaXN9LGFkZFNjcm9sbGVuZEhhbmRsZXI6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcztyZXR1cm4gdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxlbmRcIixmdW5jdGlvbihjKXthLmNhbGwoYixjKX0sITEpLHRoaXN9LGFkZENvbnRlbnRyZW5mcmVzaEhhbmRsZXI6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpczt0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNvbnRlbnRyZWZyZXNoXCIsZnVuY3Rpb24oYyl7YS5jYWxsKGIsYyl9LCExKX0sYWRkRXZlbnRMaXN0ZW5lcjpmdW5jdGlvbihhLGIsYyl7dmFyIGQ9dGhpczt0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihhLGZ1bmN0aW9uKGEpe2IuY2FsbChkLGEpfSwhIWMpfSxyZW1vdmVFdmVudExpc3RlbmVyOmZ1bmN0aW9uKGEsYil7dmFyIGM9dGhpczt0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihhLGZ1bmN0aW9uKGEpe2IuY2FsbChjLGEpfSl9LGVuYWJsZVBsdWdpbjpmdW5jdGlvbihhLGIpe3ZhciBjPXNbYV07cmV0dXJuIGMmJiF0aGlzLnBsdWdpbnNbYV0mJih0aGlzLnBsdWdpbnNbYV09ITAsYj1ifHx7fSxjLmNhbGwodGhpcyxhLGIpKSx0aGlzfX07Zm9yKHZhciBRIGluIFApdGhpc1tRXT1QW1FdO2RlbGV0ZSBQfXZhciBwPWEuZG9jdW1lbnQscT1hLm5hdmlnYXRvci51c2VyQWdlbnQscj17fSxzPXt9LHQ9YS5kcHJ8fChhLm5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZXxpUGFkfGlQb2QvKT9kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgvYS5zY3JlZW4uYXZhaWxXaWR0aDoxKSx1PXtub3JtYWw6WzIqdCwuMDAxNSp0XSxzbG93OlsxLjUqdCwuMDAzKnRdLHZlcnlzbG93OlsxLjUqdCwuMDA1KnRdfSx2PSEhcS5tYXRjaCgvRmlyZWZveC9pKSx3PSEhcS5tYXRjaCgvSUVNb2JpbGUvaSkseD12P1wiLW1vei1cIjp3P1wiLW1zLVwiOlwiLXdlYmtpdC1cIix5PXY/XCJNb3pcIjp3P1wibXNcIjpcIndlYmtpdFwiLHo9dz9cIk1TQ1NTTWF0cml4XCI6XCJXZWJLaXRDU1NNYXRyaXhcIixBPSEhdnx8eiBpbiBhJiZcIm0xMVwiaW4gbmV3IGFbel0sQj0hMTtwLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIixmdW5jdGlvbihhKXtyZXR1cm4gQj8oYS5wcmV2ZW50RGVmYXVsdCgpLCExKTohMH0sITEpLGIuc2Nyb2xsPWZ1bmN0aW9uKGEsYyl7aWYoMT09PWFyZ3VtZW50cy5sZW5ndGgmJiEoYXJndW1lbnRzWzBdaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpaWYoYz1hcmd1bWVudHNbMF0sYy5zY3JvbGxFbGVtZW50KWE9Yy5zY3JvbGxFbGVtZW50O2Vsc2V7aWYoIWMuc2Nyb2xsV3JhcCl0aHJvdyBuZXcgRXJyb3IoXCJubyBzY3JvbGwgZWxlbWVudFwiKTthPWMuc2Nyb2xsV3JhcC5maXJzdEVsZW1lbnRDaGlsZH1pZighYS5wYXJlbnROb2RlKXRocm93IG5ldyBFcnJvcihcIndyb25nIGRvbSB0cmVlXCIpO2lmKGMmJmMuZGlyZWN0aW9uJiZbXCJ4XCIsXCJ5XCJdLmluZGV4T2YoYy5kaXJlY3Rpb24pPDApdGhyb3cgbmV3IEVycm9yKFwid3JvbmcgZGlyZWN0aW9uXCIpO3ZhciBkO3JldHVybiBkPWMuZG93bmdyYWRlPT09ITAmJmIuc2Nyb2xsLmRvd25ncmFkZT9iLnNjcm9sbC5kb3duZ3JhZGUoYSxjKTphLnNjcm9sbElkP3JbYS5zY3JvbGxJZF06bmV3IG8oYSxjKX0sYi5zY3JvbGwucGx1Z2luPWZ1bmN0aW9uKGEsYil7cmV0dXJuIGI/KGE9YS5zcGxpdChcIixcIiksdm9pZCBhLmZvckVhY2goZnVuY3Rpb24oYSl7c1thXT1ifSkpOnNbYV19fSh3aW5kb3csd2luZG93LmxpYnx8KHdpbmRvdy5saWI9e30pKTs7bW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cubGliWydzY3JvbGwnXTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9zY3JvbGxqcy9idWlsZC9zY3JvbGwuY29tbW9uLmpzXG4gKiogbW9kdWxlIGlkID0gMzJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIih0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgJiYgKHdpbmRvdyA9IHtjdHJsOiB7fSwgbGliOiB7fX0pOyF3aW5kb3cuY3RybCAmJiAod2luZG93LmN0cmwgPSB7fSk7IXdpbmRvdy5saWIgJiYgKHdpbmRvdy5saWIgPSB7fSk7IWZ1bmN0aW9uKGEsYil7ZnVuY3Rpb24gYyhhKXtyZXR1cm4gc2V0VGltZW91dChhLGwpfWZ1bmN0aW9uIGQoYSl7Y2xlYXJUaW1lb3V0KGEpfWZ1bmN0aW9uIGUoKXt2YXIgYT17fSxiPW5ldyBtKGZ1bmN0aW9uKGIsYyl7YS5yZXNvbHZlPWIsYS5yZWplY3Q9Y30pO3JldHVybiBhLnByb21pc2U9YixhfWZ1bmN0aW9uIGYoYSxiKXtyZXR1cm5bXCJ0aGVuXCIsXCJjYXRjaFwiXS5mb3JFYWNoKGZ1bmN0aW9uKGMpe2JbY109ZnVuY3Rpb24oKXtyZXR1cm4gYVtjXS5hcHBseShhLGFyZ3VtZW50cyl9fSksYn1mdW5jdGlvbiBnKGIpe3ZhciBjLGQsaD0hMTt0aGlzLnJlcXVlc3Q9ZnVuY3Rpb24oKXtoPSExO3ZhciBnPWFyZ3VtZW50cztyZXR1cm4gYz1lKCksZihjLnByb21pc2UsdGhpcyksZD1uKGZ1bmN0aW9uKCl7aHx8YyYmYy5yZXNvbHZlKGIuYXBwbHkoYSxnKSl9KSx0aGlzfSx0aGlzLmNhbmNlbD1mdW5jdGlvbigpe3JldHVybiBkJiYoaD0hMCxvKGQpLGMmJmMucmVqZWN0KFwiQ0FOQ0VMXCIpKSx0aGlzfSx0aGlzLmNsb25lPWZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBnKGIpfX1mdW5jdGlvbiBoKGEsYil7XCJmdW5jdGlvblwiPT10eXBlb2YgYiYmKGI9ezA6Yn0pO2Zvcih2YXIgYz1hL2wsZD0xL2MsZT1bXSxmPU9iamVjdC5rZXlzKGIpLm1hcChmdW5jdGlvbihhKXtyZXR1cm4gcGFyc2VJbnQoYSl9KSxoPTA7Yz5oO2grKyl7dmFyIGk9ZlswXSxqPWQqaDtpZihudWxsIT1pJiYxMDAqaj49aSl7dmFyIGs9YltcIlwiK2ldO2sgaW5zdGFuY2VvZiBnfHwoaz1uZXcgZyhrKSksZS5wdXNoKGspLGYuc2hpZnQoKX1lbHNlIGUubGVuZ3RoJiZlLnB1c2goZVtlLmxlbmd0aC0xXS5jbG9uZSgpKX1yZXR1cm4gZX1mdW5jdGlvbiBpKGEpe3ZhciBjO3JldHVyblwic3RyaW5nXCI9PXR5cGVvZiBhfHxhIGluc3RhbmNlb2YgQXJyYXk/Yi5jdWJpY2Jlemllcj9cInN0cmluZ1wiPT10eXBlb2YgYT9iLmN1YmljYmV6aWVyW2FdJiYoYz1iLmN1YmljYmV6aWVyW2FdKTphIGluc3RhbmNlb2YgQXJyYXkmJjQ9PT1hLmxlbmd0aCYmKGM9Yi5jdWJpY2Jlemllci5hcHBseShiLmN1YmljYmV6aWVyLGEpKTpjb25zb2xlLmVycm9yKFwicmVxdWlyZSBsaWIuY3ViaWNiZXppZXJcIik6XCJmdW5jdGlvblwiPT10eXBlb2YgYSYmKGM9YSksY31mdW5jdGlvbiBqKGEsYixjKXt2YXIgZCxnPWgoYSxjKSxqPTEvKGEvbCksaz0wLG09aShiKTtpZighbSl0aHJvdyBuZXcgRXJyb3IoXCJ1bmV4Y2VwdCB0aW1pbmcgZnVuY3Rpb25cIik7dmFyIG49ITE7dGhpcy5wbGF5PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYSgpe3ZhciBjPWoqKGsrMSkudG9GaXhlZCgxMCksZT1nW2tdO2UucmVxdWVzdChjLnRvRml4ZWQoMTApLGIoYykudG9GaXhlZCgxMCkpLnRoZW4oZnVuY3Rpb24oKXtuJiYoaz09PWcubGVuZ3RoLTE/KG49ITEsZCYmZC5yZXNvbHZlKFwiRklOSVNIXCIpLGQ9bnVsbCk6KGsrKyxhKCkpKX0sZnVuY3Rpb24oKXt9KX1pZighbilyZXR1cm4gbj0hMCxkfHwoZD1lKCksZihkLnByb21pc2UsdGhpcykpLGEoKSx0aGlzfSx0aGlzLnN0b3A9ZnVuY3Rpb24oKXtyZXR1cm4gbj8obj0hMSxnW2tdJiZnW2tdLmNhbmNlbCgpLHRoaXMpOnZvaWQgMH19dmFyIGs9NjAsbD0xZTMvayxtPWEuUHJvbWlzZXx8Yi5wcm9taXNlJiZiLnByb21pc2UuRVM2UHJvbWlzZSxuPXdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWV8fHdpbmRvdy5tc1JlcXVlc3RBbmltYXRpb25GcmFtZXx8d2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZXx8d2luZG93Lm1velJlcXVlc3RBbmltYXRpb25GcmFtZXx8YyxvPXdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZXx8d2luZG93Lm1zQ2FuY2VsQW5pbWF0aW9uRnJhbWV8fHdpbmRvdy53ZWJraXRDYW5jZWxBbmltYXRpb25GcmFtZXx8d2luZG93Lm1vekNhbmNlbEFuaW1hdGlvbkZyYW1lfHxkOyhuPT09Y3x8bz09PWQpJiYobj1jLG89ZCksYi5hbmltYXRpb249ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBuZXcgaihhLGIsYyl9LGIuYW5pbWF0aW9uLmZyYW1lPWZ1bmN0aW9uKGEpe3JldHVybiBuZXcgZyhhKX0sYi5hbmltYXRpb24ucmVxdWVzdEZyYW1lPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBnKGEpO3JldHVybiBiLnJlcXVlc3QoKX19KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpOzttb2R1bGUuZXhwb3J0cyA9IHdpbmRvdy5saWJbJ2FuaW1hdGlvbiddO1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2FuaW1hdGlvbmpzL2J1aWxkL2FuaW1hdGlvbi5jb21tb24uanNcbiAqKiBtb2R1bGUgaWQgPSAzM1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSAmJiAod2luZG93ID0ge2N0cmw6IHt9LCBsaWI6IHt9fSk7IXdpbmRvdy5jdHJsICYmICh3aW5kb3cuY3RybCA9IHt9KTshd2luZG93LmxpYiAmJiAod2luZG93LmxpYiA9IHt9KTshZnVuY3Rpb24oYSxiKXtmdW5jdGlvbiBjKGEsYixjLGQpe2Z1bmN0aW9uIGUoYSl7cmV0dXJuKDMqayphKzIqbCkqYSttfWZ1bmN0aW9uIGYoYSl7cmV0dXJuKChrKmErbCkqYSttKSphfWZ1bmN0aW9uIGcoYSl7cmV0dXJuKChuKmErbykqYStwKSphfWZ1bmN0aW9uIGgoYSl7Zm9yKHZhciBiLGMsZD1hLGc9MDs4Pmc7ZysrKXtpZihjPWYoZCktYSxNYXRoLmFicyhjKTxqKXJldHVybiBkO2lmKGI9ZShkKSxNYXRoLmFicyhiKTxqKWJyZWFrO2QtPWMvYn12YXIgaD0xLGk9MDtmb3IoZD1hO2g+aTspe2lmKGM9ZihkKS1hLE1hdGguYWJzKGMpPGopcmV0dXJuIGQ7Yz4wP2g9ZDppPWQsZD0oaCtpKS8yfXJldHVybiBkfWZ1bmN0aW9uIGkoYSl7cmV0dXJuIGcoaChhKSl9dmFyIGo9MWUtNixrPTMqYS0zKmMrMSxsPTMqYy02KmEsbT0zKmEsbj0zKmItMypkKzEsbz0zKmQtNipiLHA9MypiO3JldHVybiBpfWIuY3ViaWNiZXppZXI9YyxiLmN1YmljYmV6aWVyLmxpbmVhcj1jKDAsMCwxLDEpLGIuY3ViaWNiZXppZXIuZWFzZT1jKC4yNSwuMSwuMjUsMSksYi5jdWJpY2Jlemllci5lYXNlSW49YyguNDIsMCwxLDEpLGIuY3ViaWNiZXppZXIuZWFzZU91dD1jKDAsMCwuNTgsMSksYi5jdWJpY2Jlemllci5lYXNlSW5PdXQ9YyguNDIsMCwuNTgsMSl9KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpOzttb2R1bGUuZXhwb3J0cyA9IHdpbmRvdy5saWJbJ2N1YmljYmV6aWVyJ107XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3ViaWNiZXppZXIvYnVpbGQvY3ViaWNiZXppZXIuY29tbW9uLmpzXG4gKiogbW9kdWxlIGlkID0gMzRcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIih0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgJiYgKHdpbmRvdyA9IHtjdHJsOiB7fSwgbGliOiB7fX0pOyF3aW5kb3cuY3RybCAmJiAod2luZG93LmN0cmwgPSB7fSk7IXdpbmRvdy5saWIgJiYgKHdpbmRvdy5saWIgPSB7fSk7IWZ1bmN0aW9uKGEpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIGIoYSxiKXtmb3IodmFyIGM9YTtjOyl7aWYoYy5jb250YWlucyhiKXx8Yz09YilyZXR1cm4gYztjPWMucGFyZW50Tm9kZX1yZXR1cm4gbnVsbH1mdW5jdGlvbiBjKGEsYixjKXt2YXIgZD1pLmNyZWF0ZUV2ZW50KFwiSFRNTEV2ZW50c1wiKTtpZihkLmluaXRFdmVudChiLCEwLCEwKSxcIm9iamVjdFwiPT10eXBlb2YgYylmb3IodmFyIGUgaW4gYylkW2VdPWNbZV07YS5kaXNwYXRjaEV2ZW50KGQpfWZ1bmN0aW9uIGQoYSxiLGMsZCxlLGYsZyxoKXt2YXIgaT1NYXRoLmF0YW4yKGgtZixnLWUpLU1hdGguYXRhbjIoZC1iLGMtYSksaj1NYXRoLnNxcnQoKE1hdGgucG93KGgtZiwyKStNYXRoLnBvdyhnLWUsMikpLyhNYXRoLnBvdyhkLWIsMikrTWF0aC5wb3coYy1hLDIpKSksaz1bZS1qKmEqTWF0aC5jb3MoaSkraipiKk1hdGguc2luKGkpLGYtaipiKk1hdGguY29zKGkpLWoqYSpNYXRoLnNpbihpKV07cmV0dXJue3JvdGF0ZTppLHNjYWxlOmosdHJhbnNsYXRlOmssbWF0cml4OltbaipNYXRoLmNvcyhpKSwtaipNYXRoLnNpbihpKSxrWzBdXSxbaipNYXRoLnNpbihpKSxqKk1hdGguY29zKGkpLGtbMV1dLFswLDAsMV1dfX1mdW5jdGlvbiBlKGEpezA9PT1PYmplY3Qua2V5cyhsKS5sZW5ndGgmJihqLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIixmLCExKSxqLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLGcsITEpLGouYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsaCwhMSkpO2Zvcih2YXIgZD0wO2Q8YS5jaGFuZ2VkVG91Y2hlcy5sZW5ndGg7ZCsrKXt2YXIgZT1hLmNoYW5nZWRUb3VjaGVzW2RdLGk9e307Zm9yKHZhciBtIGluIGUpaVttXT1lW21dO3ZhciBuPXtzdGFydFRvdWNoOmksc3RhcnRUaW1lOkRhdGUubm93KCksc3RhdHVzOlwidGFwcGluZ1wiLGVsZW1lbnQ6YS5zcmNFbGVtZW50fHxhLnRhcmdldCxwcmVzc2luZ0hhbmRsZXI6c2V0VGltZW91dChmdW5jdGlvbihiLGQpe3JldHVybiBmdW5jdGlvbigpe1widGFwcGluZ1wiPT09bi5zdGF0dXMmJihuLnN0YXR1cz1cInByZXNzaW5nXCIsYyhiLFwibG9uZ3ByZXNzXCIse3RvdWNoOmQsdG91Y2hlczphLnRvdWNoZXMsY2hhbmdlZFRvdWNoZXM6YS5jaGFuZ2VkVG91Y2hlcyx0b3VjaEV2ZW50OmF9KSksY2xlYXJUaW1lb3V0KG4ucHJlc3NpbmdIYW5kbGVyKSxuLnByZXNzaW5nSGFuZGxlcj1udWxsfX0oYS5zcmNFbGVtZW50fHxhLnRhcmdldCxhLmNoYW5nZWRUb3VjaGVzW2RdKSw1MDApfTtsW2UuaWRlbnRpZmllcl09bn1pZigyPT1PYmplY3Qua2V5cyhsKS5sZW5ndGgpe3ZhciBvPVtdO2Zvcih2YXIgbSBpbiBsKW8ucHVzaChsW21dLmVsZW1lbnQpO2MoYihvWzBdLG9bMV0pLFwiZHVhbHRvdWNoc3RhcnRcIix7dG91Y2hlczprLmNhbGwoYS50b3VjaGVzKSx0b3VjaEV2ZW50OmF9KX19ZnVuY3Rpb24gZihhKXtmb3IodmFyIGU9MDtlPGEuY2hhbmdlZFRvdWNoZXMubGVuZ3RoO2UrKyl7dmFyIGY9YS5jaGFuZ2VkVG91Y2hlc1tlXSxnPWxbZi5pZGVudGlmaWVyXTtpZighZylyZXR1cm47Zy5sYXN0VG91Y2h8fChnLmxhc3RUb3VjaD1nLnN0YXJ0VG91Y2gpLGcubGFzdFRpbWV8fChnLmxhc3RUaW1lPWcuc3RhcnRUaW1lKSxnLnZlbG9jaXR5WHx8KGcudmVsb2NpdHlYPTApLGcudmVsb2NpdHlZfHwoZy52ZWxvY2l0eVk9MCksZy5kdXJhdGlvbnx8KGcuZHVyYXRpb249MCk7dmFyIGg9RGF0ZS5ub3coKS1nLmxhc3RUaW1lLGk9KGYuY2xpZW50WC1nLmxhc3RUb3VjaC5jbGllbnRYKS9oLGo9KGYuY2xpZW50WS1nLmxhc3RUb3VjaC5jbGllbnRZKS9oLGs9NzA7aD5rJiYoaD1rKSxnLmR1cmF0aW9uK2g+ayYmKGcuZHVyYXRpb249ay1oKSxnLnZlbG9jaXR5WD0oZy52ZWxvY2l0eVgqZy5kdXJhdGlvbitpKmgpLyhnLmR1cmF0aW9uK2gpLGcudmVsb2NpdHlZPShnLnZlbG9jaXR5WSpnLmR1cmF0aW9uK2oqaCkvKGcuZHVyYXRpb24raCksZy5kdXJhdGlvbis9aCxnLmxhc3RUb3VjaD17fTtmb3IodmFyIG0gaW4gZilnLmxhc3RUb3VjaFttXT1mW21dO2cubGFzdFRpbWU9RGF0ZS5ub3coKTt2YXIgbj1mLmNsaWVudFgtZy5zdGFydFRvdWNoLmNsaWVudFgsbz1mLmNsaWVudFktZy5zdGFydFRvdWNoLmNsaWVudFkscD1NYXRoLnNxcnQoTWF0aC5wb3cobiwyKStNYXRoLnBvdyhvLDIpKTsoXCJ0YXBwaW5nXCI9PT1nLnN0YXR1c3x8XCJwcmVzc2luZ1wiPT09Zy5zdGF0dXMpJiZwPjEwJiYoZy5zdGF0dXM9XCJwYW5uaW5nXCIsZy5pc1ZlcnRpY2FsPSEoTWF0aC5hYnMobik+TWF0aC5hYnMobykpLGMoZy5lbGVtZW50LFwicGFuc3RhcnRcIix7dG91Y2g6Zix0b3VjaGVzOmEudG91Y2hlcyxjaGFuZ2VkVG91Y2hlczphLmNoYW5nZWRUb3VjaGVzLHRvdWNoRXZlbnQ6YSxpc1ZlcnRpY2FsOmcuaXNWZXJ0aWNhbH0pLGMoZy5lbGVtZW50LChnLmlzVmVydGljYWw/XCJ2ZXJ0aWNhbFwiOlwiaG9yaXpvbnRhbFwiKStcInBhbnN0YXJ0XCIse3RvdWNoOmYsdG91Y2hFdmVudDphfSkpLFwicGFubmluZ1wiPT09Zy5zdGF0dXMmJihnLnBhblRpbWU9RGF0ZS5ub3coKSxjKGcuZWxlbWVudCxcInBhbm1vdmVcIix7ZGlzcGxhY2VtZW50WDpuLGRpc3BsYWNlbWVudFk6byx0b3VjaDpmLHRvdWNoZXM6YS50b3VjaGVzLGNoYW5nZWRUb3VjaGVzOmEuY2hhbmdlZFRvdWNoZXMsdG91Y2hFdmVudDphLGlzVmVydGljYWw6Zy5pc1ZlcnRpY2FsfSksZy5pc1ZlcnRpY2FsP2MoZy5lbGVtZW50LFwidmVydGljYWxwYW5tb3ZlXCIse2Rpc3BsYWNlbWVudFk6byx0b3VjaDpmLHRvdWNoRXZlbnQ6YX0pOmMoZy5lbGVtZW50LFwiaG9yaXpvbnRhbHBhbm1vdmVcIix7ZGlzcGxhY2VtZW50WDpuLHRvdWNoOmYsdG91Y2hFdmVudDphfSkpfWlmKDI9PU9iamVjdC5rZXlzKGwpLmxlbmd0aCl7Zm9yKHZhciBxLHI9W10scz1bXSx0PVtdLGU9MDtlPGEudG91Y2hlcy5sZW5ndGg7ZSsrKXt2YXIgZj1hLnRvdWNoZXNbZV0sZz1sW2YuaWRlbnRpZmllcl07ci5wdXNoKFtnLnN0YXJ0VG91Y2guY2xpZW50WCxnLnN0YXJ0VG91Y2guY2xpZW50WV0pLHMucHVzaChbZi5jbGllbnRYLGYuY2xpZW50WV0pfWZvcih2YXIgbSBpbiBsKXQucHVzaChsW21dLmVsZW1lbnQpO3E9ZChyWzBdWzBdLHJbMF1bMV0sclsxXVswXSxyWzFdWzFdLHNbMF1bMF0sc1swXVsxXSxzWzFdWzBdLHNbMV1bMV0pLGMoYih0WzBdLHRbMV0pLFwiZHVhbHRvdWNoXCIse3RyYW5zZm9ybTpxLHRvdWNoZXM6YS50b3VjaGVzLHRvdWNoRXZlbnQ6YX0pfX1mdW5jdGlvbiBnKGEpe2lmKDI9PU9iamVjdC5rZXlzKGwpLmxlbmd0aCl7dmFyIGQ9W107Zm9yKHZhciBlIGluIGwpZC5wdXNoKGxbZV0uZWxlbWVudCk7YyhiKGRbMF0sZFsxXSksXCJkdWFsdG91Y2hlbmRcIix7dG91Y2hlczprLmNhbGwoYS50b3VjaGVzKSx0b3VjaEV2ZW50OmF9KX1mb3IodmFyIGk9MDtpPGEuY2hhbmdlZFRvdWNoZXMubGVuZ3RoO2krKyl7dmFyIG49YS5jaGFuZ2VkVG91Y2hlc1tpXSxvPW4uaWRlbnRpZmllcixwPWxbb107aWYocCl7aWYocC5wcmVzc2luZ0hhbmRsZXImJihjbGVhclRpbWVvdXQocC5wcmVzc2luZ0hhbmRsZXIpLHAucHJlc3NpbmdIYW5kbGVyPW51bGwpLFwidGFwcGluZ1wiPT09cC5zdGF0dXMmJihwLnRpbWVzdGFtcD1EYXRlLm5vdygpLGMocC5lbGVtZW50LFwidGFwXCIse3RvdWNoOm4sdG91Y2hFdmVudDphfSksbSYmcC50aW1lc3RhbXAtbS50aW1lc3RhbXA8MzAwJiZjKHAuZWxlbWVudCxcImRvdWJsZXRhcFwiLHt0b3VjaDpuLHRvdWNoRXZlbnQ6YX0pLG09cCksXCJwYW5uaW5nXCI9PT1wLnN0YXR1cyl7dmFyIHE9RGF0ZS5ub3coKSxyPXEtcC5zdGFydFRpbWUscz0oKG4uY2xpZW50WC1wLnN0YXJ0VG91Y2guY2xpZW50WCkvciwobi5jbGllbnRZLXAuc3RhcnRUb3VjaC5jbGllbnRZKS9yLG4uY2xpZW50WC1wLnN0YXJ0VG91Y2guY2xpZW50WCksdD1uLmNsaWVudFktcC5zdGFydFRvdWNoLmNsaWVudFksdT1NYXRoLnNxcnQocC52ZWxvY2l0eVkqcC52ZWxvY2l0eVkrcC52ZWxvY2l0eVgqcC52ZWxvY2l0eVgpLHY9dT4uNSYmcS1wLmxhc3RUaW1lPDEwMCx3PXtkdXJhdGlvbjpyLGlzZmxpY2s6dix2ZWxvY2l0eVg6cC52ZWxvY2l0eVgsdmVsb2NpdHlZOnAudmVsb2NpdHlZLGRpc3BsYWNlbWVudFg6cyxkaXNwbGFjZW1lbnRZOnQsdG91Y2g6bix0b3VjaGVzOmEudG91Y2hlcyxjaGFuZ2VkVG91Y2hlczphLmNoYW5nZWRUb3VjaGVzLHRvdWNoRXZlbnQ6YSxpc1ZlcnRpY2FsOnAuaXNWZXJ0aWNhbH07YyhwLmVsZW1lbnQsXCJwYW5lbmRcIix3KSx2JiYoYyhwLmVsZW1lbnQsXCJzd2lwZVwiLHcpLHAuaXNWZXJ0aWNhbD9jKHAuZWxlbWVudCxcInZlcnRpY2Fsc3dpcGVcIix3KTpjKHAuZWxlbWVudCxcImhvcml6b250YWxzd2lwZVwiLHcpKX1cInByZXNzaW5nXCI9PT1wLnN0YXR1cyYmYyhwLmVsZW1lbnQsXCJwcmVzc2VuZFwiLHt0b3VjaDpuLHRvdWNoRXZlbnQ6YX0pLGRlbGV0ZSBsW29dfX0wPT09T2JqZWN0LmtleXMobCkubGVuZ3RoJiYoai5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsZiwhMSksai5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIixnLCExKSxqLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGNhbmNlbFwiLGgsITEpKX1mdW5jdGlvbiBoKGEpe2lmKDI9PU9iamVjdC5rZXlzKGwpLmxlbmd0aCl7dmFyIGQ9W107Zm9yKHZhciBlIGluIGwpZC5wdXNoKGxbZV0uZWxlbWVudCk7YyhiKGRbMF0sZFsxXSksXCJkdWFsdG91Y2hlbmRcIix7dG91Y2hlczprLmNhbGwoYS50b3VjaGVzKSx0b3VjaEV2ZW50OmF9KX1mb3IodmFyIGk9MDtpPGEuY2hhbmdlZFRvdWNoZXMubGVuZ3RoO2krKyl7dmFyIG09YS5jaGFuZ2VkVG91Y2hlc1tpXSxuPW0uaWRlbnRpZmllcixvPWxbbl07byYmKG8ucHJlc3NpbmdIYW5kbGVyJiYoY2xlYXJUaW1lb3V0KG8ucHJlc3NpbmdIYW5kbGVyKSxvLnByZXNzaW5nSGFuZGxlcj1udWxsKSxcInBhbm5pbmdcIj09PW8uc3RhdHVzJiZjKG8uZWxlbWVudCxcInBhbmVuZFwiLHt0b3VjaDptLHRvdWNoZXM6YS50b3VjaGVzLGNoYW5nZWRUb3VjaGVzOmEuY2hhbmdlZFRvdWNoZXMsdG91Y2hFdmVudDphfSksXCJwcmVzc2luZ1wiPT09by5zdGF0dXMmJmMoby5lbGVtZW50LFwicHJlc3NlbmRcIix7dG91Y2g6bSx0b3VjaEV2ZW50OmF9KSxkZWxldGUgbFtuXSl9MD09PU9iamVjdC5rZXlzKGwpLmxlbmd0aCYmKGoucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLGYsITEpLGoucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsZywhMSksai5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hjYW5jZWxcIixoLCExKSl9dmFyIGk9YS5kb2N1bWVudCxqPWkuZG9jdW1lbnRFbGVtZW50LGs9QXJyYXkucHJvdG90eXBlLnNsaWNlLGw9e30sbT1udWxsO2ouYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIixlLCExKX0od2luZG93KTs7bW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cubGliWydnZXN0dXJlanMnXTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9nZXN0dXJlanMvYnVpbGQvZ2VzdHVyZWpzLmNvbW1vbi5qc1xuICoqIG1vZHVsZSBpZCA9IDM1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpICYmICh3aW5kb3cgPSB7Y3RybDoge30sIGxpYjoge319KTshd2luZG93LmN0cmwgJiYgKHdpbmRvdy5jdHJsID0ge30pOyF3aW5kb3cubGliICYmICh3aW5kb3cubGliID0ge30pOyFmdW5jdGlvbihhLGIpe2Z1bmN0aW9uIGMoYSxiKXtyZXR1cm5bWyhhLzMrKGErYikvMy1hKS8oYi1hKSwoYSphLzMrYSpiKjIvMy1hKmEpLyhiKmItYSphKV0sWyhiLzMrKGErYikvMy1hKS8oYi1hKSwoYipiLzMrYSpiKjIvMy1hKmEpLyhiKmItYSphKV1dfWZ1bmN0aW9uIGQoYSl7aWYodGhpcy52PWEudnx8MCx0aGlzLmE9YS5hfHwwLFwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLnQmJih0aGlzLnQ9YS50KSxcInVuZGVmaW5lZFwiIT10eXBlb2YgYS5zJiYodGhpcy5zPWEucyksXCJ1bmRlZmluZWRcIj09dHlwZW9mIHRoaXMudClpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgdGhpcy5zKXRoaXMudD0tdGhpcy52L3RoaXMuYTtlbHNle3ZhciBiPShNYXRoLnNxcnQodGhpcy52KnRoaXMudisyKnRoaXMuYSp0aGlzLnMpLXRoaXMudikvdGhpcy5hLGM9KC1NYXRoLnNxcnQodGhpcy52KnRoaXMudisyKnRoaXMuYSp0aGlzLnMpLXRoaXMudikvdGhpcy5hO3RoaXMudD1NYXRoLm1pbihiLGMpfVwidW5kZWZpbmVkXCI9PXR5cGVvZiB0aGlzLnMmJih0aGlzLnM9dGhpcy5hKnRoaXMudCp0aGlzLnQvMit0aGlzLnYqdGhpcy50KX1kLnByb3RvdHlwZS5nZW5lcmF0ZUN1YmljQmV6aWVyPWZ1bmN0aW9uKCl7cmV0dXJuIGModGhpcy52L3RoaXMuYSx0aGlzLnQrdGhpcy52L3RoaXMuYSl9LGIubW90aW9uPWR9KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpOzttb2R1bGUuZXhwb3J0cyA9IHdpbmRvdy5saWJbJ21vdGlvbiddO1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L21vdGlvbmpzL2J1aWxkL21vdGlvbi5jb21tb24uanNcbiAqKiBtb2R1bGUgaWQgPSAzNlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG5yZXF1aXJlKCdrb3VudGRvd24vYnVpbGQvY291bnRkb3duJylcblxudmFyIEZPUk1BVFRFUl9SRUdFWFAgPSAvKFxcXFwpPyhkZCp8aGg/fG1tP3xzcz8pL2dpXG5cbmZ1bmN0aW9uIGZvcm1hdERhdGVUaW1lKGRhdGEsIGZvcm1hdHRlciwgdGltZUNvbG9yKSB7XG4gIHJldHVybiBmb3JtYXR0ZXIucmVwbGFjZShGT1JNQVRURVJfUkVHRVhQLCBmdW5jdGlvbiAobSkge1xuICAgIHZhciBsZW4gPSBtLmxlbmd0aFxuICAgIHZhciBmaXJzdENoYXIgPSBtLmNoYXJBdCgwKVxuICAgIC8vIGVzY2FwZSBjaGFyYWN0ZXJcbiAgICBpZiAoZmlyc3RDaGFyID09PSAnXFxcXCcpIHtcbiAgICAgIHJldHVybiBtLnJlcGxhY2UoJ1xcXFwnLCAnJylcbiAgICB9XG4gICAgdmFyIHZhbHVlID0gKGZpcnN0Q2hhciA9PT0gJ2QnID8gZGF0YS5kYXlzIDpcbiAgICAgICAgICAgICAgICBmaXJzdENoYXIgPT09ICdoJyA/IGRhdGEuaG91cnMgOlxuICAgICAgICAgICAgICAgIGZpcnN0Q2hhciA9PT0gJ20nID8gZGF0YS5taW51dGVzIDpcbiAgICAgICAgICAgICAgICBmaXJzdENoYXIgPT09ICdzJyA/IGRhdGEuc2Vjb25kcyA6IDApICsgJydcblxuICAgIC8vIDUgemVybyBzaG91bGQgYmUgZW5vdWdoXG4gICAgcmV0dXJuICc8c3BhbiBzdHlsZT1cIm1hcmdpbjo0cHg7Y29sb3I6J1xuICAgICAgKyB0aW1lQ29sb3IgKyAnXCIgPidcbiAgICAgICsgKCcwMDAwMCcgKyB2YWx1ZSkuc3Vic3RyKC1NYXRoLm1heCh2YWx1ZS5sZW5ndGgsIGxlbikpXG4gICAgICArICc8L3NwYW4+J1xuICB9KVxufVxuXG5mdW5jdGlvbiBDb3VudGRvd24gKGRhdGEpIHtcbiAgQXRvbWljLmNhbGwodGhpcywgZGF0YSlcbn1cblxuQ291bnRkb3duLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQXRvbWljLnByb3RvdHlwZSlcblxuQ291bnRkb3duLnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKCd3ZWV4LWVsZW1lbnQnKVxuICB2YXIgZGF0YSA9IHRoaXMuZGF0YVxuICB2YXIgdGltZSA9IE51bWJlcihkYXRhLmF0dHIuY291bnRkb3duVGltZSkgfHwgMFxuICB2YXIgZW5kVGltZSA9IERhdGUubm93KCkgLyAxMDAwICsgdGltZVxuICB2YXIgY2QgPSBsaWIuY291bnRkb3duKHtcbiAgICBlbmREYXRlOiBlbmRUaW1lLFxuICAgIG9uVXBkYXRlOiBmdW5jdGlvbiAodGltZSkge1xuICAgICAgdmFyIHRpbWVDb2xvciA9IGRhdGEuc3R5bGUudGltZUNvbG9yIHx8ICcjMDAwJ1xuICAgICAgdmFyIHJlc3VsdCA9IGZvcm1hdERhdGVUaW1lKHRpbWUsIGRhdGEuYXR0ci5mb3JtYXR0ZXJWYWx1ZSwgdGltZUNvbG9yKVxuICAgICAgbm9kZS5pbm5lckhUTUwgPSByZXN1bHRcbiAgICB9LFxuICAgIG9uRW5kOiBmdW5jdGlvbiAoKSB7XG4gICAgfVxuICB9KS5zdGFydCgpXG5cbiAgcmV0dXJuIG5vZGVcbn1cblxuQ291bnRkb3duLnByb3RvdHlwZS5zdHlsZSA9IHtcbiAgdGV4dENvbG9yOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB0aGlzLm5vZGUuc3R5bGUuY29sb3IgPSB2YWx1ZVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ291bnRkb3duXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvY291bnRkb3duLmpzXG4gKiogbW9kdWxlIGlkID0gMzdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIiFmdW5jdGlvbihhLGIpe2Z1bmN0aW9uIGMoYSl7dmFyIGI7aWYoXCJudW1iZXJcIj09dHlwZW9mIGEpYj1uZXcgRGF0ZSgxZTMqYSk7ZWxzZSBpZihcInN0cmluZ1wiPT10eXBlb2YgYSl7dmFyIGM9YS5jaGFyQXQoMCksZD1cIitcIj09PWMsaD1cIi1cIj09PWM7aWYoZHx8aCl7Zm9yKHZhciBpLGo9YS5zdWJzdHIoMSksaz1qLnNwbGl0KFwiOlwiKSxsPVswLDAsMCwwXSxtPTQ7ay5sZW5ndGgmJi0tbT49MDspbFttXT1wYXJzZUludChrLnBvcCgpKXx8MDtpPWUqbFswXStmKmxbMV0rZypsWzJdK2xbM10sYj1uZXcgRGF0ZSxiLnNldFNlY29uZHMoYi5nZXRTZWNvbmRzKCkraSooaD8tMToxKSksYi5zZXRNaWxsaXNlY29uZHMoMCl9fXJldHVybiBifHwoYj1uZXcgRGF0ZShhKSksYn1mdW5jdGlvbiBkKGEsYil7cmV0dXJuIGIucmVwbGFjZShGT1JNQVRURVJfUkVHRVhQLGZ1bmN0aW9uKGIpe3ZhciBjPWIubGVuZ3RoLGQ9Yi5jaGFyQXQoMCk7aWYoXCJcXFxcXCI9PT1kKXJldHVybiBiLnJlcGxhY2UoXCJcXFxcXCIsXCJcIik7dmFyIGU9KFwiZFwiPT09ZD9hLmRheXM6XCJoXCI9PT1kP2EuaG91cnM6XCJtXCI9PT1kP2EubWludXRlczpcInNcIj09PWQ/YS5zZWNvbmRzOjApK1wiXCI7cmV0dXJuKFwiMDAwMDBcIitlKS5zdWJzdHIoLU1hdGgubWF4KGUubGVuZ3RoLGMpKX0pfXZhciBlPTg2NDAwLGY9MzYwMCxnPTYwLGg9XCJk5aSpaGjml7ZtbeWIhnNz56eSXCI7Rk9STUFUVEVSX1JFR0VYUD0vKFxcXFwpPyhkZCp8aGg/fG1tP3xzcz8pL2dpO3ZhciBpPWZ1bmN0aW9uKGEpe2E9YXx8e307dmFyIGI9dGhpcyxkPWMoYS5lbmREYXRlKTtpZighZHx8IWQuZ2V0VGltZSgpKXRocm93IG5ldyBFcnJvcihcIkludmFsaWQgZW5kRGF0ZVwiKTtiLmVuZERhdGU9ZCxiLm9uVXBkYXRlPWEub25VcGRhdGUsYi5vbkVuZD1hLm9uRW5kLGIuaW50ZXJ2YWw9YS5pbnRlcnZhbHx8MWUzLGIuc3RyaW5nRm9ybWF0dGVyPWEuc3RyaW5nRm9ybWF0dGVyfHxoLGIuY29ycmVjdERhdGVPZmZzZXQ9YS5jb3JyZWN0RGF0ZU9mZnNldHx8MCxiLnVwZGF0ZUVsZW1lbnQ9YS51cGRhdGVFbGVtZW50LGIuX2RhdGE9e2RheXM6MCxob3VyczowLG1pbnV0ZXM6MCxzZWNvbmRzOjB9fTtpLnByb3RvdHlwZT17c3RhcnQ6ZnVuY3Rpb24oKXt2YXIgYT10aGlzO3JldHVybiBhLnN0b3AoKSxhLl91cGRhdGUoKSYmKGEuX2ludGVydmFsSWQ9c2V0SW50ZXJ2YWwoZnVuY3Rpb24oKXthLl91cGRhdGUoKX0sYS5pbnRlcnZhbCkpLGF9LF91cGRhdGU6ZnVuY3Rpb24oKXt2YXIgYSxiPXRoaXMsYz1iLl9kYXRhLGg9Yi51cGRhdGVFbGVtZW50LGk9K25ldyBEYXRlKzFlMypiLmNvcnJlY3REYXRlT2Zmc2V0LGo9TWF0aC5tYXgoMCxNYXRoLnJvdW5kKChiLmVuZERhdGUuZ2V0VGltZSgpLWkpLzFlMykpLGs9MD49ajtyZXR1cm4gYy50b3RhbFNlY29uZHM9aixqLT0oYy5kYXlzPU1hdGguZmxvb3Ioai9lKSkqZSxqLT0oYy5ob3Vycz1NYXRoLmZsb29yKGovZikpKmYsai09KGMubWludXRlcz1NYXRoLmZsb29yKGovZykpKmcsYy5zZWNvbmRzPWosYy5zdHJpbmdWYWx1ZT1kKGMsYi5zdHJpbmdGb3JtYXR0ZXIpLGgmJihoLmlubmVySFRNTD1jLnN0cmluZ1ZhbHVlKSwoYT1iLm9uVXBkYXRlKSYmYS5jYWxsKGIsYyksaz8oYi5zdG9wKCksKGE9Yi5vbkVuZCkmJmEuY2FsbChiKSwhMSk6ITB9LHN0b3A6ZnVuY3Rpb24oKXt2YXIgYT10aGlzO3JldHVybiBhLl9pbnRlcnZhbElkJiYoY2xlYXJJbnRlcnZhbChhLl9pbnRlcnZhbElkKSxhLl9pbnRlcnZhbElkPW51bGwpLGF9LHNldEVuZERhdGU6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcztyZXR1cm4gYi5lbmREYXRlPWMoYSksYn19LGIuY291bnRkb3duPWZ1bmN0aW9uKGEpe3JldHVybiBuZXcgaShhKX19KHdpbmRvdyx3aW5kb3cubGlifHwod2luZG93LmxpYj17fSkpO1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2tvdW50ZG93bi9idWlsZC9jb3VudGRvd24uanNcbiAqKiBtb2R1bGUgaWQgPSAzOFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKVxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcbnZhciBDb21wb25lbnRNYW5hZ2VyID0gcmVxdWlyZSgnLi4vY29tcG9uZW50TWFuYWdlcicpXG52YXIgTGF6eUxvYWQgPSByZXF1aXJlKCcuLi9sYXp5TG9hZCcpXG5cbmZ1bmN0aW9uIE1hcnF1ZWUgKGRhdGEpIHtcbiAgdGhpcy5pbnRlcnZhbCA9IE51bWJlcihkYXRhLmF0dHIuaW50ZXJ2YWwpIHx8IDUgKiAxMDAwXG4gIHRoaXMudHJhbnNpdGlvbkR1cmF0aW9uID0gTnVtYmVyKGRhdGEuYXR0ci50cmFuc2l0aW9uRHVyYXRpb24pIHx8IDUwMFxuICB0aGlzLmRlbGF5ID0gTnVtYmVyKGRhdGEuYXR0ci5kZWxheSkgfHwgMFxuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5NYXJxdWVlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxuTWFycXVlZS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1jb250YWluZXInKVxuICBub2RlLnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbidcbiAgLy8gZml4IHBhZ2Ugc2hha2luZyBkdXJpbmcgc2xpZGVyJ3MgcGxheWluZ1xuICBub2RlLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd0cmFuc2xhdGUzRCgwLDAsMCknXG4gIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcignd2Via2l0VHJhbnNpdGlvbkVuZCcsIHRoaXMuZW5kLmJpbmQodGhpcyksIGZhbHNlKVxuICByZXR1cm4gbm9kZVxufVxuXG5NYXJxdWVlLnByb3RvdHlwZS5jcmVhdGVDaGlsZHJlbiA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gZmlyc3QgcnVuOlxuICAvLyAtIGNyZWF0ZSBlYWNoIGNoaWxkXG4gIC8vIC0gYXBwZW5kIHRvIHBhcmVudE5vZGVcbiAgLy8gLSBmaW5kIGN1cnJlbnQgYW5kIG5leHRcbiAgLy8gLSBzZXQgY3VycmVudCBhbmQgbmV4dCBzaG93biBhbmQgb3RoZXJzIGhpZGRlblxuICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgdmFyIHBhcmVudFJlZiA9IHRoaXMuZGF0YS5yZWZcbiAgdmFyIGluc3RhbmNlSWQgPSB0aGlzLmRhdGEuaW5zdGFuY2VJZFxuICB2YXIgaXRlbXMgPSBbXVxuICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG5cbiAgdmFyIGZyYWdtZW50LCBpc0ZsZXgsIGNoaWxkLCBub2RlLCBpXG5cbiAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpXG4gICAgaXNGbGV4ID0gZmFsc2VcbiAgICBmb3IgKGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoaWxkcmVuW2ldLnNjYWxlID0gdGhpcy5kYXRhLnNjYWxlXG4gICAgICBjaGlsZHJlbltpXS5pbnN0YW5jZUlkID0gaW5zdGFuY2VJZFxuICAgICAgY2hpbGQgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoY2hpbGRyZW5baV0pXG4gICAgICBjaGlsZC5wYXJlbnRSZWYgPSBwYXJlbnRSZWZcbiAgICAgIHRoaXMuaW5pdENoaWxkKGNoaWxkKVxuICAgICAgLy8gYXBwZW5kIGFuZCBwdXNoXG4gICAgICBpdGVtcy5wdXNoKGNoaWxkKVxuICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoY2hpbGQubm9kZSlcbiAgICAgIGlmICghaXNGbGV4ICYmIGNoaWxkLmRhdGEuc3R5bGUuaGFzT3duUHJvcGVydHkoJ2ZsZXgnKSkge1xuICAgICAgICBpc0ZsZXggPSB0cnVlXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMubm9kZS5hcHBlbmRDaGlsZChmcmFnbWVudClcbiAgfVxuXG4gIC8vIHNldCBpdGVtc1xuICB0aGlzLml0ZW1zID0gaXRlbXNcblxuICAvLyByZXNldCB0aGUgY2xvY2sgZm9yIGZpcnN0IHRyYW5zaXRpb25cbiAgdGhpcy5yZXNldCgpXG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLmluaXRDaGlsZCA9IGZ1bmN0aW9uIChjaGlsZCkge1xuICB2YXIgbm9kZSA9IGNoaWxkLm5vZGVcbiAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSdcbiAgbm9kZS5zdHlsZS50b3AgPSAnMCdcbiAgbm9kZS5zdHlsZS5sZWZ0ID0gJzAnXG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLmFwcGVuZENoaWxkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgLy8gZG9tICsgaXRlbXNcbiAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSBDb21wb25lbnRNYW5hZ2VyLmdldEluc3RhbmNlKHRoaXMuZGF0YS5pbnN0YW5jZUlkKVxuICB2YXIgY2hpbGQgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoZGF0YSlcbiAgdGhpcy5pbml0Q2hpbGQoY2hpbGQpXG4gIHRoaXMubm9kZS5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICB0aGlzLml0ZW1zLnB1c2goY2hpbGQpXG4gIHRoaXMucmVzZXQoKVxuICByZXR1cm4gY2hpbGQgLy8gQHRvZG8gcmVkZXNpZ24gQ29tcG9uZW50I2FwcGVuZENoaWxkKGNvbXBvbmVudClcbn1cblxuTWFycXVlZS5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgLy8gZG9tICsgaXRlbXNcbiAgdmFyIGluZGV4ID0gdGhpcy5pdGVtcy5pbmRleE9mKGJlZm9yZSlcbiAgdGhpcy5pdGVtcy5zcGxpY2UoaW5kZXgsIDAsIGNoaWxkKVxuICB0aGlzLmluaXRDaGlsZChjaGlsZClcbiAgdGhpcy5ub2RlLmluc2VydEJlZm9yZShjaGlsZC5ub2RlLCBiZWZvcmUubm9kZSlcbiAgdGhpcy5yZXNldCgpXG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLnJlbW92ZUNoaWxkID0gZnVuY3Rpb24gKGNoaWxkKSB7XG4gIC8vIGRvbSArIGl0ZW1zXG4gIHZhciBpbmRleCA9IHRoaXMuaXRlbXMuaW5kZXhPZihjaGlsZClcbiAgdGhpcy5pdGVtcy5zcGxpY2UoaW5kZXgsIDEpXG4gIHRoaXMubm9kZS5yZW1vdmVDaGlsZChjaGlsZC5ub2RlKVxuICB0aGlzLnJlc2V0KClcbn1cblxuLyoqXG4gKiBzdGF0dXM6IHtcbiAqICAgY3VycmVudDoge3RyYW5zbGF0ZVk6IDAsIHNob3duOiB0cnVlfSxcbiAqICAgbmV4dDoge3RyYW5zbGF0ZVk6IGhlaWdodCwgc2hvd246IHRydWV9LFxuICogICBvdGhlcnNbXToge3Nob3duOiBmYWxzZX1cbiAqICAgaW5kZXg6IGluZGV4XG4gKiB9XG4gKi9cbk1hcnF1ZWUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaW50ZXJ2YWwgPSB0aGlzLmludGVydmFsIC0gMFxuICB2YXIgZGVsYXkgPSB0aGlzLmRlbGF5IC0gMFxuICB2YXIgaXRlbXMgPSB0aGlzLml0ZW1zXG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIHZhciBsb29wID0gZnVuY3Rpb24gKCkge1xuICAgIHNlbGYubmV4dCgpXG4gICAgc2VsZi50aW1lcklkID0gc2V0VGltZW91dChsb29wLCBzZWxmLmludGVydmFsKVxuICB9XG5cbiAgLy8gcmVzZXQgZGlzcGxheSBhbmQgdHJhbnNmb3JtXG4gIGl0ZW1zLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7XG4gICAgdmFyIG5vZGUgPSBpdGVtLm5vZGVcbiAgICAvLyBzZXQgbm9uLWN1cnJlbnQoMCl8bmV4dCgxKSBpdGVtIGhpZGRlblxuICAgIG5vZGUuc3R5bGUuZGlzcGxheSA9IGluZGV4ID4gMSA/ICdub25lJyA6ICcnXG4gICAgLy8gc2V0IG5leHQoMSkgaXRlbSB0cmFuc2xhdGVZXG4gICAgLy8gVE9ETzogaXQgc3VwcG9zZWQgdG8gdXNlIGl0ZW0uZGF0YS5zdHlsZVxuICAgIC8vIGJ1dCBzb21laG93IHRoZSBzdHlsZSBvYmplY3QgaXMgZW1wdHkuXG4gICAgLy8gVGhpcyBwcm9ibGVtIHJlbGllcyBvbiBqc2ZyYW1ld29yaydzIGJ1Z2ZpeC5cblxuICAgIC8vIG5vZGUuc3R5bGUudHJhbnNmb3JtID0gaW5kZXggPT09IDFcbiAgICAvLyAgICAgPyAndHJhbnNsYXRlM0QoMCwnICsgY29uZmlnLnNjYWxlICogaXRlbS5kYXRhLnN0eWxlLmhlaWdodCArICdweCwwKSdcbiAgICAvLyAgICAgOiAnJ1xuICAgIC8vIG5vZGUuc3R5bGUud2Via2l0VHJhbnNmb3JtID0gaW5kZXggPT09IDFcbiAgICAvLyAgICAgPyAndHJhbnNsYXRlM0QoMCwnICsgY29uZmlnLnNjYWxlICogaXRlbS5kYXRhLnN0eWxlLmhlaWdodCArICdweCwwKSdcbiAgICAvLyAgICAgOiAnJ1xuICAgIG5vZGUuc3R5bGUudHJhbnNmb3JtID0gaW5kZXggPT09IDFcbiAgICAgICAgPyAndHJhbnNsYXRlM0QoMCwnICsgc2VsZi5kYXRhLnNjYWxlICogc2VsZi5kYXRhLnN0eWxlLmhlaWdodCArICdweCwwKSdcbiAgICAgICAgOiAnJ1xuICAgIG5vZGUuc3R5bGUud2Via2l0VHJhbnNmb3JtID0gaW5kZXggPT09IDFcbiAgICAgICAgPyAndHJhbnNsYXRlM0QoMCwnICsgc2VsZi5kYXRhLnNjYWxlICogc2VsZi5kYXRhLnN0eWxlLmhlaWdodCArICdweCwwKSdcbiAgICAgICAgOiAnJ1xuICB9KVxuXG4gIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIC8vIHJlc2V0IGN1cnJlbnQsIG5leHQsIGluZGV4XG4gICAgc2VsZi5jdXJyZW50SXRlbSA9IGl0ZW1zWzBdXG4gICAgc2VsZi5uZXh0SXRlbSA9IGl0ZW1zWzFdXG4gICAgc2VsZi5jdXJyZW50SW5kZXggPSAwXG5cbiAgICBpdGVtcy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtLCBpbmRleCkge1xuICAgICAgdmFyIG5vZGUgPSBpdGVtLm5vZGVcbiAgICAgIC8vIHNldCB0cmFuc2l0aW9uXG4gICAgICBub2RlLnN0eWxlLnRyYW5zaXRpb24gPSAndHJhbnNmb3JtICdcbiAgICAgICAgICArIHNlbGYudHJhbnNpdGlvbkR1cmF0aW9uXG4gICAgICAgICAgKyAnbXMgZWFzZSdcbiAgICAgIG5vZGUuc3R5bGUud2Via2l0VHJhbnNpdGlvbiA9ICctd2Via2l0LXRyYW5zZm9ybSAnXG4gICAgICAgICAgKyBzZWxmLnRyYW5zaXRpb25EdXJhdGlvblxuICAgICAgICAgICsgJ21zIGVhc2UnXG4gICAgfSlcblxuICAgIGNsZWFyVGltZW91dChzZWxmLnRpbWVySWQpXG5cbiAgICBpZiAoaXRlbXMubGVuZ3RoID4gMSkge1xuICAgICAgc2VsZi50aW1lcklkID0gc2V0VGltZW91dChsb29wLCBkZWxheSArIGludGVydmFsKVxuICAgIH1cbiAgfSwgMTMpXG5cbn1cblxuLyoqXG4gKiBuZXh0OlxuICogLSBjdXJyZW50OiB7dHJhbnNsYXRlWTogLWhlaWdodH1cbiAqIC0gbmV4dDoge3RyYW5zbGF0ZVk6IDB9XG4gKi9cbk1hcnF1ZWUucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIC0gdXBkYXRlIHN0YXRlXG4gIC8vICAgLSBzZXQgY3VycmVudCBhbmQgbmV4dCB0cmFuc2l0aW9uXG4gIC8vICAgLSBoaWRlIGN1cnJlbnQgd2hlbiB0cmFuc2l0aW9uIGVuZFxuICAvLyAgIC0gc2V0IG5leHQgdG8gY3VycmVudFxuICAvLyAgIC0gZmluZCBuZXcgbmV4dFxuICB2YXIgbmV4dCA9IHRoaXMubmV4dEl0ZW0ubm9kZVxuICB2YXIgY3VycmVudCA9IHRoaXMuY3VycmVudEl0ZW0ubm9kZVxuICB0aGlzLnRyYW5zaXRpb25JbmRleCA9IHRoaXMuY3VycmVudEluZGV4XG5cbiAgLy8gVXNlIHNldFRpbWVvdXQgdG8gZml4IHRoZSBwcm9ibGVtIHRoYXQgd2hlbiB0aGVcbiAgLy8gcGFnZSByZWNvdmVyIGZyb20gYmFja3N0YWdlLCB0aGUgc2xpZGVyIHdpbGxcbiAgLy8gbm90IHdvcmsgYW55IGxvbmdlci5cbiAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgbmV4dC5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlM0QoMCwwLDApJ1xuICAgIG5leHQuc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3RyYW5zbGF0ZTNEKDAsMCwwKSdcbiAgICBjdXJyZW50LnN0eWxlLnRyYW5zZm9ybSA9ICd0cmFuc2xhdGUzRCgwLC0nXG4gICAgICAgICsgdGhpcy5kYXRhLnNjYWxlICogdGhpcy5kYXRhLnN0eWxlLmhlaWdodFxuICAgICAgICArICdweCwwKSdcbiAgICBjdXJyZW50LnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd0cmFuc2xhdGUzRCgwLC0nXG4gICAgICAgICsgdGhpcy5kYXRhLnNjYWxlICogdGhpcy5kYXRhLnN0eWxlLmhlaWdodFxuICAgICAgICArICdweCwwKSdcbiAgICB0aGlzLmZpcmVFdmVudCgnY2hhbmdlJylcbiAgfS5iaW5kKHRoaXMpLCAzMDApXG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLmZpcmVFdmVudCA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLml0ZW1zLmxlbmd0aFxuICB2YXIgbmV4dEluZGV4ID0gKHRoaXMuY3VycmVudEluZGV4ICsgMSkgJSBsZW5ndGhcbiAgdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJylcbiAgZXZ0LmluaXRFdmVudCh0eXBlLCBmYWxzZSwgZmFsc2UpXG4gIGV2dC5kYXRhID0ge1xuICAgIHByZXZJbmRleDogdGhpcy5jdXJyZW50SW5kZXgsXG4gICAgaW5kZXg6IG5leHRJbmRleFxuICB9XG4gIHRoaXMubm9kZS5kaXNwYXRjaEV2ZW50KGV2dClcbn1cblxuLyoqXG4gKiBlbmQ6XG4gKiAtIG9sZCBjdXJyZW50OiB7c2hvd246IGZhbHNlfVxuICogLSBvbGQgY3VycmVudDoge3RyYW5zbGF0ZVk6IDB9XG4gKiAtIGluZGV4KysgJSBsZW5ndGhcbiAqIC0gbmV3IGN1cnJlbnQgPSBvbGQgbmV4dFxuICogLSBuZXcgbmV4dCA9IGl0ZW1zW2luZGV4KzEgJSBsZW5ndGhdXG4gKiAtIG5ldyBuZXh0OiB7dHJhbnNsYXRlWTogaGVpZ2h0fVxuICogLSBuZXcgbmV4dDoge3Nob3duOiB0cnVlfVxuICovXG5NYXJxdWVlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoZSkge1xuICB2YXIgdGFyZ2V0ID0gZS50YXJnZXRcbiAgdmFyIGl0ZW1zID0gdGhpcy5pdGVtc1xuICB2YXIgbGVuZ3RoID0gaXRlbXMubGVuZ3RoXG4gIHZhciBjdXJyZW50LCBuZXh0XG4gIHZhciBjdXJyZW50SW5kZXgsIG5leHRJbmRleFxuXG4gIGN1cnJlbnRJbmRleCA9IHRoaXMudHJhbnNpdGlvbkluZGV4XG5cbiAgaWYgKGlzTmFOKGN1cnJlbnRJbmRleCkpIHtcbiAgICByZXR1cm5cbiAgfVxuICBkZWxldGUgdGhpcy50cmFuc2l0aW9uSW5kZXhcblxuICBjdXJyZW50ID0gdGhpcy5jdXJyZW50SXRlbS5ub2RlXG4gIGN1cnJlbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJ1xuICBjdXJyZW50LnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICcnXG5cbiAgY3VycmVudEluZGV4ID0gKGN1cnJlbnRJbmRleCArIDEpICUgbGVuZ3RoXG4gIG5leHRJbmRleCA9IChjdXJyZW50SW5kZXggKyAxKSAlIGxlbmd0aFxuXG4gIHRoaXMuY3VycmVudEluZGV4ID0gY3VycmVudEluZGV4XG4gIHRoaXMuY3VycmVudEl0ZW0gPSB0aGlzLm5leHRJdGVtXG4gIHRoaXMubmV4dEl0ZW0gPSBpdGVtc1tuZXh0SW5kZXhdXG5cbiAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgbmV4dCA9IHRoaXMubmV4dEl0ZW0ubm9kZVxuICAgIC8vIFRPRE86IGl0IHN1cHBvc2VkIHRvIHVzZSB0aGlzLm5leHRJdGVtLmRhdGEuc3R5bGVcbiAgICAvLyBidXQgc29tZWhvdyB0aGUgc3R5bGUgb2JqZWN0IGlzIGVtcHR5LlxuICAgIC8vIFRoaXMgcHJvYmxlbSByZWxpZXMgb24ganNmcmFtZXdvcmsncyBidWdmaXguXG5cbiAgICBuZXh0LnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICd0cmFuc2xhdGUzRCgwLCdcbiAgICAgICAgKyB0aGlzLmRhdGEuc2NhbGUgKiB0aGlzLmRhdGEuc3R5bGUuaGVpZ2h0XG4gICAgICAgICsgJ3B4LDApJ1xuICAgIG5leHQuc3R5bGUuZGlzcGxheSA9ICcnXG4gICAgTGF6eUxvYWQubG9hZElmTmVlZGVkKG5leHQpXG4gIH0uYmluZCh0aGlzKSlcbn1cblxuTWFycXVlZS5wcm90b3R5cGUuYXR0ciA9IHtcbiAgaW50ZXJ2YWw6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuaW50ZXJ2YWwgPSB2YWx1ZVxuICB9LFxuICB0cmFuc2l0aW9uRHVyYXRpb246IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMudHJhbnNpdGlvbkR1cmF0aW9uID0gdmFsdWVcbiAgfSxcbiAgZGVsYXk6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHRoaXMuZGVsYXkgPSB2YWx1ZVxuICB9XG59XG5cbk1hcnF1ZWUucHJvdG90eXBlLmNsZWFyQXR0ciA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5pbnRlcnZhbCA9IDUgKiAxMDAwXG4gIHRoaXMudHJhbnNpdGlvbkR1cmF0aW9uID0gNTAwXG4gIHRoaXMuZGVsYXkgPSAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gTWFycXVlZVxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL21hcnF1ZWUuanNcbiAqKiBtb2R1bGUgaWQgPSAzOVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBleHRlbmQgPSByZXF1aXJlKCcuLi91dGlscycpLmV4dGVuZFxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxudmFyIENvbXBvbmVudE1hbmFnZXIgPSByZXF1aXJlKCcuLi9jb21wb25lbnRNYW5hZ2VyJylcbnZhciBMYXp5TG9hZCA9IHJlcXVpcmUoJy4uL2xhenlMb2FkJylcbnJlcXVpcmUoJ2NhcnJvdXNlbCcpXG5yZXF1aXJlKCcuLi9zdHlsZXMvc2xpZGVyLnNjc3MnKVxuXG5mdW5jdGlvbiBTbGlkZXIgKGRhdGEpIHtcbiAgdGhpcy5hdXRvUGxheSA9IHRydWUgIC8vIGFsd2F5cyB0cnVlIGZvciBhdXRvcGxheVxuICB0aGlzLmRpcmVjdGlvbiA9ICdyb3cnIC8vICdjb2x1bW4nIGlzIG5vdCB0ZW1wb3JhcmlseSBzdXBwb3J0ZWQuXG4gIHRoaXMuY2hpbGRyZW4gPSBbXVxuICB0aGlzLmlzUGFnZVNob3cgPSB0cnVlXG4gIHRoaXMuaXNEb21SZW5kZXJpbmcgPSB0cnVlXG5cbiAgLy8gYmluZCBldmVudCAncGFnZXNob3cnIGFuZCAncGFnZWhpZGUnIG9uIHdpbmRvdy5cbiAgdGhpcy5faWRsZVdoZW5QYWdlRGlzYXBwZWFyKClcbiAgLy8gYmluZCBldmVudCAncmVuZGVyQmVnaW4nIGFuZCAncmVuZGVyRW5kJyBvbiB3aW5kb3cuXG4gIHRoaXMuX2lkbGVXaGVuRG9tUmVuZGVyaW5nKClcblxuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5TbGlkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDb21wb25lbnQucHJvdG90eXBlKVxuXG5TbGlkZXIucHJvdG90eXBlLl9pZGxlV2hlblBhZ2VEaXNhcHBlYXIgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXNcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BhZ2VzaG93JywgZnVuY3Rpb24gKCkge1xuICAgIF90aGlzLmlzUGFnZVNob3cgPSB0cnVlXG4gICAgX3RoaXMuYXV0b1BsYXkgJiYgIV90aGlzLmlzRG9tUmVuZGVyaW5nICYmIF90aGlzLnBsYXkoKVxuICB9KVxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncGFnZWhpZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgX3RoaXMuaXNQYWdlU2hvdyA9IGZhbHNlXG4gICAgX3RoaXMuc3RvcCgpXG4gIH0pXG59XG5cblNsaWRlci5wcm90b3R5cGUuX2lkbGVXaGVuRG9tUmVuZGVyaW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgX3RoaXMgPSB0aGlzXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZW5kZXJlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgX3RoaXMuaXNEb21SZW5kZXJpbmcgPSBmYWxzZVxuICAgIF90aGlzLmF1dG9QbGF5ICYmIF90aGlzLmlzUGFnZVNob3cgJiYgX3RoaXMucGxheSgpXG4gIH0pXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZW5kZXJiZWdpbicsIGZ1bmN0aW9uICgpIHtcbiAgICBfdGhpcy5pc0RvbVJlbmRlcmluZyA9IHRydWVcbiAgICBfdGhpcy5zdG9wKClcbiAgfSlcbn1cblxuU2xpZGVyLnByb3RvdHlwZS5hdHRyID0ge1xuICBpbnRlcnZhbDogZnVuY3Rpb24gKHZhbCkge1xuICAgIHRoaXMuaW50ZXJ2YWwgPSBwYXJzZUludCh2YWwpIHx8IDMwMDBcbiAgICBpZiAodGhpcy5jYXJyb3VzZWwpIHtcbiAgICAgIHRoaXMuY2Fycm91c2VsLnBsYXlJbnRlcnZhbCA9IHRoaXMuaW50ZXJ2YWxcbiAgICB9XG4gIH0sXG5cbiAgcGxheXN0YXR1czogZnVuY3Rpb24gKHZhbCkge1xuICAgIHRoaXMucGxheXN0YXR1cyA9IHZhbCAmJiB2YWwgIT09ICdmYWxzZScgPyB0cnVlIDogZmFsc2VcbiAgICB0aGlzLmF1dG9QbGF5ID0gdGhpcy5wbGF5c3RhdHVzXG4gICAgaWYgKHRoaXMuY2Fycm91c2VsKSB7XG4gICAgICBpZiAodGhpcy5wbGF5c3RhdHVzKSB7XG4gICAgICAgIHRoaXMucGxheSgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnN0b3AoKVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvLyBzdXBwb3J0IHBsYXlzdGF0dXMnIGFsaWFzIGF1dG8tcGxheSBmb3IgY29tcGF0aWJpbGl0eVxuICBhdXRvUGxheTogZnVuY3Rpb24gKHZhbCkge1xuICAgIHRoaXMuYXR0ci5wbGF5c3RhdHVzLmNhbGwodGhpcywgdmFsKVxuICB9XG59XG5cblNsaWRlci5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnc2xpZGVyJylcbiAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSdcbiAgbm9kZS5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nXG4gIHJldHVybiBub2RlXG59XG5cblNsaWRlci5wcm90b3R5cGUuX2RvUmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICB2YXIgX3RoaXMgPSB0aGlzXG4gIF90aGlzLmNyZWF0ZUNoaWxkcmVuKClcbiAgX3RoaXMub25BcHBlbmQoKVxufVxuXG5TbGlkZXIucHJvdG90eXBlLnJlbW92ZUNoaWxkID0gZnVuY3Rpb24gKGNoaWxkKSB7XG4gIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICBpZiAoY2hpbGRyZW4pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoY2hpbGQuZGF0YS5yZWYgPT09IGNoaWxkcmVuW2ldLnJlZikge1xuICAgICAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMSlcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aGlzLl9kb1JlbmRlcigpXG59XG5cblNsaWRlci5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIC8vIHZhciBjaGlsZEluZGV4ID0gdGhpcy5jaGlsZHJlbi5pbmRleE9mKGJlZm9yZS5kYXRhKVxuICB2YXIgY2hpbGRJbmRleCA9IC0xXG4gIGZvciAodmFyIGkgPSAwLCBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKGNoaWxkcmVuW2ldLnJlZiA9PT0gYmVmb3JlLmRhdGEucmVmKSB7XG4gICAgICBjaGlsZEluZGV4ID0gaVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgY2hpbGRyZW4uc3BsaWNlKGNoaWxkSW5kZXgsIDAsIGNoaWxkLmRhdGEpXG5cbiAgdGhpcy5fZG9SZW5kZXIoKVxuICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxXVxuICB9XG59XG5cblNsaWRlci5wcm90b3R5cGUuYXBwZW5kQ2hpbGQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB2YXIgY2hpbGRyZW4gPSB0aGlzLmRhdGEuY2hpbGRyZW4gfHwgKHRoaXMuZGF0YS5jaGlsZHJlbiA9IFtdKVxuICBjaGlsZHJlbi5wdXNoKGRhdGEpXG4gIHRoaXMuX2RvUmVuZGVyKClcbiAgaWYgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiB0aGlzLmNoaWxkcmVuW3RoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMV1cbiAgfVxufVxuXG5TbGlkZXIucHJvdG90eXBlLmNyZWF0ZUNoaWxkcmVuID0gZnVuY3Rpb24gKCkge1xuXG4gIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcblxuICAvLyByZWNyZWF0ZSBzbGlkZXIgY29udGFpbmVyLlxuICBpZiAodGhpcy5zbGlkZXJDb250YWluZXIpIHtcbiAgICB0aGlzLm5vZGUucmVtb3ZlQ2hpbGQodGhpcy5zbGlkZXJDb250YWluZXIpXG4gIH1cbiAgaWYgKHRoaXMuaW5kaWNhdG9yKSB7XG4gICAgdGhpcy5pbmRpY2F0b3Iubm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuaW5kaWNhdG9yLm5vZGUpXG4gIH1cbiAgdGhpcy5jaGlsZHJlbiA9IFtdXG5cbiAgdmFyIHNsaWRlckNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3VsJylcbiAgc2xpZGVyQ29udGFpbmVyLnN0eWxlLmxpc3RTdHlsZSA9ICdub25lJ1xuICB0aGlzLm5vZGUuYXBwZW5kQ2hpbGQoc2xpZGVyQ29udGFpbmVyKVxuICB0aGlzLnNsaWRlckNvbnRhaW5lciA9IHNsaWRlckNvbnRhaW5lclxuXG4gIHZhciBjaGlsZHJlbiA9IHRoaXMuZGF0YS5jaGlsZHJlblxuICB2YXIgc2NhbGUgPSB0aGlzLmRhdGEuc2NhbGVcbiAgdmFyIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpXG4gIHZhciBpbmRpY2F0b3JEYXRhLCB3aWR0aCwgaGVpZ2h0XG4gIHZhciBjaGlsZFdpZHRoID0gMFxuICB2YXIgY2hpbGRIZWlnaHQgPSAwXG5cbiAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjaGlsZFxuICAgICAgY2hpbGRyZW5baV0uc2NhbGUgPSB0aGlzLmRhdGEuc2NhbGVcbiAgICAgIGNoaWxkcmVuW2ldLmluc3RhbmNlSWQgPSB0aGlzLmRhdGEuaW5zdGFuY2VJZFxuICAgICAgaWYgKGNoaWxkcmVuW2ldLnR5cGUgPT09ICdpbmRpY2F0b3InKSB7XG4gICAgICAgIGluZGljYXRvckRhdGEgPSBleHRlbmQoY2hpbGRyZW5baV0sIHtcbiAgICAgICAgICBleHRyYToge1xuICAgICAgICAgICAgYW1vdW50OiBjaGlsZHJlbi5sZW5ndGggLSAxLFxuICAgICAgICAgICAgaW5kZXg6IDBcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGlsZCA9IGNvbXBvbmVudE1hbmFnZXIuY3JlYXRlRWxlbWVudChjaGlsZHJlbltpXSwgJ2xpJylcbiAgICAgICAgdGhpcy5jaGlsZHJlbi5wdXNoKGNoaWxkKVxuICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuICAgICAgICB3aWR0aCA9IGNoaWxkLmRhdGEuc3R5bGUud2lkdGggfHwgMFxuICAgICAgICBoZWlnaHQgPSBjaGlsZC5kYXRhLnN0eWxlLmhlaWdodCB8fCAwXG4gICAgICAgIHdpZHRoID4gY2hpbGRXaWR0aCAmJiAoY2hpbGRXaWR0aCA9IHdpZHRoKVxuICAgICAgICBoZWlnaHQgPiBjaGlsZEhlaWdodCAmJiAoY2hpbGRIZWlnaHQgPSBoZWlnaHQpXG4gICAgICAgIGNoaWxkLnBhcmVudFJlZiA9IHRoaXMuZGF0YS5yZWZcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gYXBwZW5kIGluZGljYXRvclxuICAgIGlmIChpbmRpY2F0b3JEYXRhKSB7XG4gICAgICBpbmRpY2F0b3JEYXRhLmV4dHJhLndpZHRoID0gdGhpcy5kYXRhLnN0eWxlLndpZHRoIHx8IGNoaWxkV2lkdGhcbiAgICAgIGluZGljYXRvckRhdGEuZXh0cmEuaGVpZ2h0ID0gdGhpcy5kYXRhLnN0eWxlLmhlaWdodCB8fCBjaGlsZEhlaWdodFxuICAgICAgdGhpcy5pbmRpY2F0b3IgPSBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUVsZW1lbnQoaW5kaWNhdG9yRGF0YSlcbiAgICAgIHRoaXMuaW5kaWNhdG9yLnBhcmVudFJlZiA9IHRoaXMuZGF0YS5yZWZcbiAgICAgIHRoaXMuaW5kaWNhdG9yLnNsaWRlciA9IHRoaXNcbiAgICAgIHRoaXMubm9kZS5hcHBlbmRDaGlsZCh0aGlzLmluZGljYXRvci5ub2RlKVxuICAgIH1cblxuICAgIHNsaWRlckNvbnRhaW5lci5zdHlsZS5oZWlnaHQgPSBzY2FsZSAqIHRoaXMuZGF0YS5zdHlsZS5oZWlnaHQgKyAncHgnXG4gICAgc2xpZGVyQ29udGFpbmVyLmFwcGVuZENoaWxkKGZyYWdtZW50KVxuICB9XG59XG5cblNsaWRlci5wcm90b3R5cGUub25BcHBlbmQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhcnJvdXNlbCkge1xuICAgIHRoaXMuY2Fycm91c2VsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuX2dldFNsaWRlckNoYW5nZUhhbmRsZXIoKSlcbiAgICB0aGlzLmNhcnJvdXNlbC5zdG9wKClcbiAgICB0aGlzLmNhcnJvdXNlbCA9IG51bGxcbiAgfVxuICB0aGlzLmNhcnJvdXNlbCA9IG5ldyBsaWIuY2Fycm91c2VsKHRoaXMuc2xpZGVyQ29udGFpbmVyLCB7XG4gICAgYXV0b3BsYXk6IHRoaXMuYXV0b1BsYXksXG4gICAgdXNlR2VzdHVyZTogdHJ1ZVxuICB9KVxuXG4gIHRoaXMuY2Fycm91c2VsLnBsYXlJbnRlcnZhbCA9IHRoaXMuaW50ZXJ2YWxcbiAgdGhpcy5jYXJyb3VzZWwuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5fZ2V0U2xpZGVyQ2hhbmdlSGFuZGxlcigpKVxuICB0aGlzLmN1cnJlbnRJbmRleCA9IDBcblxuICAvLyBwcmVsb2FkIGFsbCBpbWFnZXMgZm9yIHNsaWRlclxuICAvLyBiZWNhdXNlOlxuICAvLyAxLiBsaWItaW1nIGRvZXNuJ3QgbGlzdGVuIHRvIGV2ZW50IHRyYW5zaXRpb25lbmRcbiAgLy8gMi4gZXZlbiBpZiB3ZSBmaXJlIGxhenkgbG9hZCBpbiBzbGlkZXIncyBjaGFuZ2UgZXZlbnQgaGFuZGxlcixcbiAgLy8gICAgdGhlIG5leHQgaW1hZ2Ugc3RpbGwgd29uJ3QgYmUgcHJlbG9hZGVkIHV0aWxsIHRoZSBtb21lbnQgaXRcbiAgLy8gICAgc2xpZGVzIGludG8gdGhlIHZpZXcsIHdoaWNoIGlzIHRvbyBsYXRlLlxuICBpZiAodGhpcy5wcmVsb2FkSW1nc1RpbWVyKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucHJlbG9hZEltZ3NUaW1lcilcbiAgfVxuICAvLyBUaGUgdGltZSBqdXN0IGJlZm9yZSB0aGUgc2Vjb25kIHNsaWRlIGFwcGVhciBhbmQgZW5vdWdoXG4gIC8vIGZvciBhbGwgY2hpbGQgZWxlbWVudHMgdG8gYXBwZW5kIGlzIG9rLlxuICB2YXIgcHJlbG9hZFRpbWUgPSAwLjhcbiAgdGhpcy5wcmVsb2FkSW1nc1RpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGltZ3MgPSB0aGlzLmNhcnJvdXNlbC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2ltZycpXG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBpbWdzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdmFyIGltZyA9IGltZ3NbaV1cbiAgICAgIHZhciBpTGF6eVNyYyA9IGltZy5nZXRBdHRyaWJ1dGUoJ2ktbGF6eS1zcmMnKVxuICAgICAgdmFyIGltZ1NyYyA9IGltZy5nZXRBdHRyaWJ1dGUoJ2ltZy1zcmMnKVxuICAgICAgaWYgKGlMYXp5U3JjKSB7XG4gICAgICAgIGltZy5zZXRBdHRyaWJ1dGUoJ3NyYycsIGlMYXp5U3JjKVxuICAgICAgfSBlbHNlIGlmIChpbWdTcmMpIHtcbiAgICAgICAgaW1nLnNldEF0dHJpYnV0ZSgnc3JjJywgaW1nU3JjKVxuICAgICAgfVxuICAgICAgaW1nLnJlbW92ZUF0dHJpYnV0ZSgnaS1sYXp5LXNyYycpXG4gICAgICBpbWcucmVtb3ZlQXR0cmlidXRlKCdpbWctc3JjJylcbiAgICB9XG4gIH0uYmluZCh0aGlzKSwgcHJlbG9hZFRpbWUgKiAxMDAwKVxuXG4gIC8vIGF2b2lkIHBhZ2Ugc2Nyb2xsIHdoZW4gcGFubmluZ1xuICB2YXIgcGFubmluZyA9IGZhbHNlXG4gIHRoaXMuY2Fycm91c2VsLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncGFuc3RhcnQnLCBmdW5jdGlvbiAoZSkge1xuICAgIGlmICghZS5pc1ZlcnRpY2FsKSB7XG4gICAgICBwYW5uaW5nID0gdHJ1ZVxuICAgIH1cbiAgfSlcbiAgdGhpcy5jYXJyb3VzZWwuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdwYW5lbmQnLCBmdW5jdGlvbiAoZSkge1xuICAgIGlmICghZS5pc1ZlcnRpY2FsKSB7XG4gICAgICBwYW5uaW5nID0gZmFsc2VcbiAgICB9XG4gIH0pXG5cbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAocGFubmluZykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgcmV0dXJuIHRydWVcbiAgfS5iaW5kKHRoaXMpKVxuXG59XG5cblNsaWRlci5wcm90b3R5cGUuX3VwZGF0ZUluZGljYXRvcnMgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuaW5kaWNhdG9yICYmIHRoaXMuaW5kaWNhdG9yLnNldEluZGV4KHRoaXMuY3VycmVudEluZGV4KVxufVxuXG5TbGlkZXIucHJvdG90eXBlLl9nZXRTbGlkZXJDaGFuZ2VIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgaWYgKCF0aGlzLnNsaWRlckNoYW5nZUhhbmRsZXIpIHtcbiAgICB0aGlzLnNsaWRlckNoYW5nZUhhbmRsZXIgPSAoZnVuY3Rpb24gKGUpIHtcbiAgICAgIHZhciBpbmRleCA9IHRoaXMuY2Fycm91c2VsLml0ZW1zLmluZGV4XG4gICAgICB0aGlzLmN1cnJlbnRJbmRleCA9IGluZGV4XG5cbiAgICAgIC8vIHVwZGF0ZUluZGljYXRvcnNcbiAgICAgIHRoaXMuX3VwZGF0ZUluZGljYXRvcnMoKVxuXG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ2NoYW5nZScsIHsgaW5kZXg6IGluZGV4IH0pXG4gICAgfSkuYmluZCh0aGlzKVxuICB9XG4gIHJldHVybiB0aGlzLnNsaWRlckNoYW5nZUhhbmRsZXJcbn1cblxuU2xpZGVyLnByb3RvdHlwZS5wbGF5ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNhcnJvdXNlbC5wbGF5KClcbn1cblxuU2xpZGVyLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNhcnJvdXNlbC5zdG9wKClcbn1cblxuU2xpZGVyLnByb3RvdHlwZS5zbGlkZVRvID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gIHZhciBvZmZzZXQgPSBpbmRleCAtIHRoaXMuY3VycmVudEluZGV4XG4gIHRoaXMuY2Fycm91c2VsLml0ZW1zLnNsaWRlKG9mZnNldClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTbGlkZXJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9zbGlkZXIuanNcbiAqKiBtb2R1bGUgaWQgPSA0MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSAmJiAod2luZG93ID0ge2N0cmw6IHt9LCBsaWI6IHt9fSk7IXdpbmRvdy5jdHJsICYmICh3aW5kb3cuY3RybCA9IHt9KTshd2luZG93LmxpYiAmJiAod2luZG93LmxpYiA9IHt9KTtyZXF1aXJlKCdhbmltYXRpb25qcycpO3JlcXVpcmUoJ2N1YmljYmV6aWVyJyk7cmVxdWlyZSgnZ2VzdHVyZWpzJyk7IWZ1bmN0aW9uKCl7dmFyIGE9XCJbZGF0YS1jdHJsLW5hbWU9Y2Fycm91c2VsXXtwb3NpdGlvbjpyZWxhdGl2ZTstd2Via2l0LXRyYW5zZm9ybTp0cmFuc2xhdGVaKDFweCk7LW1zLXRyYW5zZm9ybTp0cmFuc2xhdGVaKDFweCk7dHJhbnNmb3JtOnRyYW5zbGF0ZVooMXB4KX1cIixiPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtpZihkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQoYiksYi5zdHlsZVNoZWV0KWIuc3R5bGVTaGVldC5kaXNhYmxlZHx8KGIuc3R5bGVTaGVldC5jc3NUZXh0PWEpO2Vsc2UgdHJ5e2IuaW5uZXJIVE1MPWF9Y2F0Y2goYyl7Yi5pbm5lclRleHQ9YX19KCk7IWZ1bmN0aW9uKGEsYixjKXtmdW5jdGlvbiBkKGEpe3ZhciBiLGM9e3g6MCx5OjB9LGQ9Z2V0Q29tcHV0ZWRTdHlsZShhKVtsK1wiVHJhbnNmb3JtXCJdO3JldHVyblwibm9uZVwiIT09ZCYmKGI9ZC5tYXRjaCgvXm1hdHJpeDNkXFwoKD86Wy1cXGQuXSssXFxzKil7MTJ9KFstXFxkLl0rKSxcXHMqKFstXFxkLl0rKSg/OixcXHMqWy1cXGQuXSspezJ9XFwpLyl8fGQubWF0Y2goL15tYXRyaXhcXCgoPzpbLVxcZC5dKyxcXHMqKXs0fShbLVxcZC5dKyksXFxzKihbLVxcZC5dKylcXCkkLykpJiYoYy54PXBhcnNlRmxvYXQoYlsxXSl8fDAsYy55PXBhcnNlRmxvYXQoYlsyXSl8fDApLGN9ZnVuY3Rpb24gZShhLGIpe3JldHVybiBhPXBhcnNlRmxvYXQoYSksYj1wYXJzZUZsb2F0KGIpLDAhPWEmJihhKz1cInB4XCIpLDAhPWImJihiKz1cInB4XCIpLG4/XCJ0cmFuc2xhdGUzZChcIithK1wiLCBcIitiK1wiLCAwKVwiOlwidHJhbnNsYXRlKFwiK2ErXCIsIFwiK2IrXCIpXCJ9ZnVuY3Rpb24gZihhKXtyZXR1cm4gby5jYWxsKGEpfWZ1bmN0aW9uIGcoYSxjKXtmdW5jdGlvbiBnKGEsYil7dmFyIGM9aC5jcmVhdGVFdmVudChcIkhUTUxFdmVudHNcIik7aWYoYy5pbml0RXZlbnQoYSwhMSwhMSksYilmb3IodmFyIGQgaW4gYiljW2RdPWJbZF07bi5kaXNwYXRjaEV2ZW50KGMpfWZ1bmN0aW9uIGkoYSl7Zm9yKDswPmE7KWErPXI7Zm9yKDthPj1yOylhLT1yO3JldHVybiBhfWZ1bmN0aW9uIGooYSl7aWYoMCE9PXIpe3ZhciBiLGMsZD1xLmdldChhKTtyPjEmJihiPXEuZ2V0KGEtMSksYz0yPT09cj9xLmdldENsb25lZChhKzEpOnEuZ2V0KGErMSksZC5zdHlsZS5sZWZ0PS1vK1wicHhcIixiLnN0eWxlLmxlZnQ9LW8tcytcInB4XCIsYy5zdHlsZS5sZWZ0PS1vK3MrXCJweFwiKSx0PWQuaW5kZXgsZyhcImNoYW5nZVwiLHtwcmV2SXRlbTpiLGN1ckl0ZW06ZCxuZXh0SXRlbTpjfSl9fXZhciBrPXRoaXMsbT1EYXRlLm5vdygpK1wiLVwiKyArK3Asbj1kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7MSE9PWFyZ3VtZW50cy5sZW5ndGh8fGFyZ3VtZW50c1swXWluc3RhbmNlb2YgSFRNTEVsZW1lbnR8fChjPWFyZ3VtZW50c1swXSxhPW51bGwpLGF8fChhPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ1bFwiKSxuLmFwcGVuZENoaWxkKGEpKSxjPWN8fHt9LGEuc2V0QXR0cmlidXRlKFwiZGF0YS1jdHJsLW5hbWVcIixcImNhcnJvdXNlbFwiKSxhLnNldEF0dHJpYnV0ZShcImRhdGEtY3RybC1pZFwiLG0pLGEuc3R5bGUucG9zaXRpb249XCJyZWxhdGl2ZVwiLGEuc3R5bGVbbCtcIlRyYW5zZm9ybVwiXT1lKDAsMCk7dmFyIG89MCxxPXt9LHI9MCxzPWMuc3RlcHx8YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCx0PTA7cS5hZGQ9ZnVuY3Rpb24oYil7dmFyIGM9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpXCIpO3JldHVybiBjLnN0eWxlLmRpc3BsYXk9XCJub25lXCIsYy5zdHlsZVtcImZsb2F0XCJdPVwibGVmdFwiLGMuaW5kZXg9cixcInN0cmluZ1wiPT10eXBlb2YgYj9jLmlubmVySFRNTD1iOmIgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCYmYy5hcHBlbmRDaGlsZChiKSxhLmFwcGVuZENoaWxkKGMpLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShxLHIrXCJcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIGN9fSkscisrLGN9LHEuZ2V0PWZ1bmN0aW9uKGEpe3JldHVybiBxW2koYSldfSxxLmdldENsb25lZD1mdW5jdGlvbihiKXtmdW5jdGlvbiBjKGEsYixkKXt2YXIgZT1hLl9saXN0ZW5lcnM7aWYoZSl7Yi5fbGlzdGVuZXJzPWU7Zm9yKHZhciBmIGluIGUpYi5hZGRFdmVudExpc3RlbmVyKGYsZVtmXSl9aWYoZCYmYS5jaGlsZHJlbiYmYS5jaGlsZHJlbi5sZW5ndGgpZm9yKHZhciBnPTAsaD1hLmNoaWxkcmVuLmxlbmd0aDtoPmc7ZysrKWMoYS5jaGlsZHJlbltnXSxiLmNoaWxkcmVuW2ddLGQpfXZhciBiPWkoYiksZD1hLnF1ZXJ5U2VsZWN0b3IoJ1tjbG9uZWQ9XCJjbG9uZWQtJytiKydcIl0nKSxlPXFbYl07cmV0dXJuIGR8fChkPWUuY2xvbmVOb2RlKCEwKSxjKGUsZCwhMCksYS5hcHBlbmRDaGlsZChkKSxkLnNldEF0dHJpYnV0ZShcImNsb25lZFwiLFwiY2xvbmVkLVwiK2IpLGQuaW5kZXg9YiksZH0scS5zbGlkZT1mdW5jdGlvbihjKXtpZigwIT09cil7MT09PXImJihjPTApO3ZhciBmPWQoYSkueCxnPW8rcyotYyxoPWctZjtpZigwIT09aCl7bmV3IGIuYW5pbWF0aW9uKDQwMCxiLmN1YmljYmV6aWVyLmVhc2UsZnVuY3Rpb24oYixjKXthLnN0eWxlW2wrXCJUcmFuc2Zvcm1cIl09ZShmK2gqYywwKX0pLnBsYXkoKS50aGVuKGZ1bmN0aW9uKCl7bz1nLGEuc3R5bGVbbCtcIlRyYW5zZm9ybVwiXT1lKGcsMCksYyYmaih0K2MpfSl9fX0scS5uZXh0PWZ1bmN0aW9uKCl7cS5zbGlkZSgxKX0scS5wcmV2PWZ1bmN0aW9uKCl7cS5zbGlkZSgtMSl9LGYoYS5xdWVyeVNlbGVjdG9yQWxsKFwibGlcIikpLmZvckVhY2goZnVuY3Rpb24oYSl7YS5zdHlsZS5wb3NpdGlvbj1cImFic29sdXRlXCIsYS5zdHlsZS50b3A9XCIwXCIsYS5zdHlsZS5sZWZ0PXIqcytcInB4XCIsYS5zdHlsZVtcImZsb2F0XCJdPVwibGVmdFwiLGEuaW5kZXg9cixPYmplY3QuZGVmaW5lUHJvcGVydHkocSxyK1wiXCIse2dldDpmdW5jdGlvbigpe3JldHVybiBhfX0pLHIrK30pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLFwiaXRlbXNcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHF9fSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHEsXCJsZW5ndGhcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHJ9fSksT2JqZWN0LmRlZmluZVByb3BlcnR5KHEsXCJpbmRleFwiLHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdH19KSxPYmplY3QuZGVmaW5lUHJvcGVydHkocSxcInN0ZXBcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHN9LHNldDpmdW5jdGlvbihhKXtzPWF9fSk7dmFyIHU9ITEsdj0hMSx3PSExO3RoaXMucGxheT1mdW5jdGlvbigpe3JldHVybiB1P3ZvaWQodnx8KHY9c2V0VGltZW91dChmdW5jdGlvbigpe3c9ITAscS5uZXh0KCksc2V0VGltZW91dChmdW5jdGlvbigpe3c9ITF9LDUwMCksdj1zZXRUaW1lb3V0KGFyZ3VtZW50cy5jYWxsZWUsNDAwK3opfSw0MDAreikpKToodT0hMCxqKDApKX0sdGhpcy5zdG9wPWZ1bmN0aW9uKCl7diYmKGNsZWFyVGltZW91dCh2KSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dj0hMX0sNTAwKSl9O3ZhciB4PSExLHk9ITE7T2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsXCJhdXRvcGxheVwiLHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4geH0sc2V0OmZ1bmN0aW9uKGEpe3g9ISFhLHkmJihjbGVhclRpbWVvdXQoeSkseT0hMSkseD95PXNldFRpbWVvdXQoZnVuY3Rpb24oKXtrLnBsYXkoKX0sMmUzKTprLnN0b3AoKX19KSx0aGlzLmF1dG9wbGF5PSEhYy5hdXRvcGxheTt2YXIgej0xNTAwO2lmKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLFwicGxheUludGVydmFsXCIse2dldDpmdW5jdGlvbigpe3JldHVybiB6fSxzZXQ6ZnVuY3Rpb24oYSl7ej1hfX0pLHRoaXMucGxheUludGVydmFsPSEhYy5wbGF5SW50ZXJ2YWx8fDE1MDAsYy51c2VHZXN0dXJlKXt2YXIgQSxCPSExO2EuYWRkRXZlbnRMaXN0ZW5lcihcInBhbnN0YXJ0XCIsZnVuY3Rpb24oYSl7YS5pc1ZlcnRpY2FsfHxCJiZ3fHwoYS5wcmV2ZW50RGVmYXVsdCgpLGEuc3RvcFByb3BhZ2F0aW9uKCkseCYmay5zdG9wKCksQT0wLEI9ITApfSksYS5hZGRFdmVudExpc3RlbmVyKFwicGFubW92ZVwiLGZ1bmN0aW9uKGIpeyFiLmlzVmVydGljYWwmJkImJihiLnByZXZlbnREZWZhdWx0KCksYi5zdG9wUHJvcGFnYXRpb24oKSxBPWIuZGlzcGxhY2VtZW50WCxhLnN0eWxlW2wrXCJUcmFuc2Zvcm1cIl09ZShvK0EsMCkpfSksYS5hZGRFdmVudExpc3RlbmVyKFwicGFuZW5kXCIsZnVuY3Rpb24oYSl7IWEuaXNWZXJ0aWNhbCYmQiYmKGEucHJldmVudERlZmF1bHQoKSxhLnN0b3BQcm9wYWdhdGlvbigpLEI9ITEsYS5pc2ZsaWNrPzA+QT9xLm5leHQoKTpxLnByZXYoKTpNYXRoLmFicyhBKTxzLzI/cS5zbGlkZSgwKTpxLnNsaWRlKDA+QT8xOi0xKSx4JiZzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ay5wbGF5KCl9LDJlMykpfSwhMSksYS5hZGRFdmVudExpc3RlbmVyKFwic3dpcGVcIixmdW5jdGlvbihhKXthLmlzVmVydGljYWx8fChhLnByZXZlbnREZWZhdWx0KCksYS5zdG9wUHJvcGFnYXRpb24oKSl9KX10aGlzLmFkZEV2ZW50TGlzdGVuZXI9ZnVuY3Rpb24oYSxiKXt0aGlzLnJvb3QuYWRkRXZlbnRMaXN0ZW5lcihhLGIsITEpfSx0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXI9ZnVuY3Rpb24oYSxiKXt0aGlzLnJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lcihhLGIsITEpfSx0aGlzLnJvb3Q9bix0aGlzLmVsZW1lbnQ9YX12YXIgaD1hLmRvY3VtZW50LGk9YS5uYXZpZ2F0b3IudXNlckFnZW50LGo9ISFpLm1hdGNoKC9GaXJlZm94L2kpLGs9ISFpLm1hdGNoKC9JRU1vYmlsZS9pKSxsPWo/XCJNb3pcIjprP1wibXNcIjpcIndlYmtpdFwiLG09az9cIk1TQ1NTTWF0cml4XCI6XCJXZWJLaXRDU1NNYXRyaXhcIixuPSEhanx8bSBpbiBhJiZcIm0xMVwiaW4gbmV3IGFbbV0sbz1BcnJheS5wcm90b3R5cGUuc2xpY2UscD0wO2IuY2Fycm91c2VsPWd9KHdpbmRvdyx3aW5kb3cubGliLHdpbmRvdy5jdHJsfHwod2luZG93LmN0cmw9e30pKTs7bW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cubGliWydjYXJyb3VzZWwnXTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jYXJyb3VzZWwvYnVpbGQvY2Fycm91c2VsLmNvbW1vbi5qc1xuICoqIG1vZHVsZSBpZCA9IDQxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vc2xpZGVyLnNjc3NcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL25vZGVfbW9kdWxlcy9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9zbGlkZXIuc2Nzc1wiLCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vc2xpZGVyLnNjc3NcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvc3R5bGVzL3NsaWRlci5zY3NzXG4gKiogbW9kdWxlIGlkID0gNDJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiLnNsaWRlciB7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7IH1cXG5cXG4uc2xpZGVyIC5pbmRpY2F0b3ItY29udGFpbmVyIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGRpc3BsYXk6IC13ZWJraXQtYm94O1xcbiAgZGlzcGxheTogLXdlYmtpdC1mbGV4O1xcbiAgZGlzcGxheTogZmxleDtcXG4gIC13ZWJraXQtYm94LWFsaWduOiBjZW50ZXI7XFxuICBib3gtYWxpZ246IGNlbnRlcjtcXG4gIC13ZWJraXQtYWxpZ24taXRlbXM6IGNlbnRlcjtcXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxuICAtd2Via2l0LWJveC1wYWNrOiBjZW50ZXI7XFxuICBib3gtcGFjazogY2VudGVyO1xcbiAgLXdlYmtpdC1qdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcXG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xcbiAgZm9udC1zaXplOiAwOyB9XFxuICAuc2xpZGVyIC5pbmRpY2F0b3ItY29udGFpbmVyIC5pbmRpY2F0b3Ige1xcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7IH1cXG4gIC5zbGlkZXIgLmluZGljYXRvci1jb250YWluZXIucm93IHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICBib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7IH1cXG4gIC5zbGlkZXIgLmluZGljYXRvci1jb250YWluZXIuY29sdW1uIHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcXG4gICAgYm94LW9yaWVudDogdmVydGljYWw7XFxuICAgIC13ZWJraXQtZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9zbGlkZXIuc2Nzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtFQUNFLG1CQUFtQixFQUNwQjs7QUFDRDtFQUNFLG1CQUFtQjtFQUNuQixxQkFBcUI7RUFDckIsc0JBQXNCO0VBQ3RCLGNBQWM7RUFDZCwwQkFBMEI7RUFDMUIsa0JBQWtCO0VBQ2xCLDRCQUE0QjtFQUM1QixvQkFBb0I7RUFDcEIseUJBQXlCO0VBQ3pCLGlCQUFpQjtFQUNqQixnQ0FBZ0M7RUFDaEMsd0JBQXdCO0VBQ3hCLGFBQWEsRUFvQmQ7RUFqQ0Q7SUFnQkksbUJBQW1CLEVBQ3BCO0VBakJIO0lBb0JJLCtCQUErQjtJQUMvQix1QkFBdUI7SUFDdkIsNEJBQTRCO0lBQzVCLG9CQUFvQixFQUNyQjtFQXhCSDtJQTJCSSw2QkFBNkI7SUFDN0IscUJBQXFCO0lBQ3JCLCtCQUErQjtJQUMvQix1QkFBdUIsRUFDeEJcIixcImZpbGVcIjpcInNsaWRlci5zY3NzXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi5zbGlkZXIge1xcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcbn1cXG4uc2xpZGVyIC5pbmRpY2F0b3ItY29udGFpbmVyIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGRpc3BsYXk6IC13ZWJraXQtYm94O1xcbiAgZGlzcGxheTogLXdlYmtpdC1mbGV4O1xcbiAgZGlzcGxheTogZmxleDtcXG4gIC13ZWJraXQtYm94LWFsaWduOiBjZW50ZXI7XFxuICBib3gtYWxpZ246IGNlbnRlcjtcXG4gIC13ZWJraXQtYWxpZ24taXRlbXM6IGNlbnRlcjtcXG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XFxuICAtd2Via2l0LWJveC1wYWNrOiBjZW50ZXI7XFxuICBib3gtcGFjazogY2VudGVyO1xcbiAgLXdlYmtpdC1qdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcXG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xcbiAgZm9udC1zaXplOiAwO1xcblxcbiAgLmluZGljYXRvciB7XFxuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcXG4gIH1cXG5cXG4gICYucm93IHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICBib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICB9XFxuXFxuICAmLmNvbHVtbiB7XFxuICAgIC13ZWJraXQtYm94LW9yaWVudDogdmVydGljYWw7XFxuICAgIGJveC1vcmllbnQ6IHZlcnRpY2FsO1xcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XFxuICB9XFxuXFxufVwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Nhc3MtbG9hZGVyP3NvdXJjZU1hcCEuL3NyYy9zdHlsZXMvc2xpZGVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA0M1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBleHRlbmQgPSByZXF1aXJlKCcuLi91dGlscycpLmV4dGVuZFxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG52YXIgQXRvbWljID0gcmVxdWlyZSgnLi9hdG9taWMnKVxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcblxucmVxdWlyZSgnLi4vc3R5bGVzL2luZGljYXRvci5zY3NzJylcblxudmFyIERFRkFVTFRfSVRFTV9DT0xPUiA9ICcjOTk5J1xudmFyIERFRkFVTFRfSVRFTV9TRUxFQ1RFRF9DT0xPUiA9ICcjMDAwMGZmJ1xudmFyIERFRkFVTFRfSVRFTV9TSVpFID0gMjBcbnZhciBERUZBVUxUX01BUkdJTl9TSVpFID0gMTBcblxuLy8gU3R5bGUgc3VwcG9ydGVkOlxuLy8gICBwb3NpdGlvbjogKGRlZmF1bHQgLSBhYnNvbHV0ZSlcbi8vICAgaXRlbUNvbG9yOiBjb2xvciBvZiBpbmRpY2F0b3IgZG90c1xuLy8gICBpdGVtU2VsZWN0ZWRDb2xvcjogY29sb3Igb2YgdGhlIHNlbGVjdGVkIGluZGljYXRvciBkb3Rcbi8vICAgaXRlbVNpemU6IHNpemUgb2YgaW5kaWNhdG9yc1xuLy8gICBvdGhlciBsYXlvdXQgc3R5bGVzXG5mdW5jdGlvbiBJbmRpY2F0b3IgKGRhdGEpIHtcbiAgdGhpcy5kaXJlY3Rpb24gPSAncm93JyAvLyAnY29sdW1uJyBpcyBub3QgdGVtcG9yYXJpbHkgc3VwcG9ydGVkLlxuICB0aGlzLmFtb3VudCA9IGRhdGEuZXh0cmEuYW1vdW50XG4gIHRoaXMuaW5kZXggPSBkYXRhLmV4dHJhLmluZGV4XG4gIHRoaXMuc2xpZGVyV2lkdGggPSBkYXRhLmV4dHJhLndpZHRoXG4gIHRoaXMuc2xpZGVySGVpZ2h0ID0gZGF0YS5leHRyYS5oZWlnaHRcbiAgdmFyIHN0eWxlcyA9IGRhdGEuc3R5bGUgfHwge31cbiAgdGhpcy5kYXRhID0gZGF0YVxuICB0aGlzLnN0eWxlLndpZHRoLmNhbGwodGhpcywgc3R5bGVzLndpZHRoKVxuICB0aGlzLnN0eWxlLmhlaWdodC5jYWxsKHRoaXMsIHN0eWxlcy5oZWlnaHQpXG4gIHRoaXMuaXRlbXMgPSBbXVxuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5JbmRpY2F0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5JbmRpY2F0b3IucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtaW5kaWNhdG9ycycpXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1lbGVtZW50JylcbiAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSdcbiAgdGhpcy5ub2RlID0gbm9kZVxuICB0aGlzLnN0eWxlLml0ZW1TaXplLmNhbGwodGhpcywgMClcbiAgdGhpcy5pdGVtQ29sb3IgPSBERUZBVUxUX0lURU1fQ09MT1JcbiAgdGhpcy5pdGVtU2VsZWN0ZWRDb2xvciA9IERFRkFVTFRfSVRFTV9TRUxFQ1RFRF9DT0xPUlxuICB0aGlzLnVwZGF0ZVN0eWxlKHtcbiAgICBsZWZ0OiAwLFxuICAgIHRvcDogMCxcbiAgICBpdGVtU2l6ZTogMFxuICB9KVxuICByZXR1cm4gbm9kZVxufVxuXG5JbmRpY2F0b3IucHJvdG90eXBlLmNyZWF0ZUNoaWxkcmVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgcm9vdCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYW1vdW50OyBpKyspIHtcbiAgICB2YXIgaW5kaWNhdG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICBpbmRpY2F0b3IuY2xhc3NMaXN0LmFkZCgnd2VleC1pbmRpY2F0b3InKVxuICAgIGluZGljYXRvci5zdHlsZS5ib3hTaXppbmcgPSAnYm9yZGVyLWJveCdcbiAgICBpbmRpY2F0b3Iuc3R5bGUubWFyZ2luID0gJzAgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKERFRkFVTFRfTUFSR0lOX1NJWkUgKiB0aGlzLmRhdGEuc2NhbGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAncHgnXG4gICAgaW5kaWNhdG9yLnN0eWxlLndpZHRoID0gdGhpcy5pdGVtU2l6ZSArICdweCdcbiAgICBpbmRpY2F0b3Iuc3R5bGUuaGVpZ2h0ID0gdGhpcy5pdGVtU2l6ZSArICdweCdcbiAgICBpbmRpY2F0b3Iuc2V0QXR0cmlidXRlKCdpbmRleCcsIGkpXG4gICAgaWYgKHRoaXMuaW5kZXggPT09IGkpIHtcbiAgICAgIGluZGljYXRvci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLml0ZW1TZWxlY3RlZENvbG9yXG4gICAgfSBlbHNlIHtcbiAgICAgIGluZGljYXRvci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLml0ZW1Db2xvclxuICAgIH1cbiAgICBpbmRpY2F0b3IuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9jbGlja0hhbmRsZXIuYmluZCh0aGlzLCBpKSlcbiAgICB0aGlzLml0ZW1zW2ldID0gaW5kaWNhdG9yXG4gICAgcm9vdC5hcHBlbmRDaGlsZChpbmRpY2F0b3IpXG4gIH1cbiAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKHJvb3QpXG59XG5cbkluZGljYXRvci5wcm90b3R5cGUuc3R5bGVcbiAgICA9IGV4dGVuZChPYmplY3QuY3JlYXRlKEF0b21pYy5wcm90b3R5cGUuc3R5bGUpLCB7XG4gIGl0ZW1Db2xvcjogZnVuY3Rpb24gKHZhbCkge1xuICAgIHRoaXMuaXRlbUNvbG9yID0gdmFsIHx8IERFRkFVTFRfSVRFTV9DT0xPUlxuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5pdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRoaXMuaXRlbXNbaV0uc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5pdGVtQ29sb3JcbiAgICB9XG4gIH0sXG5cbiAgaXRlbVNlbGVjdGVkQ29sb3I6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICB0aGlzLml0ZW1TZWxlY3RlZENvbG9yID0gdmFsIHx8IERFRkFVTFRfSVRFTV9TRUxFQ1RFRF9DT0xPUlxuICAgIGlmICh0eXBlb2YgdGhpcy5pbmRleCAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgJiYgdGhpcy5pdGVtcy5sZW5ndGggPiB0aGlzLmluZGV4KSB7XG4gICAgICB0aGlzLml0ZW1zW3RoaXMuaW5kZXhdLnN0eWxlLmJhY2tncm91bmRDb2xvclxuICAgICAgICAgID0gdGhpcy5pdGVtU2VsZWN0ZWRDb2xvclxuICAgIH1cbiAgfSxcblxuICBpdGVtU2l6ZTogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhbCA9IHBhcnNlSW50KHZhbCkgKiB0aGlzLmRhdGEuc2NhbGVcbiAgICAgICAgICB8fCBERUZBVUxUX0lURU1fU0laRSAqIHRoaXMuZGF0YS5zY2FsZVxuICAgIHRoaXMuaXRlbVNpemUgPSB2YWxcbiAgICB0aGlzLm5vZGUuc3R5bGUuaGVpZ2h0ID0gdmFsICsgJ3B4J1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5pdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRoaXMuaXRlbXNbaV0uc3R5bGUud2lkdGggPSB2YWwgKyAncHgnXG4gICAgICB0aGlzLml0ZW1zW2ldLnN0eWxlLmhlaWdodCA9IHZhbCArICdweCdcbiAgICB9XG4gIH0sXG5cbiAgd2lkdGg6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICB2YWwgPSBwYXJzZUludCh2YWwpICogdGhpcy5kYXRhLnNjYWxlIHx8IHBhcnNlSW50KHRoaXMuc2xpZGVyV2lkdGgpXG4gICAgdGhpcy52aXJ0dWFsV3JhcHBlcldpZHRoID0gdmFsXG4gIH0sXG5cbiAgaGVpZ2h0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFsID0gcGFyc2VJbnQodmFsKSAqIHRoaXMuZGF0YS5zY2FsZSB8fCBwYXJzZUludCh0aGlzLnNsaWRlckhlaWdodClcbiAgICB0aGlzLnZpcnR1YWxXcmFwcGVySGVpZ2h0ID0gdmFsXG4gIH0sXG5cbiAgdG9wOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFsID0gdGhpcy52aXJ0dWFsV3JhcHBlckhlaWdodCAvIDIgLSB0aGlzLml0ZW1TaXplIC8gMlxuICAgICAgICArIHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgIHRoaXMubm9kZS5zdHlsZS5ib3R0b20gPSAnJ1xuICAgIHRoaXMubm9kZS5zdHlsZS50b3AgPSB2YWwgKyAncHgnXG4gIH0sXG5cbiAgYm90dG9tOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFsID0gdGhpcy52aXJ0dWFsV3JhcHBlckhlaWdodCAvIDIgLSB0aGlzLml0ZW1TaXplIC8gMlxuICAgICAgICArIHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgIHRoaXMubm9kZS5zdHlsZS50b3AgPSAnJ1xuICAgIHRoaXMubm9kZS5zdHlsZS5ib3R0b20gPSB2YWwgKyAncHgnXG4gIH0sXG5cbiAgbGVmdDogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhbCA9IHRoaXMudmlydHVhbFdyYXBwZXJXaWR0aCAvIDJcbiAgICAgICAgICAtICh0aGlzLml0ZW1TaXplICsgMiAqIERFRkFVTFRfTUFSR0lOX1NJWkUgKiB0aGlzLmRhdGEuc2NhbGUpXG4gICAgICAgICAgICAgICogdGhpcy5hbW91bnQgLyAyXG4gICAgICAgICAgKyB2YWwgKiB0aGlzLmRhdGEuc2NhbGVcbiAgICB0aGlzLm5vZGUuc3R5bGUucmlnaHQgPSAnJ1xuICAgIHRoaXMubm9kZS5zdHlsZS5sZWZ0ID0gdmFsICsgJ3B4J1xuICB9LFxuXG4gIHJpZ2h0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFsID0gdGhpcy52aXJ0dWFsV3JhcHBlcldpZHRoIC8gMlxuICAgICAgICAgIC0gKHRoaXMuaXRlbVNpemUgKyAyICogREVGQVVMVF9NQVJHSU5fU0laRSAqIHRoaXMuZGF0YS5zY2FsZSlcbiAgICAgICAgICAgICAgKiB0aGlzLmFtb3VudCAvIDJcbiAgICAgICAgICArIHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgIHRoaXMubm9kZS5zdHlsZS5sZWZ0ID0gJydcbiAgICB0aGlzLm5vZGUuc3R5bGUucmlnaHQgPSB2YWwgKyAncHgnXG4gIH1cbn0pXG5cbkluZGljYXRvci5wcm90b3R5cGUuc2V0SW5kZXggPSBmdW5jdGlvbiAoaWR4KSB7XG4gIGlmIChpZHggPj0gdGhpcy5hbW91bnQpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgcHJldiA9IHRoaXMuaXRlbXNbdGhpcy5pbmRleF1cbiAgdmFyIGN1ciA9IHRoaXMuaXRlbXNbaWR4XVxuICBwcmV2LmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpXG4gIHByZXYuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5pdGVtQ29sb3JcbiAgY3VyLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpXG4gIGN1ci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLml0ZW1TZWxlY3RlZENvbG9yXG4gIHRoaXMuaW5kZXggPSBpZHhcbn1cblxuSW5kaWNhdG9yLnByb3RvdHlwZS5fY2xpY2tIYW5kbGVyID0gZnVuY3Rpb24gKGlkeCkge1xuICB0aGlzLnNsaWRlci5zbGlkZVRvKGlkeClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBJbmRpY2F0b3JcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9pbmRpY2F0b3IuanNcbiAqKiBtb2R1bGUgaWQgPSA0NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2luZGljYXRvci5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vaW5kaWNhdG9yLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2luZGljYXRvci5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy9pbmRpY2F0b3Iuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDQ1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi53ZWV4LWluZGljYXRvcnMge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDsgfVxcbiAgLndlZXgtaW5kaWNhdG9ycyAud2VleC1pbmRpY2F0b3Ige1xcbiAgICBmbG9hdDogbGVmdDtcXG4gICAgYm9yZGVyLXJhZGl1czogNTAlOyB9XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL3NyYy9zcmMvc3R5bGVzL2luZGljYXRvci5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0UsbUJBQW1CO0VBQ25CLG9CQUFvQixFQU9yQjtFQVREO0lBS0ksWUFBWTtJQUNaLG1CQUFtQixFQUNwQlwiLFwiZmlsZVwiOlwiaW5kaWNhdG9yLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLndlZXgtaW5kaWNhdG9ycyB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xcblxcbiAgLndlZXgtaW5kaWNhdG9yIHtcXG4gICAgZmxvYXQ6IGxlZnQ7XFxuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcXG4gIH1cXG5cXG59XCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vc3JjL3N0eWxlcy9pbmRpY2F0b3Iuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDQ2XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIEF0b21pYyA9IHJlcXVpcmUoJy4vYXRvbWljJylcbnZhciBtc2dRdWV1ZSA9IHJlcXVpcmUoJy4uL21lc3NhZ2VRdWV1ZScpXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJylcblxuLy8gVE9ETzogcmVmYWN0b3IgdGhpcyBzY3NzIGNvZGUgc2luY2UgdGhpcyBpcyBzdHJvbmdseVxuLy8gZGVwZW5kZW50IG9uIGxpYi5mbGV4aWJsZSBvdGhlciB0aGFuIHRoZSB2YWx1ZSBvZlxuLy8gc2NhbGUuXG5yZXF1aXJlKCcuLi9zdHlsZXMvdGFiaGVhZGVyLnNjc3MnKVxuXG5mdW5jdGlvbiBUYWJIZWFkZXIoZGF0YSkge1xuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG52YXIgcHJvdG8gPSBUYWJIZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5wcm90by5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIG91dHNpZGUgY29udGFpbmVyLlxuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuY2xhc3NOYW1lID0gJ3RhYi1oZWFkZXInXG4gIC8vIHRpcCBvbiB0aGUgdG9wLlxuICB2YXIgYmFyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgYmFyLmNsYXNzTmFtZSA9ICdoZWFkZXItYmFyJ1xuICBiYXIudGV4dENvbnRlbnQgPSAnQ0hBTkdFIEZMT09SJ1xuICAvLyBtaWRkbGUgbGF5ZXIuXG4gIHZhciBib2R5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgYm9keS5jbGFzc05hbWUgPSAnaGVhZGVyLWJvZHknXG4gIHZhciBib3ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpXG4gIGJveC5jbGFzc05hbWUgPSAndGFiaGVhZGVyJ1xuXG4gIGJvZHkuYXBwZW5kQ2hpbGQoYm94KVxuICBub2RlLmFwcGVuZENoaWxkKGJhcilcbiAgbm9kZS5hcHBlbmRDaGlsZChib2R5KVxuICB0aGlzLl9iYXIgPSBiYXJcbiAgdGhpcy5fYm9keSA9IGJvZHlcbiAgdGhpcy5ib3ggPSBib3hcbiAgdGhpcy5ub2RlID0gbm9kZVxuICAvLyBpbml0IGV2ZW50cy5cbiAgdGhpcy5faW5pdEZvbGRCdG4oKVxuICB0aGlzLl9pbml0RXZlbnQoKVxuICByZXR1cm4gbm9kZVxufVxuXG5wcm90by5faW5pdEZvbGRCdG4gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXNcbiAgdmFyIG5vZGUgPSB0aGlzLm5vZGVcbiAgdmFyIGJ0biA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKVxuICBidG4uY2xhc3NOYW1lID0gJ2ZvbGQtdG9nZ2xlIGljb25mb250J1xuICBidG4uaW5uZXJIVE1MID0gJyYjeGU2NjE7J1xuICBub2RlLmFwcGVuZENoaWxkKGJ0bilcblxuICBidG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKF90aGlzLnVuZm9sZGluZykge1xuICAgICAgX3RoaXMuX2ZvbGRpbmcoKVxuICAgIH0gZWxzZSB7XG4gICAgICBfdGhpcy5fdW5mb2xkaW5nKClcbiAgICB9XG4gIH0pXG59XG5cbnByb3RvLl9pbml0TWFzayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG1hc2sgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBtYXNrLmNsYXNzTmFtZSA9ICd0YWJoZWFkZXItbWFzaydcbiAgdGhpcy5tYXNrID0gbWFza1xuICAvLyBzdG9wIGRlZmF1bHQgYmVoYXZpb3I6IHBhZ2UgbW92aW5nLlxuICBtYXNrLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIGZ1bmN0aW9uIChldnQpIHtcbiAgICBldnQucHJldmVudERlZmF1bHQoKVxuICB9KVxuICAvLyBjbGljayB0byB1bmZvbGQuXG4gIHZhciBfdGhpcyA9IHRoaXNcbiAgbWFzay5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICBfdGhpcy5fZm9sZGluZygpXG4gIH0pXG5cbiAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChtYXNrKVxufVxuXG5wcm90by5fdW5mb2xkaW5nID0gZnVuY3Rpb24gKCkge1xuICAvLyBtYXJrIHRoZSBpbml0aWFsIHBvc2lpdG9uIG9mIHRhYmhlYWRlclxuICBpZiAoIXRoaXMuZmxhZykge1xuICAgIHZhciBmbGFnID0gZG9jdW1lbnQuY3JlYXRlQ29tbWVudCgndGFiaGVhZGVyJylcbiAgICB0aGlzLmZsYWcgPSBmbGFnXG4gICAgdGhpcy5ub2RlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGZsYWcsIHRoaXMubm9kZSlcbiAgfVxuICBpZiAoIXRoaXMubWFzaykge1xuICAgIHRoaXMuX2luaXRNYXNrKClcbiAgfVxuXG4gIC8vIHJlY29yZCB0aGUgc2Nyb2xsIHBvc2l0aW9uLlxuICB0aGlzLl9zY3JvbGxWYWwgPSB0aGlzLl9ib2R5LnNjcm9sbExlZnRcbiAgLy8gcmVjb3JkIHRoZSBwb3NpdGlvbiBpbiBkb2N1bWVudC5cbiAgdGhpcy5fdG9wVmFsID0gdGhpcy5ub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcFxuICB0aGlzLl9zdHlsZVRvcCA9IHRoaXMubm9kZS5zdHlsZS50b3BcblxuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMubm9kZSlcbiAgdGhpcy5ub2RlLmNsYXNzTGlzdC5hZGQoJ3VuZm9sZC1oZWFkZXInKVxuICB0aGlzLm5vZGUuc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nXG4gIC8vIHJlY2FsYyB0aGUgcG9zaXRpb24gd2hlbiBpdCBpcyB1bmZvbGRlZC5cbiAgdmFyIHRoSGVpZ2h0ID0gdGhpcy5ub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodFxuICBpZiAodGhIZWlnaHQgKyB0aGlzLl90b3BWYWwgPiB3aW5kb3cuaW5uZXJIZWlnaHQpIHtcbiAgICB0aGlzLl90b3BWYWwgPSB0aGlzLl90b3BWYWxcbiAgICAgICAgKyAod2luZG93LmlubmVySGVpZ2h0IC0gdGhIZWlnaHQgLSB0aGlzLl90b3BWYWwpXG4gIH1cblxuICB0aGlzLm5vZGUuc3R5bGUudG9wID0gdGhpcy5fdG9wVmFsICsgJ3B4J1xuICAvLyBwcm9jZXNzIG1hc2sgc3R5bGVcbiAgdGhpcy5tYXNrLmNsYXNzTGlzdC5hZGQoJ3VuZm9sZC1oZWFkZXInKVxuICB0aGlzLm1hc2suc3R5bGUuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0ICsgJ3B4J1xuICB0aGlzLnVuZm9sZGluZyA9IHRydWVcbn1cblxucHJvdG8uX2ZvbGRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnVuZm9sZGluZyAhPT0gdHJ1ZSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdGhpcy5tYXNrLmNsYXNzTGlzdC5yZW1vdmUoJ3VuZm9sZC1oZWFkZXInKVxuICB0aGlzLm5vZGUuY2xhc3NMaXN0LnJlbW92ZSgndW5mb2xkLWhlYWRlcicpXG5cbiAgdGhpcy5ub2RlLnN0eWxlLmhlaWdodCA9ICcnXG4gIHRoaXMubm9kZS5zdHlsZS50b3AgPSB0aGlzLl9zdHlsZVRvcFxuXG4gIC8vIHJlY292ZXIgdGhlIHBvc2l0aW9uIG9mIHRhYmhlYWRlci5cbiAgdGhpcy5mbGFnLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXMubm9kZSwgdGhpcy5mbGFnKVxuICAvLyByZWNvdmVyIHRoZSBwb3NpdGlvbiBvZiBzY29sbGVyLlxuICB0aGlzLl9ib2R5LnNjcm9sbExlZnQgPSB0aGlzLl9zY3JvbGxWYWxcblxuICB0aGlzLl9zY3JvbGxUb1ZpZXcoKVxuICB0aGlzLnVuZm9sZGluZyA9IGZhbHNlXG59XG5cbnByb3RvLl9pbml0RXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2luaXRDbGlja0V2ZW50KClcbiAgdGhpcy5faW5pdFNlbGVjdEV2ZW50KClcbn1cblxuLy8gaW5pdCBldmVudHMuXG5wcm90by5faW5pdENsaWNrRXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBib3ggPSB0aGlzLmJveFxuICB2YXIgX3RoaXMgPSB0aGlzXG5cbiAgYm94LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKGV2dCkge1xuICAgIHZhciB0YXJnZXQgPSBldnQudGFyZ2V0XG4gICAgaWYgKHRhcmdldC5ub2RlTmFtZSA9PT0gJ1VMJykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRhcmdldC5wYXJlbnROb2RlLm5vZGVOYW1lID09PSAnTEknKSB7XG4gICAgICB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZVxuICAgIH1cblxuICAgIHZhciBmbG9vciA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZmxvb3InKVxuXG4gICAgaWYgKF90aGlzLmRhdGEuYXR0ci5zZWxlY3RlZEluZGV4ID09IGZsb29yKSB7XG4gICAgICAvLyBEdXBsaWNhdGVkIGNsaWNraW5nLCBub3QgdG8gdHJpZ2dlciBzZWxlY3QgZXZlbnQuXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBmaXJlRXZlbnQodGFyZ2V0LCAnc2VsZWN0Jywge2luZGV4OiAgZmxvb3J9KVxuICB9KVxufVxuXG5wcm90by5faW5pdFNlbGVjdEV2ZW50ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IHRoaXMubm9kZVxuICB2YXIgX3RoaXMgPSB0aGlzXG4gIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0JywgZnVuY3Rpb24gKGV2dCkge1xuICAgIHZhciBpbmRleFxuICAgIGlmIChldnQuaW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaW5kZXggPSBldnQuaW5kZXhcbiAgICB9IGVsc2UgaWYgKGV2dC5kYXRhICYmIGV2dC5kYXRhLmluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGluZGV4ID0gZXZ0LmRhdGEuaW5kZXhcbiAgICB9XG5cbiAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgX3RoaXMuYXR0ci5zZWxlY3RlZEluZGV4LmNhbGwoX3RoaXMsIGluZGV4KVxuICB9KVxufVxuXG5wcm90by5hdHRyID0ge1xuICBoaWdobGlnaHRJY29uOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhpZ2hsaWdodEljb24oKVxuICB9LFxuICBkYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGF0dHIgPSB0aGlzLmRhdGEuYXR0clxuICAgIC8vIEVuc3VyZSB0aGVyZSBpcyBhIGRlZmF1bHQgc2VsZWN0ZWQgdmFsdWUuXG4gICAgaWYgKGF0dHIuc2VsZWN0ZWRJbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhdHRyLnNlbGVjdGVkSW5kZXggPSAwXG4gICAgfVxuXG4gICAgdmFyIGxpc3QgPSBhdHRyLmRhdGEgfHwgW11cbiAgICB2YXIgY3VySXRlbSA9IGF0dHIuc2VsZWN0ZWRJbmRleFxuXG4gICAgdmFyIHJldCA9IFtdXG4gICAgdmFyIGl0ZW1UbXBsID0gJzxsaSBjbGFzcz1cInRoLWl0ZW1cIiBkYXRhLWZsb29yPVwie3tmbG9vcn19XCI+J1xuICAgICAgICArICd7e2hsSWNvbn19e3tmbG9vck5hbWV9fTwvbGk+J1xuXG4gICAgbGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtLCBpZHgpIHtcbiAgICAgIHZhciBodG1sID0gaXRlbVRtcGwucmVwbGFjZSgne3tmbG9vcn19JywgaWR4KVxuICAgICAgaWYgKGN1ckl0ZW0gPT0gaWR4KSB7XG4gICAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoJ3t7aGxJY29ufX0nLCBjcmVhdGVIaWdobGlnaHRJY29uKCkpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sID0gaHRtbC5yZXBsYWNlKCd7e2hsSWNvbn19JywgJycpXG4gICAgICB9XG5cbiAgICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoJ3t7Zmxvb3JOYW1lfX0nLCBpdGVtKVxuXG4gICAgICByZXQucHVzaChodG1sKVxuICAgIH0sIHRoaXMpXG5cbiAgICB0aGlzLmJveC5pbm5lckhUTUwgPSByZXQuam9pbignJylcbiAgfSxcbiAgc2VsZWN0ZWRJbmRleDogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhciBhdHRyID0gdGhpcy5kYXRhLmF0dHJcblxuICAgIGlmICh2YWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFsID0gMFxuICAgIH1cblxuICAgIC8vIGlmICh2YWwgPT0gYXR0ci5zZWxlY3RlZEluZGV4KSB7XG4gICAgLy8gICByZXR1cm5cbiAgICAvLyB9XG5cbiAgICBhdHRyLnNlbGVjdGVkSW5kZXggPSB2YWxcblxuICAgIHRoaXMuYXR0ci5kYXRhLmNhbGwodGhpcylcblxuICAgIHRoaXMuX2ZvbGRpbmcoKVxuICAgIHRoaXMuc3R5bGUudGV4dEhpZ2hsaWdodENvbG9yLmNhbGwodGhpcywgdGhpcy50ZXh0SGlnaGxpZ2h0Q29sb3IpXG4gIH1cbn1cblxucHJvdG8uc3R5bGUgPSBPYmplY3QuY3JlYXRlKEF0b21pYy5wcm90b3R5cGUuc3R5bGUpXG5cbnByb3RvLnN0eWxlLm9wYWNpdHkgPSBmdW5jdGlvbiAodmFsKSB7XG4gIGlmICh2YWwgPT09IHVuZGVmaW5lZCB8fCB2YWwgPCAwIHx8IHZhbCA+IDEpIHtcbiAgICB2YWwgPSAxXG4gIH1cblxuICB0aGlzLm5vZGUuc3R5bGUub3BhY2l0eSA9IHZhbFxufVxuXG5wcm90by5zdHlsZS50ZXh0Q29sb3IgPSBmdW5jdGlvbiAodmFsKSB7XG4gIGlmICghaXNWYWxpZENvbG9yKHZhbCkpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIHRoaXMubm9kZS5zdHlsZS5jb2xvciA9IHZhbFxufVxuXG5wcm90by5zdHlsZS50ZXh0SGlnaGxpZ2h0Q29sb3IgPSBmdW5jdGlvbiAodmFsKSB7XG4gIGlmICghaXNWYWxpZENvbG9yKHZhbCkpIHtcbiAgICByZXR1cm5cbiAgfVxuICB0aGlzLnRleHRIaWdobGlnaHRDb2xvciA9IHZhbFxuICB2YXIgYXR0ciA9IHRoaXMuZGF0YS5hdHRyXG5cbiAgdmFyIG5vZGUgPSB0aGlzLm5vZGUucXVlcnlTZWxlY3RvcignW2RhdGEtZmxvb3I9XCInXG4gICAgICArIGF0dHIuc2VsZWN0ZWRJbmRleCArICdcIl0nKVxuICBpZiAobm9kZSkge1xuICAgIG5vZGUuc3R5bGUuY29sb3IgPSB2YWxcbiAgICB0aGlzLl9zY3JvbGxUb1ZpZXcobm9kZSlcbiAgfVxufVxuXG5wcm90by5fc2Nyb2xsVG9WaWV3ID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgaWYgKCFub2RlKSB7XG4gICAgdmFyIGF0dHIgPSB0aGlzLmRhdGEuYXR0clxuICAgIG5vZGUgPSB0aGlzLm5vZGUucXVlcnlTZWxlY3RvcignW2RhdGEtZmxvb3I9XCInICsgYXR0ci5zZWxlY3RlZEluZGV4ICsgJ1wiXScpXG4gIH1cbiAgaWYgKCFub2RlKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgZGVmYXVsdFZhbCA9IHRoaXMuX2JvZHkuc2Nyb2xsTGVmdFxuICB2YXIgbGVmdFZhbCA9IGRlZmF1bHRWYWwgIC0gbm9kZS5vZmZzZXRMZWZ0ICsgMzAwXG5cbiAgdmFyIHNjcm9sbFZhbCA9IGdldFNjcm9sbFZhbCh0aGlzLl9ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBub2RlKVxuICBkb1Njcm9sbCh0aGlzLl9ib2R5LCBzY3JvbGxWYWwpXG59XG5cbi8vIHNjcm9sbCB0aGUgdGFiaGVhZGVyLlxuLy8gcG9zaXRpdmUgdmFsIG1lYW5zIHRvIHNjcm9sbCByaWdodC5cbi8vIG5lZ2F0aXZlIHZhbCBtZWFucyB0byBzY3JvbGwgbGVmdC5cbmZ1bmN0aW9uIGRvU2Nyb2xsKG5vZGUsIHZhbCwgZmluaXNoKSB7XG4gIGlmICghdmFsKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGZpbmlzaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZmluaXNoID0gTWF0aC5hYnModmFsKVxuICB9XG5cbiAgaWYgKGZpbmlzaCA8PSAwKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodmFsID4gMCkge1xuICAgICAgbm9kZS5zY3JvbGxMZWZ0ICs9IDJcbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZS5zY3JvbGxMZWZ0IC09IDJcbiAgICB9XG4gICAgZmluaXNoIC09IDJcblxuICAgIGRvU2Nyb2xsKG5vZGUsIHZhbCwgZmluaXNoKVxuICB9KVxufVxuXG4vLyBnZXQgc2Nyb2xsIGRpc3RhbmNlLlxuZnVuY3Rpb24gZ2V0U2Nyb2xsVmFsKHJlY3QsIG5vZGUpIHtcbiAgdmFyIGxlZnQgPSBub2RlLnByZXZpb3VzU2libGluZ1xuICB2YXIgcmlnaHQgPSBub2RlLm5leHRTaWJsaW5nXG4gIHZhciBzY3JvbGxWYWxcblxuICAvLyBwcm9jZXNzIGxlZnQtc2lkZSBlbGVtZW50IGZpcnN0LlxuICBpZiAobGVmdCkge1xuICAgIHZhciBsZWZ0UmVjdCA9IGxlZnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAvLyBvbmx5IG5lZWQgdG8gY29tcGFyZSB0aGUgdmFsdWUgb2YgbGVmdC5cbiAgICBpZiAobGVmdFJlY3QubGVmdCA8IHJlY3QubGVmdCkge1xuICAgICAgc2Nyb2xsVmFsID0gbGVmdFJlY3QubGVmdFxuICAgICAgcmV0dXJuIHNjcm9sbFZhbFxuICAgIH1cbiAgfVxuXG4gIGlmIChyaWdodCkge1xuICAgIHZhciByaWdodFJlY3QgPSByaWdodC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIC8vIGNvbXBhcmUgdGhlIHZhbHVlIG9mIHJpZ2h0LlxuICAgIGlmIChyaWdodFJlY3QucmlnaHQgPiByZWN0LnJpZ2h0KSB7XG4gICAgICBzY3JvbGxWYWwgPSByaWdodFJlY3QucmlnaHQgLSByZWN0LnJpZ2h0XG4gICAgICByZXR1cm4gc2Nyb2xsVmFsXG4gICAgfVxuICB9XG5cbiAgLy8gcHJvY2VzcyBjdXJyZW50IG5vZGUsIGZyb20gbGVmdCB0byByaWdodC5cbiAgdmFyIG5vZGVSZWN0ID0gbm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICBpZiAobm9kZVJlY3QubGVmdCA8IHJlY3QubGVmdCkge1xuICAgIHNjcm9sbFZhbCA9IG5vZGVSZWN0LmxlZnRcbiAgfSBlbHNlIGlmIChub2RlUmVjdC5yaWdodCA+IHJlY3QucmlnaHQpIHtcbiAgICBzY3JvbGxWYWwgPSBub2RlUmVjdC5yaWdodCAtIHJlY3QucmlnaHRcbiAgfVxuXG4gIHJldHVybiBzY3JvbGxWYWxcbn1cblxuLy8gdHJpZ2dlciBhbmQgYnJvYWRjYXN0IGV2ZW50cy5cbmZ1bmN0aW9uIGZpcmVFdmVudChlbGVtZW50LCB0eXBlLCBkYXRhKSB7XG4gIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnRXZlbnQnKVxuICBldnQuZGF0YSA9IGRhdGFcbiAgdXRpbHMuZXh0ZW5kKGV2dCwgZGF0YSlcbiAgLy8gbmVlZCBidWJibGUuXG4gIGV2dC5pbml0RXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSlcblxuICBlbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZ0KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVIaWdobGlnaHRJY29uKGNvZGUpIHtcbiAgdmFyIGh0bWwgPSAnPGkgY2xhc3M9XCJobC1pY29uIGljb25mb250XCI+JyArICcmI3hlNjUwJyArICc8L2k+J1xuICByZXR1cm4gaHRtbFxufVxuXG5mdW5jdGlvbiBpc1ZhbGlkQ29sb3IoY29sb3IpIHtcbiAgaWYgKCFjb2xvcikge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgaWYgKGNvbG9yLmNoYXJBdCgwKSAhPT0gJyMnKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAoY29sb3IubGVuZ3RoICE9PSA3KSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFRhYkhlYWRlclxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL3RhYmhlYWRlci5qc1xuICoqIG1vZHVsZSBpZCA9IDQ3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJylcbnZhciBtZXNzYWdlUXVldWUgPSBbXVxuXG5mdW5jdGlvbiBmbHVzaE1lc3NhZ2UoKSB7XG4gIGlmICh0eXBlb2YgY2FsbEpTID09PSAnZnVuY3Rpb24nICYmIG1lc3NhZ2VRdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgY2FsbEpTKGNvbmZpZy5pbnN0YW5jZUlkLCBKU09OLnN0cmluZ2lmeShtZXNzYWdlUXVldWUpKVxuICAgIG1lc3NhZ2VRdWV1ZS5sZW5ndGggPSAwXG4gIH1cbn1cblxuZnVuY3Rpb24gcHVzaChtc2cpIHtcbiAgbWVzc2FnZVF1ZXVlLnB1c2gobXNnKVxufVxuXG4vKipcbiAqIFRvIGZpeCB0aGUgcHJvYmxlbSBvZiBjYWxsYXBwLCB0aGUgdHdvLXdheSB0aW1lIGxvb3AgbWVjaGFuaXNtIG11c3RcbiAqIGJlIHJlcGxhY2VkIGJ5IGRpcmVjdGx5IHByb2NlZHVyZSBjYWxsIGV4Y2VwdCB0aGUgc2l0dWF0aW9uIG9mXG4gKiBwYWdlIGxvYWRpbmcuXG4gKiAyMDE1LTExLTAzXG4gKi9cbmZ1bmN0aW9uIHB1c2hEaXJlY3RseShtc2cpIHtcbiAgY2FsbEpTKGNvbmZpZy5pbnN0YW5jZUlkLCBbbXNnXSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHB1c2g6IHB1c2hEaXJlY3RseVxufVxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9tZXNzYWdlUXVldWUuanNcbiAqKiBtb2R1bGUgaWQgPSA0OFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3RhYmhlYWRlci5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vdGFiaGVhZGVyLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3RhYmhlYWRlci5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy90YWJoZWFkZXIuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDQ5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi50YWItaGVhZGVyIHtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIHdpZHRoOiAxMHJlbTtcXG4gIGZvbnQtc2l6ZTogMTRweDtcXG4gIGNvbG9yOiAjMzMzOyB9XFxuICAudGFiLWhlYWRlciAuaGVhZGVyLWJhciB7XFxuICAgIGhlaWdodDogMS4xN3JlbTtcXG4gICAgbGluZS1oZWlnaHQ6IDEuMTdyZW07XFxuICAgIGRpc3BsYXk6IG5vbmU7XFxuICAgIGNvbG9yOiAjOTk5O1xcbiAgICBwYWRkaW5nLWxlZnQ6IDAuNHJlbTsgfVxcbiAgLnRhYi1oZWFkZXIgLmhlYWRlci1ib2R5IHtcXG4gICAgbWFyZ2luLXJpZ2h0OiAxLjA3cmVtO1xcbiAgICBvdmVyZmxvdy14OiBhdXRvO1xcbiAgICBvdmVyZmxvdy15OiBoaWRkZW47IH1cXG4gICAgLnRhYi1oZWFkZXIgLmhlYWRlci1ib2R5Ojotd2Via2l0LXNjcm9sbGJhciB7XFxuICAgICAgd2lkdGg6IDA7XFxuICAgICAgaGVpZ2h0OiAwO1xcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47IH1cXG4gIC50YWItaGVhZGVyIC5mb2xkLXRvZ2dsZSB7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiAwLjU5cmVtO1xcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcXG4gICAgcmlnaHQ6IDAuMjlyZW07XFxuICAgIHdpZHRoOiAwLjQ4cmVtO1xcbiAgICBoZWlnaHQ6IDAuNDhyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAwLjQ4cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHotaW5kZXg6IDk5O1xcbiAgICBmb250LXNpemU6IDE0cHg7IH1cXG4gIC50YWItaGVhZGVyLnVuZm9sZC1oZWFkZXIge1xcbiAgICBwb3NpdGlvbjogZml4ZWQgIWltcG9ydGFudDtcXG4gICAgdG9wOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBvdmVyZmxvdzogaGlkZGVuOyB9XFxuXFxuLnRhYmhlYWRlciB7XFxuICBsaXN0LXN0eWxlOiBub25lO1xcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcXG4gIGhlaWdodDogMS4xN3JlbTtcXG4gIGxpbmUtaGVpZ2h0OiAxLjE3cmVtOyB9XFxuICAudGFiaGVhZGVyIC50aC1pdGVtIHtcXG4gICAgcGFkZGluZy1sZWZ0OiAwLjcycmVtO1xcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsgfVxcbiAgLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICAgIHdpZHRoOiAwLjRyZW07XFxuICAgIGhlaWdodDogMC40cmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC40cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiA1MCU7XFxuICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC01MCUpO1xcbiAgICBsZWZ0OiAwLjI0cmVtO1xcbiAgICBmb250LXNpemU6IDE0cHg7IH1cXG5cXG4udW5mb2xkLWhlYWRlciAuaGVhZGVyLWJhciB7XFxuICBkaXNwbGF5OiBibG9jazsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC5mb2xkLXRvZ2dsZSB7XFxuICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKSByb3RhdGUoMTgwZGVnKTsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC5oZWFkZXItYm9keSB7XFxuICBtYXJnaW4tcmlnaHQ6IDA7XFxuICBwYWRkaW5nOiAwLjI0cmVtOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIgLnRhYmhlYWRlciB7XFxuICBkaXNwbGF5OiBibG9jaztcXG4gIGhlaWdodDogYXV0bzsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC50aC1pdGVtIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBmbG9hdDogbGVmdDtcXG4gIHdpZHRoOiAzMy4zMzMzJTtcXG4gIGhlaWdodDogMS4wMXJlbTtcXG4gIGxpbmUtaGVpZ2h0OiAxLjAxcmVtOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIgLmhsLWljb24ge1xcbiAgbWFyZ2luLXJpZ2h0OiAwO1xcbiAgcG9zaXRpb246IGFic29sdXRlOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIudGFiaGVhZGVyLW1hc2sge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogMTAwJTtcXG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC42KTsgfVxcblxcbi50YWJoZWFkZXItbWFzayB7XFxuICBkaXNwbGF5OiBub25lO1xcbiAgcG9zaXRpb246IGZpeGVkO1xcbiAgbGVmdDogMDtcXG4gIHRvcDogMDsgfVxcblxcbkBmb250LWZhY2Uge1xcbiAgZm9udC1mYW1pbHk6IFxcXCJpY29uZm9udFxcXCI7XFxuICBzcmM6IHVybChcXFwiZGF0YTphcHBsaWNhdGlvbi94LWZvbnQtdHRmO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LEFBRUFBQUFQQUlBQUF3QndSa1pVVFhCRDk4VUFBQUQ4QUFBQUhFOVRMekpYTDF6SUFBQUJHQUFBQUdCamJXRndzNklIYmdBQUFYZ0FBQUZhWTNaMElBeVYvc3dBQUFwUUFBQUFKR1p3WjIwdzk1NlZBQUFLZEFBQUNaWm5ZWE53QUFBQUVBQUFDa2dBQUFBSVoyeDVadXhvUEZJQUFBTFVBQUFFV0dobFlXUUhBNWgzQUFBSExBQUFBRFpvYUdWaEJ6SURjZ0FBQjJRQUFBQWthRzEwZUFzMkFXMEFBQWVJQUFBQUdHeHZZMkVEY0FRZUFBQUhvQUFBQUJCdFlYaHdBU2tLS3dBQUI3QUFBQUFnYm1GdFpRbC8zaGdBQUFmUUFBQUNMbkJ2YzNUbTdmMGJBQUFLQUFBQUFFaHdjbVZ3cGJtK1pnQUFGQXdBQUFDVkFBQUFBUUFBQUFETVBhTFBBQUFBQU5JREtub0FBQUFBMGdNcWV3QUVBL29COUFBRkFBQUNtUUxNQUFBQWp3S1pBc3dBQUFIckFETUJDUUFBQWdBR0F3QUFBQUFBQUFBQUFBRVFBQUFBQUFBQUFBQUFBQUJRWmtWa0FNQUFlT2JlQXl6L0xBQmNBeGdBbEFBQUFBRUFBQUFBQXhnQUFBQUFBQ0FBQVFBQUFBTUFBQUFEQUFBQUhBQUJBQUFBQUFCVUFBTUFBUUFBQUJ3QUJBQTRBQUFBQ2dBSUFBSUFBZ0I0NWxEbVllYmUvLzhBQUFCNDVsRG1ZZWJlLy8vL2l4bTBHYVFaS0FBQkFBQUFBQUFBQUFBQUFBQUFBUVlBQUFFQUFBQUFBQUFBQVFJQUFBQUNBQUFBQUFBQUFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBTUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDQUNJQUFBRXlBcW9BQXdBSEFDbEFKZ0FBQUFNQ0FBTlhBQUlCQVFKTEFBSUNBVThFQVFFQ0FVTUFBQWNHQlFRQUF3QURFUVVQS3pNUklSRW5NeEVqSWdFUTdzek1BcXI5VmlJQ1pnQUFBQVVBTFAvaEE3d0RHQUFXQURBQU9nQlNBRjRCZDB1d0UxQllRRW9DQVFBTkRnMEFEbVlBQXc0QkRnTmVBQUVJQ0FGY0VBRUpDQW9HQ1Y0UkFRd0dCQVlNWGdBTEJBdHBEd0VJQUFZTUNBWllBQW9IQlFJRUN3b0VXUklCRGc0TlVRQU5EUW9PUWh0THNCZFFXRUJMQWdFQURRNE5BQTVtQUFNT0FRNERYZ0FCQ0FnQlhCQUJDUWdLQ0FrS1poRUJEQVlFQmd4ZUFBc0VDMmtQQVFnQUJnd0lCbGdBQ2djRkFnUUxDZ1JaRWdFT0RnMVJBQTBOQ2c1Q0cwdXdHRkJZUUV3Q0FRQU5EZzBBRG1ZQUF3NEJEZ05lQUFFSUNBRmNFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNHMEJPQWdFQURRNE5BQTVtQUFNT0FRNERBV1lBQVFnT0FRaGtFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNXVmxaUUNoVFV6czdNakVYRjFOZVUxNWJXRHRTTzFKTFF6YzFNVG95T2hjd0Z6QlJFVEVZRVNnVlFCTVdLd0VHS3dFaURnSWRBU0UxTkNZMU5DNENLd0VWSVFVVkZCWVVEZ0lqQmlZckFTY2hCeXNCSWljaUxnSTlBUmNpQmhRV016STJOQ1lYQmdjT0F4NEJPd1l5TmljdUFTY21Kd0UxTkQ0Q093RXlGaDBCQVJrYkdsTVNKUndTQTVBQkNoZ25Ib1grU2dLaUFSVWZJdzRPSHc0Z0xmNUpMQjBpRkJrWklCTUlkd3dTRWd3TkVoS01DQVlGQ3dRQ0JBOE9KVU5SVUVBa0Z4WUpCUWtGQlFiK3BBVVBHaFc4SHlrQ0h3RU1HU2NhVENrUUhBUU5JQnNTWVlnMEZ6bzZKUmNKQVFHQWdBRVRHeUFPcHo4UkdoRVJHaEY4R2hZVEpBNFFEUWdZR2cwakVSTVVBWGZrQ3hnVERCMG00d0FBQWdDZy8yd0RZQUxzQUJJQUdnQWhRQjRBQUFBREFnQURXUUFDQVFFQ1RRQUNBZ0ZSQUFFQ0FVVVRGamtRQkJJckFDQUdGUlFlQXhjV093RXlQd0VTTlRRQUlpWTBOaklXRkFLUy90ek9SRlZ2TVJBSkRnRU9DVzNiL3VLRVhsNkVYZ0xzenBJMWxYeUpOaEVLQzMwQkRJeVMvczVlaEY1ZWhBQUFBQUVBZ2dCSkE0UUI2QUFkQUJ0QUdCSVJBZ0VBQVVBRkFRQStBQUFCQUdnQUFRRmZFeDhDRUNzQkpnY0dCd2tCTGdFR0J3WVVGd0V3TXhjVkZqSTNBVDRETGdJRGVoRVdBd1ArdVA2MEJoRVFCZ29LQVdFQkFRb2FDUUZlQXdRQ0FRRUNCQUhoRWcwREF2NjFBVWtIQkFVR0NSc0ovcUlCQVFrSkFXSUNCd1lIQ0FZR0FBRUFmd0NMQTRFQ0p3QWhBQjFBR2hZUEFnRUFBVUFGQVFBK0FBQUJBR2dDQVFFQlh5UXVFd01SS3lVQk1DY2pOU1lIQmdjQkRnRVVGaGNlQWpNeU53a0JGak15TmpjK0FpNEJBM2YrbndFQkVoVUVBdjZpQlFVRkJRTUhDQVFPQ1FGSUFVd0tEUVlNQlFNRkFRRUZ3d0ZlQVFFUkRRSUQvcDhGREF3TUJBTUVBZ2tCUy82MkNRVUZBd29KQ2drQUFBRUFBQUFCQUFBTEl5bm9Ydzg4OVFBTEJBQUFBQUFBMGdNcWV3QUFBQURTQXlwN0FDTC9iQU84QXhnQUFBQUlBQUlBQUFBQUFBQUFBUUFBQXhqL2JBQmNCQUFBQUFBQUE3d0FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBVUJkZ0FpQUFBQUFBRlZBQUFENlFBc0JBQUFvQUNDQUg4QUFBQW9BQ2dBS0FGa0FhSUI1QUlzQUFFQUFBQUhBRjhBQlFBQUFBQUFBZ0FtQURRQWJBQUFBSW9KbGdBQUFBQUFBQUFNQUpZQUFRQUFBQUFBQVFBSUFBQUFBUUFBQUFBQUFnQUdBQWdBQVFBQUFBQUFBd0FrQUE0QUFRQUFBQUFBQkFBSUFESUFBUUFBQUFBQUJRQkdBRG9BQVFBQUFBQUFCZ0FJQUlBQUF3QUJCQWtBQVFBUUFJZ0FBd0FCQkFrQUFnQU1BSmdBQXdBQkJBa0FBd0JJQUtRQUF3QUJCQWtBQkFBUUFPd0FBd0FCQkFrQUJRQ01BUHdBQXdBQkJBa0FCZ0FRQVlocFkyOXVabTl1ZEUxbFpHbDFiVVp2Ym5SR2IzSm5aU0F5TGpBZ09pQnBZMjl1Wm05dWRDQTZJREkyTFRndE1qQXhOV2xqYjI1bWIyNTBWbVZ5YzJsdmJpQXhMakFnT3lCMGRHWmhkWFJ2YUdsdWRDQW9kakF1T1RRcElDMXNJRGdnTFhJZ05UQWdMVWNnTWpBd0lDMTRJREUwSUMxM0lDSkhJaUF0WmlBdGMybGpiMjVtYjI1MEFHa0FZd0J2QUc0QVpnQnZBRzRBZEFCTkFHVUFaQUJwQUhVQWJRQkdBRzhBYmdCMEFFWUFid0J5QUdjQVpRQWdBRElBTGdBd0FDQUFPZ0FnQUdrQVl3QnZBRzRBWmdCdkFHNEFkQUFnQURvQUlBQXlBRFlBTFFBNEFDMEFNZ0F3QURFQU5RQnBBR01BYndCdUFHWUFid0J1QUhRQVZnQmxBSElBY3dCcEFHOEFiZ0FnQURFQUxnQXdBQ0FBT3dBZ0FIUUFkQUJtQUdFQWRRQjBBRzhBYUFCcEFHNEFkQUFnQUNnQWRnQXdBQzRBT1FBMEFDa0FJQUF0QUd3QUlBQTRBQ0FBTFFCeUFDQUFOUUF3QUNBQUxRQkhBQ0FBTWdBd0FEQUFJQUF0QUhnQUlBQXhBRFFBSUFBdEFIY0FJQUFpQUVjQUlnQWdBQzBBWmdBZ0FDMEFjd0JwQUdNQWJ3QnVBR1lBYndCdUFIUUFBQUFDQUFBQUFBQUEvNE1BTWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBY0FBQUFCQUFJQVd3RUNBUU1CQkFkMWJtbEZOalV3QjNWdWFVVTJOakVIZFc1cFJUWkVSUUFCQUFILy93QVBBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQXlBRElER1AvaEF4ai9iQU1ZLytFREdQOXNzQUFzc0NCZ1ppMndBU3dnWkNDd3dGQ3dCQ1phc0FSRlcxZ2hJeUViaWxnZ3NGQlFXQ0d3UUZrYklMQTRVRmdoc0RoWldTQ3dDa1ZoWkxBb1VGZ2hzQXBGSUxBd1VGZ2hzREJaR3lDd3dGQllJR1lnaW9waElMQUtVRmhnR3lDd0lGQllJYkFLWUJzZ3NEWlFXQ0d3Tm1BYllGbFpXUnV3QUN0WldTT3dBRkJZWlZsWkxiQUNMQ0JGSUxBRUpXRmtJTEFGUTFCWXNBVWpRckFHSTBJYklTRlpzQUZnTGJBRExDTWhJeUVnWkxFRllrSWdzQVlqUXJJS0FBSXFJU0N3QmtNZ2lpQ0tzQUFyc1RBRkpZcFJXR0JRRzJGU1dWZ2pXU0Vnc0VCVFdMQUFLeHNoc0VCWkk3QUFVRmhsV1Myd0JDeXdDQ05Dc0FjalFyQUFJMEt3QUVPd0IwTlJXTEFJUXl1eUFBRUFRMkJDc0JabEhGa3RzQVVzc0FCRElFVWdzQUpGWTdBQlJXSmdSQzJ3Qml5d0FFTWdSU0N3QUNzanNRUUVKV0FnUllvallTQmtJTEFnVUZnaHNBQWJzREJRV0xBZ0c3QkFXVmtqc0FCUVdHVlpzQU1sSTJGRVJDMndCeXl4QlFWRnNBRmhSQzJ3Q0N5d0FXQWdJTEFLUTBxd0FGQllJTEFLSTBKWnNBdERTckFBVWxnZ3NBc2pRbGt0c0Frc0lMZ0VBR0lndUFRQVk0b2pZYkFNUTJBZ2ltQWdzQXdqUWlNdHNBb3NTMVJZc1FjQlJGa2tzQTFsSTNndHNBc3NTMUZZUzFOWXNRY0JSRmtiSVZra3NCTmxJM2d0c0F3c3NRQU5RMVZZc1EwTlE3QUJZVUt3Q1N0WnNBQkRzQUlsUXJJQUFRQkRZRUt4Q2dJbFFyRUxBaVZDc0FFV0l5Q3dBeVZRV0xBQVE3QUVKVUtLaWlDS0kyR3dDQ29oSTdBQllTQ0tJMkd3Q0NvaEc3QUFRN0FDSlVLd0FpVmhzQWdxSVZtd0NrTkhzQXREUjJDd2dHSWdzQUpGWTdBQlJXSmdzUUFBRXlORXNBRkRzQUErc2dFQkFVTmdRaTJ3RFN5eEFBVkZWRmdBc0EwalFpQmdzQUZodFE0T0FRQU1BRUpDaW1DeERBUXJzR3NyR3lKWkxiQU9MTEVBRFNzdHNBOHNzUUVOS3kyd0VDeXhBZzByTGJBUkxMRUREU3N0c0JJc3NRUU5LeTJ3RXl5eEJRMHJMYkFVTExFR0RTc3RzQlVzc1FjTkt5MndGaXl4Q0EwckxiQVhMTEVKRFNzdHNCZ3NzQWNyc1FBRlJWUllBTEFOSTBJZ1lMQUJZYlVPRGdFQURBQkNRb3Bnc1F3RUs3QnJLeHNpV1Myd0dTeXhBQmdyTGJBYUxMRUJHQ3N0c0Jzc3NRSVlLeTJ3SEN5eEF4Z3JMYkFkTExFRUdDc3RzQjRzc1FVWUt5MndIeXl4QmhnckxiQWdMTEVIR0NzdHNDRXNzUWdZS3kyd0lpeXhDUmdyTGJBakxDQmdzQTVnSUVNanNBRmdRN0FDSmJBQ0pWRllJeUE4c0FGZ0k3QVNaUndiSVNGWkxiQWtMTEFqSzdBaktpMndKU3dnSUVjZ0lMQUNSV093QVVWaVlDTmhPQ01naWxWWUlFY2dJTEFDUldPd0FVVmlZQ05oT0JzaFdTMndKaXl4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0p5eXdCeXV4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0tDd2dOYkFCWUMyd0tTd0FzQU5GWTdBQlJXS3dBQ3V3QWtWanNBRkZZckFBSzdBQUZyUUFBQUFBQUVRK0l6aXhLQUVWS2kyd0tpd2dQQ0JISUxBQ1JXT3dBVVZpWUxBQVEyRTRMYkFyTEM0WFBDMndMQ3dnUENCSElMQUNSV093QVVWaVlMQUFRMkd3QVVOak9DMndMU3l4QWdBV0pTQXVJRWV3QUNOQ3NBSWxTWXFLUnlOSEkyRWdXR0liSVZtd0FTTkNzaXdCQVJVVUtpMndMaXl3QUJhd0JDV3dCQ1ZISTBjalliQUdSU3RsaWk0aklDQThpamd0c0M4c3NBQVdzQVFsc0FRbElDNUhJMGNqWVNDd0JDTkNzQVpGS3lDd1lGQllJTEJBVVZpekFpQURJQnV6QWlZREdsbENRaU1nc0FsRElJb2pSeU5ISTJFalJtQ3dCRU93Z0dKZ0lMQUFLeUNLaW1FZ3NBSkRZR1Fqc0FORFlXUlFXTEFDUTJFYnNBTkRZRm13QXlXd2dHSmhJeUFnc0FRbUkwWmhPQnNqc0FsRFJyQUNKYkFKUTBjalJ5TmhZQ0N3QkVPd2dHSmdJeUN3QUNzanNBUkRZTEFBSzdBRkpXR3dCU1d3Z0dLd0JDWmhJTEFFSldCa0k3QURKV0JrVUZnaEd5TWhXU01nSUxBRUppTkdZVGhaTGJBd0xMQUFGaUFnSUxBRkppQXVSeU5ISTJFalBEZ3RzREVzc0FBV0lMQUpJMElnSUNCR0kwZXdBQ3NqWVRndHNESXNzQUFXc0FNbHNBSWxSeU5ISTJHd0FGUllMaUE4SXlFYnNBSWxzQUlsUnlOSEkyRWdzQVVsc0FRbFJ5TkhJMkd3QmlXd0JTVkpzQUlsWWJBQlJXTWpJRmhpR3lGWlk3QUJSV0pnSXk0aklDQThpamdqSVZrdHNETXNzQUFXSUxBSlF5QXVSeU5ISTJFZ1lMQWdZR2F3Z0dJaklDQThpamd0c0RRc0l5QXVSckFDSlVaU1dDQThXUzZ4SkFFVUt5MndOU3dqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBMkxDTWdMa2F3QWlWR1VsZ2dQRmtqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBM0xMQXVLeU1nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3N0c0Rnc3NDOHJpaUFnUExBRUkwS0tPQ01nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3V3QkVNdXNDUXJMYkE1TExBQUZyQUVKYkFFSmlBdVJ5TkhJMkd3QmtVckl5QThJQzRqT0xFa0FSUXJMYkE2TExFSkJDVkNzQUFXc0FRbHNBUWxJQzVISTBjallTQ3dCQ05Dc0FaRkt5Q3dZRkJZSUxCQVVWaXpBaUFESUJ1ekFpWURHbGxDUWlNZ1I3QUVRN0NBWW1BZ3NBQXJJSXFLWVNDd0FrTmdaQ093QTBOaFpGQllzQUpEWVJ1d0EwTmdXYkFESmJDQVltR3dBaVZHWVRnaklEd2pPQnNoSUNCR0kwZXdBQ3NqWVRnaFdiRWtBUlFyTGJBN0xMQXVLeTZ4SkFFVUt5MndQQ3l3THlzaEl5QWdQTEFFSTBJak9MRWtBUlFyc0FSRExyQWtLeTJ3UFN5d0FCVWdSN0FBSTBLeUFBRUJGUlFUTHJBcUtpMndQaXl3QUJVZ1I3QUFJMEt5QUFFQkZSUVRMckFxS2kyd1B5eXhBQUVVRTdBcktpMndRQ3l3TFNvdHNFRXNzQUFXUlNNZ0xpQkdpaU5oT0xFa0FSUXJMYkJDTExBSkkwS3dRU3N0c0VNc3NnQUFPaXN0c0VRc3NnQUJPaXN0c0VVc3NnRUFPaXN0c0VZc3NnRUJPaXN0c0Vjc3NnQUFPeXN0c0Vnc3NnQUJPeXN0c0Vrc3NnRUFPeXN0c0Vvc3NnRUJPeXN0c0Vzc3NnQUFOeXN0c0V3c3NnQUJOeXN0c0Uwc3NnRUFOeXN0c0U0c3NnRUJOeXN0c0U4c3NnQUFPU3N0c0ZBc3NnQUJPU3N0c0ZFc3NnRUFPU3N0c0ZJc3NnRUJPU3N0c0ZNc3NnQUFQQ3N0c0ZRc3NnQUJQQ3N0c0ZVc3NnRUFQQ3N0c0ZZc3NnRUJQQ3N0c0Zjc3NnQUFPQ3N0c0Znc3NnQUJPQ3N0c0Zrc3NnRUFPQ3N0c0Zvc3NnRUJPQ3N0c0Zzc3NEQXJMckVrQVJRckxiQmNMTEF3SzdBMEt5MndYU3l3TUN1d05Tc3RzRjRzc0FBV3NEQXJzRFlyTGJCZkxMQXhLeTZ4SkFFVUt5MndZQ3l3TVN1d05Dc3RzR0Vzc0RFcnNEVXJMYkJpTExBeEs3QTJLeTJ3WXl5d01pc3VzU1FCRkNzdHNHUXNzRElyc0RRckxiQmxMTEF5SzdBMUt5MndaaXl3TWl1d05pc3RzR2Nzc0RNckxyRWtBUlFyTGJCb0xMQXpLN0EwS3kyd2FTeXdNeXV3TlNzdHNHb3NzRE1yc0RZckxiQnJMQ3V3Q0dXd0F5UlFlTEFCRlRBdEFBQkx1QURJVWxpeEFRR09XYmtJQUFnQVl5Q3dBU05FSUxBREkzQ3dEa1VnSUV1NEFBNVJTN0FHVTFwWXNEUWJzQ2haWUdZZ2lsVllzQUlsWWJBQlJXTWpZckFDSTBTekNna0ZCQ3V6Q2dzRkJDdXpEZzhGQkN0WnNnUW9DVVZTUkxNS0RRWUVLN0VHQVVTeEpBR0lVVml3UUloWXNRWURSTEVtQVloUldMZ0VBSWhZc1FZQlJGbFpXVm00QWYrRnNBU05zUVVBUkFBQUFBPT1cXFwiKSBmb3JtYXQoXFxcInRydWV0eXBlXFxcIik7IH1cXG5cXG4uaWNvbmZvbnQge1xcbiAgZm9udC1mYW1pbHk6IGljb25mb250ICFpbXBvcnRhbnQ7XFxuICBmb250LXNpemU6IDE2cHg7XFxuICBmb250LXN0eWxlOiBub3JtYWw7XFxuICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcXG4gIC13ZWJraXQtdGV4dC1zdHJva2Utd2lkdGg6IDAuMnB4O1xcbiAgLW1vei1vc3gtZm9udC1zbW9vdGhpbmc6IGdyYXlzY2FsZTsgfVxcblxcbltkYXRhLWRwcj1cXFwiMlxcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogMjhweDsgfVxcblxcbltkYXRhLWRwcj1cXFwiM1xcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogNDJweDsgfVxcblxcbltkYXRhLWRwcj1cXFwiMlxcXCJdIC50YWJoZWFkZXIgLmhsLWljb24ge1xcbiAgZm9udC1zaXplOiAyOHB4OyB9XFxuXFxuW2RhdGEtZHByPVxcXCIzXFxcIl0gLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICBmb250LXNpemU6IDQycHg7IH1cXG5cXG5bZGF0YS1kcHI9XFxcIjJcXFwiXSAudGFiLWhlYWRlciAuZm9sZC10b2dnbGUge1xcbiAgZm9udC1zaXplOiAyOHB4OyB9XFxuXFxuW2RhdGEtZHByPVxcXCIzXFxcIl0gLnRhYi1oZWFkZXIgLmZvbGQtdG9nZ2xlIHtcXG4gIGZvbnQtc2l6ZTogNDJweDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy90YWJoZWFkZXIuc2Nzc1wiLFwiLy4vc3JjL3N0eWxlcy90YWJoZWFkZXIuc2Nzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFHQTtFQUNFLG1CQUFtQjtFQUNuQixhQUFhO0VBQ2IsZ0JBQWdCO0VBQ2hCLFlBQVksRUEwQ2I7RUE5Q0Q7SUFPSSxnQkFBZ0I7SUFDaEIscUJBQXFCO0lBQ3JCLGNBQWM7SUFDZCxZQUFZO0lBQ1oscUJBQXFCLEVBQ3RCO0VBWkg7SUFlSSxzQkFBc0I7SUFDdEIsaUJBQWlCO0lBQ2pCLG1CQUFtQixFQU9wQjtJQXhCSDtNQW9CTSxTQUFTO01BQ1QsVUFBVTtNQUNWLGlCQUFpQixFQUNsQjtFQXZCTDtJQTJCSSxtQkFBbUI7SUFDbkIsYUFBYTtJQUNiLG9DQUE2QjtJQUM3QixlQUFlO0lBQ2YsZUFBZTtJQUNmLGdCQUFnQjtJQUNoQixxQkFBcUI7SUFDckIsbUJBQW1CO0lBQ25CLFlBQVk7SUFDWixnQkFBZ0IsRUFDakI7RUFyQ0g7SUF3Q0ksMkJBQTJCO0lBQzNCLE9BQU87SUFDUCxRQUFRO0lBQ1IsaUJBQWlCLEVBQ2xCOztBQUlIO0VBQ0UsaUJBQWlCO0VBQ2pCLG9CQUFvQjtFQUNwQixnQkFBZ0I7RUFDaEIscUJBQXFCLEVBb0J0QjtFQXhCRDtJQU9JLHNCQUFzQjtJQUN0QixtQkFBbUI7SUFDbkIsc0JBQXNCLEVBQ3ZCO0VBVkg7SUFhSSxjQUFjO0lBQ2QsZUFBZTtJQUNmLG9CQUFvQjtJQUNwQixtQkFBbUI7SUFDbkIsbUJBQW1CO0lBQ25CLFNBQVM7SUFDVCxvQ0FBNkI7SUFDN0IsY0FBYztJQUNkLGdCQUFnQixFQUNqQjs7QUFJSDtFQUdJLGVBQWUsRUFDaEI7O0FBSkg7RUFPSSxtREFBMEMsRUFDM0M7O0FBUkg7RUFXSSxnQkFBZ0I7RUFDaEIsaUJBQWlCLEVBQ2xCOztBQWJIO0VBZ0JJLGVBQWU7RUFDZixhQUFhLEVBQ2Q7O0FBbEJIO0VBcUJJLHVCQUF1QjtFQUN2QixZQUFZO0VBQ1osZ0JBQWdCO0VBQ2hCLGdCQUFnQjtFQUNoQixxQkFBcUIsRUFDdEI7O0FBMUJIO0VBNkJJLGdCQUFnQjtFQUNoQixtQkFBbUIsRUFDcEI7O0FBL0JIO0VBa0NJLGVBQWU7RUFDZixZQUFZO0VBQ1osYUFBYTtFQUNiLHFDQUFzQixFQUN2Qjs7QUFHSDtFQUNFLGNBQWM7RUFDZCxnQkFBZ0I7RUFDaEIsUUFBUTtFQUNSLE9BQU8sRUFDUjs7QUFFRDtFQUNFLHdCQUF3QjtFQUN4Qix5OU5BQTQ4TixFQUFBOztBQUc5OE47RUFDRSxpQ0FBaUM7RUFDakMsZ0JBQWdCO0VBQ2hCLG1CQUFtQjtFQUNuQixvQ0FBb0M7RUFDcEMsaUNBQWlDO0VBQ2pDLG1DQUFtQyxFQUNwQzs7QUNoQ0Q7RURtQ0UsZ0JBQWdCLEVBQ2pCOztBQ2pDRDtFRG9DRSxnQkFBZ0IsRUFDakI7O0FDbENEO0VEcUNFLGdCQUFnQixFQUNqQjs7QUNuQ0Q7RURzQ0UsZ0JBQWdCLEVBQ2pCOztBQ3BDRDtFRHVDRSxnQkFBZ0IsRUFDakI7O0FDckNEO0VEd0NFLGdCQUFnQixFQUNqQlwiLFwiZmlsZVwiOlwidGFiaGVhZGVyLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLy8gSGVhZHMgdXAhIFJlbSBpcyBub3QgYSBnb29kIHdheSBmb3JcXG4vLyB3ZWV4IEhUTUw1IHJlbmRlcmVyLlxcblxcbi50YWItaGVhZGVyIHtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIHdpZHRoOiAxMHJlbTtcXG4gIGZvbnQtc2l6ZTogMTRweDtcXG4gIGNvbG9yOiAjMzMzO1xcblxcbiAgLmhlYWRlci1iYXIge1xcbiAgICBoZWlnaHQ6IDEuMTdyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAxLjE3cmVtO1xcbiAgICBkaXNwbGF5OiBub25lO1xcbiAgICBjb2xvcjogIzk5OTtcXG4gICAgcGFkZGluZy1sZWZ0OiAwLjRyZW07XFxuICB9XFxuICBcXG4gIC5oZWFkZXItYm9keSB7XFxuICAgIG1hcmdpbi1yaWdodDogMS4wN3JlbTtcXG4gICAgb3ZlcmZsb3cteDogYXV0bztcXG4gICAgb3ZlcmZsb3cteTogaGlkZGVuO1xcblxcbiAgICAmOjotd2Via2l0LXNjcm9sbGJhciB7XFxuICAgICAgd2lkdGg6IDA7XFxuICAgICAgaGVpZ2h0OiAwO1xcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47XFxuICAgIH1cXG4gIH1cXG5cXG4gIC5mb2xkLXRvZ2dsZSB7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiAwLjU5cmVtO1xcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcXG4gICAgcmlnaHQ6IDAuMjlyZW07XFxuICAgIHdpZHRoOiAwLjQ4cmVtO1xcbiAgICBoZWlnaHQ6IDAuNDhyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAwLjQ4cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHotaW5kZXg6IDk5O1xcbiAgICBmb250LXNpemU6IDE0cHg7XFxuICB9XFxuXFxuICAmLnVuZm9sZC1oZWFkZXIge1xcbiAgICBwb3NpdGlvbjogZml4ZWQgIWltcG9ydGFudDtcXG4gICAgdG9wOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xcbiAgfVxcblxcbn1cXG5cXG4udGFiaGVhZGVyIHtcXG4gIGxpc3Qtc3R5bGU6IG5vbmU7XFxuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xcbiAgaGVpZ2h0OiAxLjE3cmVtO1xcbiAgbGluZS1oZWlnaHQ6IDEuMTdyZW07XFxuXFxuICAudGgtaXRlbSB7XFxuICAgIHBhZGRpbmctbGVmdDogMC43MnJlbTtcXG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxuICB9XFxuXFxuICAuaGwtaWNvbiB7XFxuICAgIHdpZHRoOiAwLjRyZW07XFxuICAgIGhlaWdodDogMC40cmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC40cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiA1MCU7XFxuICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC01MCUpO1xcbiAgICBsZWZ0OiAwLjI0cmVtO1xcbiAgICBmb250LXNpemU6IDE0cHg7XFxuICB9XFxuXFxufVxcblxcbi51bmZvbGQtaGVhZGVyIHtcXG5cXG4gIC5oZWFkZXItYmFyIHtcXG4gICAgZGlzcGxheTogYmxvY2s7XFxuICB9XFxuXFxuICAuZm9sZC10b2dnbGUge1xcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKSByb3RhdGUoMTgwZGVnKTtcXG4gIH1cXG5cXG4gIC5oZWFkZXItYm9keSB7XFxuICAgIG1hcmdpbi1yaWdodDogMDtcXG4gICAgcGFkZGluZzogMC4yNHJlbTtcXG4gIH1cXG5cXG4gIC50YWJoZWFkZXIge1xcbiAgICBkaXNwbGF5OiBibG9jaztcXG4gICAgaGVpZ2h0OiBhdXRvO1xcbiAgfVxcblxcbiAgLnRoLWl0ZW0ge1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICBmbG9hdDogbGVmdDtcXG4gICAgd2lkdGg6IDMzLjMzMzMlO1xcbiAgICBoZWlnaHQ6IDEuMDFyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAxLjAxcmVtO1xcbiAgfVxcblxcbiAgLmhsLWljb24ge1xcbiAgICBtYXJnaW4tcmlnaHQ6IDA7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIH1cXG5cXG4gICYudGFiaGVhZGVyLW1hc2sge1xcbiAgICBkaXNwbGF5OiBibG9jaztcXG4gICAgd2lkdGg6IDEwMCU7XFxuICAgIGhlaWdodDogMTAwJTtcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjYpO1xcbiAgfVxcbn1cXG5cXG4udGFiaGVhZGVyLW1hc2sge1xcbiAgZGlzcGxheTogbm9uZTtcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXG4gIGxlZnQ6IDA7XFxuICB0b3A6IDA7XFxufVxcblxcbkBmb250LWZhY2Uge1xcbiAgZm9udC1mYW1pbHk6IFxcXCJpY29uZm9udFxcXCI7XFxuICBzcmM6IHVybChcXFwiZGF0YTphcHBsaWNhdGlvbi94LWZvbnQtdHRmO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LEFBRUFBQUFQQUlBQUF3QndSa1pVVFhCRDk4VUFBQUQ4QUFBQUhFOVRMekpYTDF6SUFBQUJHQUFBQUdCamJXRndzNklIYmdBQUFYZ0FBQUZhWTNaMElBeVYvc3dBQUFwUUFBQUFKR1p3WjIwdzk1NlZBQUFLZEFBQUNaWm5ZWE53QUFBQUVBQUFDa2dBQUFBSVoyeDVadXhvUEZJQUFBTFVBQUFFV0dobFlXUUhBNWgzQUFBSExBQUFBRFpvYUdWaEJ6SURjZ0FBQjJRQUFBQWthRzEwZUFzMkFXMEFBQWVJQUFBQUdHeHZZMkVEY0FRZUFBQUhvQUFBQUJCdFlYaHdBU2tLS3dBQUI3QUFBQUFnYm1GdFpRbC8zaGdBQUFmUUFBQUNMbkJ2YzNUbTdmMGJBQUFLQUFBQUFFaHdjbVZ3cGJtK1pnQUFGQXdBQUFDVkFBQUFBUUFBQUFETVBhTFBBQUFBQU5JREtub0FBQUFBMGdNcWV3QUVBL29COUFBRkFBQUNtUUxNQUFBQWp3S1pBc3dBQUFIckFETUJDUUFBQWdBR0F3QUFBQUFBQUFBQUFBRVFBQUFBQUFBQUFBQUFBQUJRWmtWa0FNQUFlT2JlQXl6L0xBQmNBeGdBbEFBQUFBRUFBQUFBQXhnQUFBQUFBQ0FBQVFBQUFBTUFBQUFEQUFBQUhBQUJBQUFBQUFCVUFBTUFBUUFBQUJ3QUJBQTRBQUFBQ2dBSUFBSUFBZ0I0NWxEbVllYmUvLzhBQUFCNDVsRG1ZZWJlLy8vL2l4bTBHYVFaS0FBQkFBQUFBQUFBQUFBQUFBQUFBUVlBQUFFQUFBQUFBQUFBQVFJQUFBQUNBQUFBQUFBQUFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBTUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDQUNJQUFBRXlBcW9BQXdBSEFDbEFKZ0FBQUFNQ0FBTlhBQUlCQVFKTEFBSUNBVThFQVFFQ0FVTUFBQWNHQlFRQUF3QURFUVVQS3pNUklSRW5NeEVqSWdFUTdzek1BcXI5VmlJQ1pnQUFBQVVBTFAvaEE3d0RHQUFXQURBQU9nQlNBRjRCZDB1d0UxQllRRW9DQVFBTkRnMEFEbVlBQXc0QkRnTmVBQUVJQ0FGY0VBRUpDQW9HQ1Y0UkFRd0dCQVlNWGdBTEJBdHBEd0VJQUFZTUNBWllBQW9IQlFJRUN3b0VXUklCRGc0TlVRQU5EUW9PUWh0THNCZFFXRUJMQWdFQURRNE5BQTVtQUFNT0FRNERYZ0FCQ0FnQlhCQUJDUWdLQ0FrS1poRUJEQVlFQmd4ZUFBc0VDMmtQQVFnQUJnd0lCbGdBQ2djRkFnUUxDZ1JaRWdFT0RnMVJBQTBOQ2c1Q0cwdXdHRkJZUUV3Q0FRQU5EZzBBRG1ZQUF3NEJEZ05lQUFFSUNBRmNFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNHMEJPQWdFQURRNE5BQTVtQUFNT0FRNERBV1lBQVFnT0FRaGtFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNXVmxaUUNoVFV6czdNakVYRjFOZVUxNWJXRHRTTzFKTFF6YzFNVG95T2hjd0Z6QlJFVEVZRVNnVlFCTVdLd0VHS3dFaURnSWRBU0UxTkNZMU5DNENLd0VWSVFVVkZCWVVEZ0lqQmlZckFTY2hCeXNCSWljaUxnSTlBUmNpQmhRV016STJOQ1lYQmdjT0F4NEJPd1l5TmljdUFTY21Kd0UxTkQ0Q093RXlGaDBCQVJrYkdsTVNKUndTQTVBQkNoZ25Ib1grU2dLaUFSVWZJdzRPSHc0Z0xmNUpMQjBpRkJrWklCTUlkd3dTRWd3TkVoS01DQVlGQ3dRQ0JBOE9KVU5SVUVBa0Z4WUpCUWtGQlFiK3BBVVBHaFc4SHlrQ0h3RU1HU2NhVENrUUhBUU5JQnNTWVlnMEZ6bzZKUmNKQVFHQWdBRVRHeUFPcHo4UkdoRVJHaEY4R2hZVEpBNFFEUWdZR2cwakVSTVVBWGZrQ3hnVERCMG00d0FBQWdDZy8yd0RZQUxzQUJJQUdnQWhRQjRBQUFBREFnQURXUUFDQVFFQ1RRQUNBZ0ZSQUFFQ0FVVVRGamtRQkJJckFDQUdGUlFlQXhjV093RXlQd0VTTlRRQUlpWTBOaklXRkFLUy90ek9SRlZ2TVJBSkRnRU9DVzNiL3VLRVhsNkVYZ0xzenBJMWxYeUpOaEVLQzMwQkRJeVMvczVlaEY1ZWhBQUFBQUVBZ2dCSkE0UUI2QUFkQUJ0QUdCSVJBZ0VBQVVBRkFRQStBQUFCQUdnQUFRRmZFeDhDRUNzQkpnY0dCd2tCTGdFR0J3WVVGd0V3TXhjVkZqSTNBVDRETGdJRGVoRVdBd1ArdVA2MEJoRVFCZ29LQVdFQkFRb2FDUUZlQXdRQ0FRRUNCQUhoRWcwREF2NjFBVWtIQkFVR0NSc0ovcUlCQVFrSkFXSUNCd1lIQ0FZR0FBRUFmd0NMQTRFQ0p3QWhBQjFBR2hZUEFnRUFBVUFGQVFBK0FBQUJBR2dDQVFFQlh5UXVFd01SS3lVQk1DY2pOU1lIQmdjQkRnRVVGaGNlQWpNeU53a0JGak15TmpjK0FpNEJBM2YrbndFQkVoVUVBdjZpQlFVRkJRTUhDQVFPQ1FGSUFVd0tEUVlNQlFNRkFRRUZ3d0ZlQVFFUkRRSUQvcDhGREF3TUJBTUVBZ2tCUy82MkNRVUZBd29KQ2drQUFBRUFBQUFCQUFBTEl5bm9Ydzg4OVFBTEJBQUFBQUFBMGdNcWV3QUFBQURTQXlwN0FDTC9iQU84QXhnQUFBQUlBQUlBQUFBQUFBQUFBUUFBQXhqL2JBQmNCQUFBQUFBQUE3d0FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBVUJkZ0FpQUFBQUFBRlZBQUFENlFBc0JBQUFvQUNDQUg4QUFBQW9BQ2dBS0FGa0FhSUI1QUlzQUFFQUFBQUhBRjhBQlFBQUFBQUFBZ0FtQURRQWJBQUFBSW9KbGdBQUFBQUFBQUFNQUpZQUFRQUFBQUFBQVFBSUFBQUFBUUFBQUFBQUFnQUdBQWdBQVFBQUFBQUFBd0FrQUE0QUFRQUFBQUFBQkFBSUFESUFBUUFBQUFBQUJRQkdBRG9BQVFBQUFBQUFCZ0FJQUlBQUF3QUJCQWtBQVFBUUFJZ0FBd0FCQkFrQUFnQU1BSmdBQXdBQkJBa0FBd0JJQUtRQUF3QUJCQWtBQkFBUUFPd0FBd0FCQkFrQUJRQ01BUHdBQXdBQkJBa0FCZ0FRQVlocFkyOXVabTl1ZEUxbFpHbDFiVVp2Ym5SR2IzSm5aU0F5TGpBZ09pQnBZMjl1Wm05dWRDQTZJREkyTFRndE1qQXhOV2xqYjI1bWIyNTBWbVZ5YzJsdmJpQXhMakFnT3lCMGRHWmhkWFJ2YUdsdWRDQW9kakF1T1RRcElDMXNJRGdnTFhJZ05UQWdMVWNnTWpBd0lDMTRJREUwSUMxM0lDSkhJaUF0WmlBdGMybGpiMjVtYjI1MEFHa0FZd0J2QUc0QVpnQnZBRzRBZEFCTkFHVUFaQUJwQUhVQWJRQkdBRzhBYmdCMEFFWUFid0J5QUdjQVpRQWdBRElBTGdBd0FDQUFPZ0FnQUdrQVl3QnZBRzRBWmdCdkFHNEFkQUFnQURvQUlBQXlBRFlBTFFBNEFDMEFNZ0F3QURFQU5RQnBBR01BYndCdUFHWUFid0J1QUhRQVZnQmxBSElBY3dCcEFHOEFiZ0FnQURFQUxnQXdBQ0FBT3dBZ0FIUUFkQUJtQUdFQWRRQjBBRzhBYUFCcEFHNEFkQUFnQUNnQWRnQXdBQzRBT1FBMEFDa0FJQUF0QUd3QUlBQTRBQ0FBTFFCeUFDQUFOUUF3QUNBQUxRQkhBQ0FBTWdBd0FEQUFJQUF0QUhnQUlBQXhBRFFBSUFBdEFIY0FJQUFpQUVjQUlnQWdBQzBBWmdBZ0FDMEFjd0JwQUdNQWJ3QnVBR1lBYndCdUFIUUFBQUFDQUFBQUFBQUEvNE1BTWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBY0FBQUFCQUFJQVd3RUNBUU1CQkFkMWJtbEZOalV3QjNWdWFVVTJOakVIZFc1cFJUWkVSUUFCQUFILy93QVBBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQXlBRElER1AvaEF4ai9iQU1ZLytFREdQOXNzQUFzc0NCZ1ppMndBU3dnWkNDd3dGQ3dCQ1phc0FSRlcxZ2hJeUViaWxnZ3NGQlFXQ0d3UUZrYklMQTRVRmdoc0RoWldTQ3dDa1ZoWkxBb1VGZ2hzQXBGSUxBd1VGZ2hzREJaR3lDd3dGQllJR1lnaW9waElMQUtVRmhnR3lDd0lGQllJYkFLWUJzZ3NEWlFXQ0d3Tm1BYllGbFpXUnV3QUN0WldTT3dBRkJZWlZsWkxiQUNMQ0JGSUxBRUpXRmtJTEFGUTFCWXNBVWpRckFHSTBJYklTRlpzQUZnTGJBRExDTWhJeUVnWkxFRllrSWdzQVlqUXJJS0FBSXFJU0N3QmtNZ2lpQ0tzQUFyc1RBRkpZcFJXR0JRRzJGU1dWZ2pXU0Vnc0VCVFdMQUFLeHNoc0VCWkk3QUFVRmhsV1Myd0JDeXdDQ05Dc0FjalFyQUFJMEt3QUVPd0IwTlJXTEFJUXl1eUFBRUFRMkJDc0JabEhGa3RzQVVzc0FCRElFVWdzQUpGWTdBQlJXSmdSQzJ3Qml5d0FFTWdSU0N3QUNzanNRUUVKV0FnUllvallTQmtJTEFnVUZnaHNBQWJzREJRV0xBZ0c3QkFXVmtqc0FCUVdHVlpzQU1sSTJGRVJDMndCeXl4QlFWRnNBRmhSQzJ3Q0N5d0FXQWdJTEFLUTBxd0FGQllJTEFLSTBKWnNBdERTckFBVWxnZ3NBc2pRbGt0c0Frc0lMZ0VBR0lndUFRQVk0b2pZYkFNUTJBZ2ltQWdzQXdqUWlNdHNBb3NTMVJZc1FjQlJGa2tzQTFsSTNndHNBc3NTMUZZUzFOWXNRY0JSRmtiSVZra3NCTmxJM2d0c0F3c3NRQU5RMVZZc1EwTlE3QUJZVUt3Q1N0WnNBQkRzQUlsUXJJQUFRQkRZRUt4Q2dJbFFyRUxBaVZDc0FFV0l5Q3dBeVZRV0xBQVE3QUVKVUtLaWlDS0kyR3dDQ29oSTdBQllTQ0tJMkd3Q0NvaEc3QUFRN0FDSlVLd0FpVmhzQWdxSVZtd0NrTkhzQXREUjJDd2dHSWdzQUpGWTdBQlJXSmdzUUFBRXlORXNBRkRzQUErc2dFQkFVTmdRaTJ3RFN5eEFBVkZWRmdBc0EwalFpQmdzQUZodFE0T0FRQU1BRUpDaW1DeERBUXJzR3NyR3lKWkxiQU9MTEVBRFNzdHNBOHNzUUVOS3kyd0VDeXhBZzByTGJBUkxMRUREU3N0c0JJc3NRUU5LeTJ3RXl5eEJRMHJMYkFVTExFR0RTc3RzQlVzc1FjTkt5MndGaXl4Q0EwckxiQVhMTEVKRFNzdHNCZ3NzQWNyc1FBRlJWUllBTEFOSTBJZ1lMQUJZYlVPRGdFQURBQkNRb3Bnc1F3RUs3QnJLeHNpV1Myd0dTeXhBQmdyTGJBYUxMRUJHQ3N0c0Jzc3NRSVlLeTJ3SEN5eEF4Z3JMYkFkTExFRUdDc3RzQjRzc1FVWUt5MndIeXl4QmhnckxiQWdMTEVIR0NzdHNDRXNzUWdZS3kyd0lpeXhDUmdyTGJBakxDQmdzQTVnSUVNanNBRmdRN0FDSmJBQ0pWRllJeUE4c0FGZ0k3QVNaUndiSVNGWkxiQWtMTEFqSzdBaktpMndKU3dnSUVjZ0lMQUNSV093QVVWaVlDTmhPQ01naWxWWUlFY2dJTEFDUldPd0FVVmlZQ05oT0JzaFdTMndKaXl4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0p5eXdCeXV4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0tDd2dOYkFCWUMyd0tTd0FzQU5GWTdBQlJXS3dBQ3V3QWtWanNBRkZZckFBSzdBQUZyUUFBQUFBQUVRK0l6aXhLQUVWS2kyd0tpd2dQQ0JISUxBQ1JXT3dBVVZpWUxBQVEyRTRMYkFyTEM0WFBDMndMQ3dnUENCSElMQUNSV093QVVWaVlMQUFRMkd3QVVOak9DMndMU3l4QWdBV0pTQXVJRWV3QUNOQ3NBSWxTWXFLUnlOSEkyRWdXR0liSVZtd0FTTkNzaXdCQVJVVUtpMndMaXl3QUJhd0JDV3dCQ1ZISTBjalliQUdSU3RsaWk0aklDQThpamd0c0M4c3NBQVdzQVFsc0FRbElDNUhJMGNqWVNDd0JDTkNzQVpGS3lDd1lGQllJTEJBVVZpekFpQURJQnV6QWlZREdsbENRaU1nc0FsRElJb2pSeU5ISTJFalJtQ3dCRU93Z0dKZ0lMQUFLeUNLaW1FZ3NBSkRZR1Fqc0FORFlXUlFXTEFDUTJFYnNBTkRZRm13QXlXd2dHSmhJeUFnc0FRbUkwWmhPQnNqc0FsRFJyQUNKYkFKUTBjalJ5TmhZQ0N3QkVPd2dHSmdJeUN3QUNzanNBUkRZTEFBSzdBRkpXR3dCU1d3Z0dLd0JDWmhJTEFFSldCa0k3QURKV0JrVUZnaEd5TWhXU01nSUxBRUppTkdZVGhaTGJBd0xMQUFGaUFnSUxBRkppQXVSeU5ISTJFalBEZ3RzREVzc0FBV0lMQUpJMElnSUNCR0kwZXdBQ3NqWVRndHNESXNzQUFXc0FNbHNBSWxSeU5ISTJHd0FGUllMaUE4SXlFYnNBSWxzQUlsUnlOSEkyRWdzQVVsc0FRbFJ5TkhJMkd3QmlXd0JTVkpzQUlsWWJBQlJXTWpJRmhpR3lGWlk3QUJSV0pnSXk0aklDQThpamdqSVZrdHNETXNzQUFXSUxBSlF5QXVSeU5ISTJFZ1lMQWdZR2F3Z0dJaklDQThpamd0c0RRc0l5QXVSckFDSlVaU1dDQThXUzZ4SkFFVUt5MndOU3dqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBMkxDTWdMa2F3QWlWR1VsZ2dQRmtqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBM0xMQXVLeU1nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3N0c0Rnc3NDOHJpaUFnUExBRUkwS0tPQ01nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3V3QkVNdXNDUXJMYkE1TExBQUZyQUVKYkFFSmlBdVJ5TkhJMkd3QmtVckl5QThJQzRqT0xFa0FSUXJMYkE2TExFSkJDVkNzQUFXc0FRbHNBUWxJQzVISTBjallTQ3dCQ05Dc0FaRkt5Q3dZRkJZSUxCQVVWaXpBaUFESUJ1ekFpWURHbGxDUWlNZ1I3QUVRN0NBWW1BZ3NBQXJJSXFLWVNDd0FrTmdaQ093QTBOaFpGQllzQUpEWVJ1d0EwTmdXYkFESmJDQVltR3dBaVZHWVRnaklEd2pPQnNoSUNCR0kwZXdBQ3NqWVRnaFdiRWtBUlFyTGJBN0xMQXVLeTZ4SkFFVUt5MndQQ3l3THlzaEl5QWdQTEFFSTBJak9MRWtBUlFyc0FSRExyQWtLeTJ3UFN5d0FCVWdSN0FBSTBLeUFBRUJGUlFUTHJBcUtpMndQaXl3QUJVZ1I3QUFJMEt5QUFFQkZSUVRMckFxS2kyd1B5eXhBQUVVRTdBcktpMndRQ3l3TFNvdHNFRXNzQUFXUlNNZ0xpQkdpaU5oT0xFa0FSUXJMYkJDTExBSkkwS3dRU3N0c0VNc3NnQUFPaXN0c0VRc3NnQUJPaXN0c0VVc3NnRUFPaXN0c0VZc3NnRUJPaXN0c0Vjc3NnQUFPeXN0c0Vnc3NnQUJPeXN0c0Vrc3NnRUFPeXN0c0Vvc3NnRUJPeXN0c0Vzc3NnQUFOeXN0c0V3c3NnQUJOeXN0c0Uwc3NnRUFOeXN0c0U0c3NnRUJOeXN0c0U4c3NnQUFPU3N0c0ZBc3NnQUJPU3N0c0ZFc3NnRUFPU3N0c0ZJc3NnRUJPU3N0c0ZNc3NnQUFQQ3N0c0ZRc3NnQUJQQ3N0c0ZVc3NnRUFQQ3N0c0ZZc3NnRUJQQ3N0c0Zjc3NnQUFPQ3N0c0Znc3NnQUJPQ3N0c0Zrc3NnRUFPQ3N0c0Zvc3NnRUJPQ3N0c0Zzc3NEQXJMckVrQVJRckxiQmNMTEF3SzdBMEt5MndYU3l3TUN1d05Tc3RzRjRzc0FBV3NEQXJzRFlyTGJCZkxMQXhLeTZ4SkFFVUt5MndZQ3l3TVN1d05Dc3RzR0Vzc0RFcnNEVXJMYkJpTExBeEs3QTJLeTJ3WXl5d01pc3VzU1FCRkNzdHNHUXNzRElyc0RRckxiQmxMTEF5SzdBMUt5MndaaXl3TWl1d05pc3RzR2Nzc0RNckxyRWtBUlFyTGJCb0xMQXpLN0EwS3kyd2FTeXdNeXV3TlNzdHNHb3NzRE1yc0RZckxiQnJMQ3V3Q0dXd0F5UlFlTEFCRlRBdEFBQkx1QURJVWxpeEFRR09XYmtJQUFnQVl5Q3dBU05FSUxBREkzQ3dEa1VnSUV1NEFBNVJTN0FHVTFwWXNEUWJzQ2haWUdZZ2lsVllzQUlsWWJBQlJXTWpZckFDSTBTekNna0ZCQ3V6Q2dzRkJDdXpEZzhGQkN0WnNnUW9DVVZTUkxNS0RRWUVLN0VHQVVTeEpBR0lVVml3UUloWXNRWURSTEVtQVloUldMZ0VBSWhZc1FZQlJGbFpXVm00QWYrRnNBU05zUVVBUkFBQUFBPT1cXFwiKSBmb3JtYXQoXFxcInRydWV0eXBlXFxcIik7XFxufVxcblxcbi5pY29uZm9udCB7XFxuICBmb250LWZhbWlseTogaWNvbmZvbnQgIWltcG9ydGFudDtcXG4gIGZvbnQtc2l6ZTogMTZweDtcXG4gIGZvbnQtc3R5bGU6IG5vcm1hbDtcXG4gIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xcbiAgLXdlYmtpdC10ZXh0LXN0cm9rZS13aWR0aDogMC4ycHg7XFxuICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlO1xcbn1cXG5cXG5bZGF0YS1kcHI9XFxcIjJcXFwiXSAudGFiLWhlYWRlciB7XFxuICBmb250LXNpemU6IDI4cHg7XFxufVxcblxcbltkYXRhLWRwcj1cXFwiM1xcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogNDJweDtcXG59XFxuXFxuW2RhdGEtZHByPVxcXCIyXFxcIl0gLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICBmb250LXNpemU6IDI4cHg7XFxufVxcblxcbltkYXRhLWRwcj1cXFwiM1xcXCJdIC50YWJoZWFkZXIgLmhsLWljb24ge1xcbiAgZm9udC1zaXplOiA0MnB4O1xcbn1cXG5cXG5bZGF0YS1kcHI9XFxcIjJcXFwiXSAudGFiLWhlYWRlciAuZm9sZC10b2dnbGUge1xcbiAgZm9udC1zaXplOiAyOHB4O1xcbn1cXG5cXG5bZGF0YS1kcHI9XFxcIjNcXFwiXSAudGFiLWhlYWRlciAuZm9sZC10b2dnbGUge1xcbiAgZm9udC1zaXplOiA0MnB4O1xcbn1cIixcIi50YWItaGVhZGVyIHtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIHdpZHRoOiAxMHJlbTtcXG4gIGZvbnQtc2l6ZTogMTRweDtcXG4gIGNvbG9yOiAjMzMzOyB9XFxuICAudGFiLWhlYWRlciAuaGVhZGVyLWJhciB7XFxuICAgIGhlaWdodDogMS4xN3JlbTtcXG4gICAgbGluZS1oZWlnaHQ6IDEuMTdyZW07XFxuICAgIGRpc3BsYXk6IG5vbmU7XFxuICAgIGNvbG9yOiAjOTk5O1xcbiAgICBwYWRkaW5nLWxlZnQ6IDAuNHJlbTsgfVxcbiAgLnRhYi1oZWFkZXIgLmhlYWRlci1ib2R5IHtcXG4gICAgbWFyZ2luLXJpZ2h0OiAxLjA3cmVtO1xcbiAgICBvdmVyZmxvdy14OiBhdXRvO1xcbiAgICBvdmVyZmxvdy15OiBoaWRkZW47IH1cXG4gICAgLnRhYi1oZWFkZXIgLmhlYWRlci1ib2R5Ojotd2Via2l0LXNjcm9sbGJhciB7XFxuICAgICAgd2lkdGg6IDA7XFxuICAgICAgaGVpZ2h0OiAwO1xcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47IH1cXG4gIC50YWItaGVhZGVyIC5mb2xkLXRvZ2dsZSB7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiAwLjU5cmVtO1xcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcXG4gICAgcmlnaHQ6IDAuMjlyZW07XFxuICAgIHdpZHRoOiAwLjQ4cmVtO1xcbiAgICBoZWlnaHQ6IDAuNDhyZW07XFxuICAgIGxpbmUtaGVpZ2h0OiAwLjQ4cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHotaW5kZXg6IDk5O1xcbiAgICBmb250LXNpemU6IDE0cHg7IH1cXG4gIC50YWItaGVhZGVyLnVuZm9sZC1oZWFkZXIge1xcbiAgICBwb3NpdGlvbjogZml4ZWQgIWltcG9ydGFudDtcXG4gICAgdG9wOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBvdmVyZmxvdzogaGlkZGVuOyB9XFxuXFxuLnRhYmhlYWRlciB7XFxuICBsaXN0LXN0eWxlOiBub25lO1xcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcXG4gIGhlaWdodDogMS4xN3JlbTtcXG4gIGxpbmUtaGVpZ2h0OiAxLjE3cmVtOyB9XFxuICAudGFiaGVhZGVyIC50aC1pdGVtIHtcXG4gICAgcGFkZGluZy1sZWZ0OiAwLjcycmVtO1xcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsgfVxcbiAgLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICAgIHdpZHRoOiAwLjRyZW07XFxuICAgIGhlaWdodDogMC40cmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC40cmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gICAgdG9wOiA1MCU7XFxuICAgIC13ZWJraXQtdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC01MCUpO1xcbiAgICBsZWZ0OiAwLjI0cmVtO1xcbiAgICBmb250LXNpemU6IDE0cHg7IH1cXG5cXG4udW5mb2xkLWhlYWRlciAuaGVhZGVyLWJhciB7XFxuICBkaXNwbGF5OiBibG9jazsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC5mb2xkLXRvZ2dsZSB7XFxuICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKSByb3RhdGUoMTgwZGVnKTsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC5oZWFkZXItYm9keSB7XFxuICBtYXJnaW4tcmlnaHQ6IDA7XFxuICBwYWRkaW5nOiAwLjI0cmVtOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIgLnRhYmhlYWRlciB7XFxuICBkaXNwbGF5OiBibG9jaztcXG4gIGhlaWdodDogYXV0bzsgfVxcblxcbi51bmZvbGQtaGVhZGVyIC50aC1pdGVtIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBmbG9hdDogbGVmdDtcXG4gIHdpZHRoOiAzMy4zMzMzJTtcXG4gIGhlaWdodDogMS4wMXJlbTtcXG4gIGxpbmUtaGVpZ2h0OiAxLjAxcmVtOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIgLmhsLWljb24ge1xcbiAgbWFyZ2luLXJpZ2h0OiAwO1xcbiAgcG9zaXRpb246IGFic29sdXRlOyB9XFxuXFxuLnVuZm9sZC1oZWFkZXIudGFiaGVhZGVyLW1hc2sge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogMTAwJTtcXG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC42KTsgfVxcblxcbi50YWJoZWFkZXItbWFzayB7XFxuICBkaXNwbGF5OiBub25lO1xcbiAgcG9zaXRpb246IGZpeGVkO1xcbiAgbGVmdDogMDtcXG4gIHRvcDogMDsgfVxcblxcbkBmb250LWZhY2Uge1xcbiAgZm9udC1mYW1pbHk6IFxcXCJpY29uZm9udFxcXCI7XFxuICBzcmM6IHVybChcXFwiZGF0YTphcHBsaWNhdGlvbi94LWZvbnQtdHRmO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LEFBRUFBQUFQQUlBQUF3QndSa1pVVFhCRDk4VUFBQUQ4QUFBQUhFOVRMekpYTDF6SUFBQUJHQUFBQUdCamJXRndzNklIYmdBQUFYZ0FBQUZhWTNaMElBeVYvc3dBQUFwUUFBQUFKR1p3WjIwdzk1NlZBQUFLZEFBQUNaWm5ZWE53QUFBQUVBQUFDa2dBQUFBSVoyeDVadXhvUEZJQUFBTFVBQUFFV0dobFlXUUhBNWgzQUFBSExBQUFBRFpvYUdWaEJ6SURjZ0FBQjJRQUFBQWthRzEwZUFzMkFXMEFBQWVJQUFBQUdHeHZZMkVEY0FRZUFBQUhvQUFBQUJCdFlYaHdBU2tLS3dBQUI3QUFBQUFnYm1GdFpRbC8zaGdBQUFmUUFBQUNMbkJ2YzNUbTdmMGJBQUFLQUFBQUFFaHdjbVZ3cGJtK1pnQUFGQXdBQUFDVkFBQUFBUUFBQUFETVBhTFBBQUFBQU5JREtub0FBQUFBMGdNcWV3QUVBL29COUFBRkFBQUNtUUxNQUFBQWp3S1pBc3dBQUFIckFETUJDUUFBQWdBR0F3QUFBQUFBQUFBQUFBRVFBQUFBQUFBQUFBQUFBQUJRWmtWa0FNQUFlT2JlQXl6L0xBQmNBeGdBbEFBQUFBRUFBQUFBQXhnQUFBQUFBQ0FBQVFBQUFBTUFBQUFEQUFBQUhBQUJBQUFBQUFCVUFBTUFBUUFBQUJ3QUJBQTRBQUFBQ2dBSUFBSUFBZ0I0NWxEbVllYmUvLzhBQUFCNDVsRG1ZZWJlLy8vL2l4bTBHYVFaS0FBQkFBQUFBQUFBQUFBQUFBQUFBUVlBQUFFQUFBQUFBQUFBQVFJQUFBQUNBQUFBQUFBQUFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBTUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDQUNJQUFBRXlBcW9BQXdBSEFDbEFKZ0FBQUFNQ0FBTlhBQUlCQVFKTEFBSUNBVThFQVFFQ0FVTUFBQWNHQlFRQUF3QURFUVVQS3pNUklSRW5NeEVqSWdFUTdzek1BcXI5VmlJQ1pnQUFBQVVBTFAvaEE3d0RHQUFXQURBQU9nQlNBRjRCZDB1d0UxQllRRW9DQVFBTkRnMEFEbVlBQXc0QkRnTmVBQUVJQ0FGY0VBRUpDQW9HQ1Y0UkFRd0dCQVlNWGdBTEJBdHBEd0VJQUFZTUNBWllBQW9IQlFJRUN3b0VXUklCRGc0TlVRQU5EUW9PUWh0THNCZFFXRUJMQWdFQURRNE5BQTVtQUFNT0FRNERYZ0FCQ0FnQlhCQUJDUWdLQ0FrS1poRUJEQVlFQmd4ZUFBc0VDMmtQQVFnQUJnd0lCbGdBQ2djRkFnUUxDZ1JaRWdFT0RnMVJBQTBOQ2c1Q0cwdXdHRkJZUUV3Q0FRQU5EZzBBRG1ZQUF3NEJEZ05lQUFFSUNBRmNFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNHMEJPQWdFQURRNE5BQTVtQUFNT0FRNERBV1lBQVFnT0FRaGtFQUVKQ0FvSUNRcG1FUUVNQmdRR0RBUm1BQXNFQzJrUEFRZ0FCZ3dJQmxnQUNnY0ZBZ1FMQ2dSWkVnRU9EZzFSQUEwTkNnNUNXVmxaUUNoVFV6czdNakVYRjFOZVUxNWJXRHRTTzFKTFF6YzFNVG95T2hjd0Z6QlJFVEVZRVNnVlFCTVdLd0VHS3dFaURnSWRBU0UxTkNZMU5DNENLd0VWSVFVVkZCWVVEZ0lqQmlZckFTY2hCeXNCSWljaUxnSTlBUmNpQmhRV016STJOQ1lYQmdjT0F4NEJPd1l5TmljdUFTY21Kd0UxTkQ0Q093RXlGaDBCQVJrYkdsTVNKUndTQTVBQkNoZ25Ib1grU2dLaUFSVWZJdzRPSHc0Z0xmNUpMQjBpRkJrWklCTUlkd3dTRWd3TkVoS01DQVlGQ3dRQ0JBOE9KVU5SVUVBa0Z4WUpCUWtGQlFiK3BBVVBHaFc4SHlrQ0h3RU1HU2NhVENrUUhBUU5JQnNTWVlnMEZ6bzZKUmNKQVFHQWdBRVRHeUFPcHo4UkdoRVJHaEY4R2hZVEpBNFFEUWdZR2cwakVSTVVBWGZrQ3hnVERCMG00d0FBQWdDZy8yd0RZQUxzQUJJQUdnQWhRQjRBQUFBREFnQURXUUFDQVFFQ1RRQUNBZ0ZSQUFFQ0FVVVRGamtRQkJJckFDQUdGUlFlQXhjV093RXlQd0VTTlRRQUlpWTBOaklXRkFLUy90ek9SRlZ2TVJBSkRnRU9DVzNiL3VLRVhsNkVYZ0xzenBJMWxYeUpOaEVLQzMwQkRJeVMvczVlaEY1ZWhBQUFBQUVBZ2dCSkE0UUI2QUFkQUJ0QUdCSVJBZ0VBQVVBRkFRQStBQUFCQUdnQUFRRmZFeDhDRUNzQkpnY0dCd2tCTGdFR0J3WVVGd0V3TXhjVkZqSTNBVDRETGdJRGVoRVdBd1ArdVA2MEJoRVFCZ29LQVdFQkFRb2FDUUZlQXdRQ0FRRUNCQUhoRWcwREF2NjFBVWtIQkFVR0NSc0ovcUlCQVFrSkFXSUNCd1lIQ0FZR0FBRUFmd0NMQTRFQ0p3QWhBQjFBR2hZUEFnRUFBVUFGQVFBK0FBQUJBR2dDQVFFQlh5UXVFd01SS3lVQk1DY2pOU1lIQmdjQkRnRVVGaGNlQWpNeU53a0JGak15TmpjK0FpNEJBM2YrbndFQkVoVUVBdjZpQlFVRkJRTUhDQVFPQ1FGSUFVd0tEUVlNQlFNRkFRRUZ3d0ZlQVFFUkRRSUQvcDhGREF3TUJBTUVBZ2tCUy82MkNRVUZBd29KQ2drQUFBRUFBQUFCQUFBTEl5bm9Ydzg4OVFBTEJBQUFBQUFBMGdNcWV3QUFBQURTQXlwN0FDTC9iQU84QXhnQUFBQUlBQUlBQUFBQUFBQUFBUUFBQXhqL2JBQmNCQUFBQUFBQUE3d0FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBVUJkZ0FpQUFBQUFBRlZBQUFENlFBc0JBQUFvQUNDQUg4QUFBQW9BQ2dBS0FGa0FhSUI1QUlzQUFFQUFBQUhBRjhBQlFBQUFBQUFBZ0FtQURRQWJBQUFBSW9KbGdBQUFBQUFBQUFNQUpZQUFRQUFBQUFBQVFBSUFBQUFBUUFBQUFBQUFnQUdBQWdBQVFBQUFBQUFBd0FrQUE0QUFRQUFBQUFBQkFBSUFESUFBUUFBQUFBQUJRQkdBRG9BQVFBQUFBQUFCZ0FJQUlBQUF3QUJCQWtBQVFBUUFJZ0FBd0FCQkFrQUFnQU1BSmdBQXdBQkJBa0FBd0JJQUtRQUF3QUJCQWtBQkFBUUFPd0FBd0FCQkFrQUJRQ01BUHdBQXdBQkJBa0FCZ0FRQVlocFkyOXVabTl1ZEUxbFpHbDFiVVp2Ym5SR2IzSm5aU0F5TGpBZ09pQnBZMjl1Wm05dWRDQTZJREkyTFRndE1qQXhOV2xqYjI1bWIyNTBWbVZ5YzJsdmJpQXhMakFnT3lCMGRHWmhkWFJ2YUdsdWRDQW9kakF1T1RRcElDMXNJRGdnTFhJZ05UQWdMVWNnTWpBd0lDMTRJREUwSUMxM0lDSkhJaUF0WmlBdGMybGpiMjVtYjI1MEFHa0FZd0J2QUc0QVpnQnZBRzRBZEFCTkFHVUFaQUJwQUhVQWJRQkdBRzhBYmdCMEFFWUFid0J5QUdjQVpRQWdBRElBTGdBd0FDQUFPZ0FnQUdrQVl3QnZBRzRBWmdCdkFHNEFkQUFnQURvQUlBQXlBRFlBTFFBNEFDMEFNZ0F3QURFQU5RQnBBR01BYndCdUFHWUFid0J1QUhRQVZnQmxBSElBY3dCcEFHOEFiZ0FnQURFQUxnQXdBQ0FBT3dBZ0FIUUFkQUJtQUdFQWRRQjBBRzhBYUFCcEFHNEFkQUFnQUNnQWRnQXdBQzRBT1FBMEFDa0FJQUF0QUd3QUlBQTRBQ0FBTFFCeUFDQUFOUUF3QUNBQUxRQkhBQ0FBTWdBd0FEQUFJQUF0QUhnQUlBQXhBRFFBSUFBdEFIY0FJQUFpQUVjQUlnQWdBQzBBWmdBZ0FDMEFjd0JwQUdNQWJ3QnVBR1lBYndCdUFIUUFBQUFDQUFBQUFBQUEvNE1BTWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBY0FBQUFCQUFJQVd3RUNBUU1CQkFkMWJtbEZOalV3QjNWdWFVVTJOakVIZFc1cFJUWkVSUUFCQUFILy93QVBBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQXlBRElER1AvaEF4ai9iQU1ZLytFREdQOXNzQUFzc0NCZ1ppMndBU3dnWkNDd3dGQ3dCQ1phc0FSRlcxZ2hJeUViaWxnZ3NGQlFXQ0d3UUZrYklMQTRVRmdoc0RoWldTQ3dDa1ZoWkxBb1VGZ2hzQXBGSUxBd1VGZ2hzREJaR3lDd3dGQllJR1lnaW9waElMQUtVRmhnR3lDd0lGQllJYkFLWUJzZ3NEWlFXQ0d3Tm1BYllGbFpXUnV3QUN0WldTT3dBRkJZWlZsWkxiQUNMQ0JGSUxBRUpXRmtJTEFGUTFCWXNBVWpRckFHSTBJYklTRlpzQUZnTGJBRExDTWhJeUVnWkxFRllrSWdzQVlqUXJJS0FBSXFJU0N3QmtNZ2lpQ0tzQUFyc1RBRkpZcFJXR0JRRzJGU1dWZ2pXU0Vnc0VCVFdMQUFLeHNoc0VCWkk3QUFVRmhsV1Myd0JDeXdDQ05Dc0FjalFyQUFJMEt3QUVPd0IwTlJXTEFJUXl1eUFBRUFRMkJDc0JabEhGa3RzQVVzc0FCRElFVWdzQUpGWTdBQlJXSmdSQzJ3Qml5d0FFTWdSU0N3QUNzanNRUUVKV0FnUllvallTQmtJTEFnVUZnaHNBQWJzREJRV0xBZ0c3QkFXVmtqc0FCUVdHVlpzQU1sSTJGRVJDMndCeXl4QlFWRnNBRmhSQzJ3Q0N5d0FXQWdJTEFLUTBxd0FGQllJTEFLSTBKWnNBdERTckFBVWxnZ3NBc2pRbGt0c0Frc0lMZ0VBR0lndUFRQVk0b2pZYkFNUTJBZ2ltQWdzQXdqUWlNdHNBb3NTMVJZc1FjQlJGa2tzQTFsSTNndHNBc3NTMUZZUzFOWXNRY0JSRmtiSVZra3NCTmxJM2d0c0F3c3NRQU5RMVZZc1EwTlE3QUJZVUt3Q1N0WnNBQkRzQUlsUXJJQUFRQkRZRUt4Q2dJbFFyRUxBaVZDc0FFV0l5Q3dBeVZRV0xBQVE3QUVKVUtLaWlDS0kyR3dDQ29oSTdBQllTQ0tJMkd3Q0NvaEc3QUFRN0FDSlVLd0FpVmhzQWdxSVZtd0NrTkhzQXREUjJDd2dHSWdzQUpGWTdBQlJXSmdzUUFBRXlORXNBRkRzQUErc2dFQkFVTmdRaTJ3RFN5eEFBVkZWRmdBc0EwalFpQmdzQUZodFE0T0FRQU1BRUpDaW1DeERBUXJzR3NyR3lKWkxiQU9MTEVBRFNzdHNBOHNzUUVOS3kyd0VDeXhBZzByTGJBUkxMRUREU3N0c0JJc3NRUU5LeTJ3RXl5eEJRMHJMYkFVTExFR0RTc3RzQlVzc1FjTkt5MndGaXl4Q0EwckxiQVhMTEVKRFNzdHNCZ3NzQWNyc1FBRlJWUllBTEFOSTBJZ1lMQUJZYlVPRGdFQURBQkNRb3Bnc1F3RUs3QnJLeHNpV1Myd0dTeXhBQmdyTGJBYUxMRUJHQ3N0c0Jzc3NRSVlLeTJ3SEN5eEF4Z3JMYkFkTExFRUdDc3RzQjRzc1FVWUt5MndIeXl4QmhnckxiQWdMTEVIR0NzdHNDRXNzUWdZS3kyd0lpeXhDUmdyTGJBakxDQmdzQTVnSUVNanNBRmdRN0FDSmJBQ0pWRllJeUE4c0FGZ0k3QVNaUndiSVNGWkxiQWtMTEFqSzdBaktpMndKU3dnSUVjZ0lMQUNSV093QVVWaVlDTmhPQ01naWxWWUlFY2dJTEFDUldPd0FVVmlZQ05oT0JzaFdTMndKaXl4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0p5eXdCeXV4QUFWRlZGZ0FzQUVXc0NVcXNBRVZNQnNpV1Myd0tDd2dOYkFCWUMyd0tTd0FzQU5GWTdBQlJXS3dBQ3V3QWtWanNBRkZZckFBSzdBQUZyUUFBQUFBQUVRK0l6aXhLQUVWS2kyd0tpd2dQQ0JISUxBQ1JXT3dBVVZpWUxBQVEyRTRMYkFyTEM0WFBDMndMQ3dnUENCSElMQUNSV093QVVWaVlMQUFRMkd3QVVOak9DMndMU3l4QWdBV0pTQXVJRWV3QUNOQ3NBSWxTWXFLUnlOSEkyRWdXR0liSVZtd0FTTkNzaXdCQVJVVUtpMndMaXl3QUJhd0JDV3dCQ1ZISTBjalliQUdSU3RsaWk0aklDQThpamd0c0M4c3NBQVdzQVFsc0FRbElDNUhJMGNqWVNDd0JDTkNzQVpGS3lDd1lGQllJTEJBVVZpekFpQURJQnV6QWlZREdsbENRaU1nc0FsRElJb2pSeU5ISTJFalJtQ3dCRU93Z0dKZ0lMQUFLeUNLaW1FZ3NBSkRZR1Fqc0FORFlXUlFXTEFDUTJFYnNBTkRZRm13QXlXd2dHSmhJeUFnc0FRbUkwWmhPQnNqc0FsRFJyQUNKYkFKUTBjalJ5TmhZQ0N3QkVPd2dHSmdJeUN3QUNzanNBUkRZTEFBSzdBRkpXR3dCU1d3Z0dLd0JDWmhJTEFFSldCa0k3QURKV0JrVUZnaEd5TWhXU01nSUxBRUppTkdZVGhaTGJBd0xMQUFGaUFnSUxBRkppQXVSeU5ISTJFalBEZ3RzREVzc0FBV0lMQUpJMElnSUNCR0kwZXdBQ3NqWVRndHNESXNzQUFXc0FNbHNBSWxSeU5ISTJHd0FGUllMaUE4SXlFYnNBSWxzQUlsUnlOSEkyRWdzQVVsc0FRbFJ5TkhJMkd3QmlXd0JTVkpzQUlsWWJBQlJXTWpJRmhpR3lGWlk3QUJSV0pnSXk0aklDQThpamdqSVZrdHNETXNzQUFXSUxBSlF5QXVSeU5ISTJFZ1lMQWdZR2F3Z0dJaklDQThpamd0c0RRc0l5QXVSckFDSlVaU1dDQThXUzZ4SkFFVUt5MndOU3dqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBMkxDTWdMa2F3QWlWR1VsZ2dQRmtqSUM1R3NBSWxSbEJZSUR4WkxyRWtBUlFyTGJBM0xMQXVLeU1nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3N0c0Rnc3NDOHJpaUFnUExBRUkwS0tPQ01nTGthd0FpVkdVbGdnUEZrdXNTUUJGQ3V3QkVNdXNDUXJMYkE1TExBQUZyQUVKYkFFSmlBdVJ5TkhJMkd3QmtVckl5QThJQzRqT0xFa0FSUXJMYkE2TExFSkJDVkNzQUFXc0FRbHNBUWxJQzVISTBjallTQ3dCQ05Dc0FaRkt5Q3dZRkJZSUxCQVVWaXpBaUFESUJ1ekFpWURHbGxDUWlNZ1I3QUVRN0NBWW1BZ3NBQXJJSXFLWVNDd0FrTmdaQ093QTBOaFpGQllzQUpEWVJ1d0EwTmdXYkFESmJDQVltR3dBaVZHWVRnaklEd2pPQnNoSUNCR0kwZXdBQ3NqWVRnaFdiRWtBUlFyTGJBN0xMQXVLeTZ4SkFFVUt5MndQQ3l3THlzaEl5QWdQTEFFSTBJak9MRWtBUlFyc0FSRExyQWtLeTJ3UFN5d0FCVWdSN0FBSTBLeUFBRUJGUlFUTHJBcUtpMndQaXl3QUJVZ1I3QUFJMEt5QUFFQkZSUVRMckFxS2kyd1B5eXhBQUVVRTdBcktpMndRQ3l3TFNvdHNFRXNzQUFXUlNNZ0xpQkdpaU5oT0xFa0FSUXJMYkJDTExBSkkwS3dRU3N0c0VNc3NnQUFPaXN0c0VRc3NnQUJPaXN0c0VVc3NnRUFPaXN0c0VZc3NnRUJPaXN0c0Vjc3NnQUFPeXN0c0Vnc3NnQUJPeXN0c0Vrc3NnRUFPeXN0c0Vvc3NnRUJPeXN0c0Vzc3NnQUFOeXN0c0V3c3NnQUJOeXN0c0Uwc3NnRUFOeXN0c0U0c3NnRUJOeXN0c0U4c3NnQUFPU3N0c0ZBc3NnQUJPU3N0c0ZFc3NnRUFPU3N0c0ZJc3NnRUJPU3N0c0ZNc3NnQUFQQ3N0c0ZRc3NnQUJQQ3N0c0ZVc3NnRUFQQ3N0c0ZZc3NnRUJQQ3N0c0Zjc3NnQUFPQ3N0c0Znc3NnQUJPQ3N0c0Zrc3NnRUFPQ3N0c0Zvc3NnRUJPQ3N0c0Zzc3NEQXJMckVrQVJRckxiQmNMTEF3SzdBMEt5MndYU3l3TUN1d05Tc3RzRjRzc0FBV3NEQXJzRFlyTGJCZkxMQXhLeTZ4SkFFVUt5MndZQ3l3TVN1d05Dc3RzR0Vzc0RFcnNEVXJMYkJpTExBeEs3QTJLeTJ3WXl5d01pc3VzU1FCRkNzdHNHUXNzRElyc0RRckxiQmxMTEF5SzdBMUt5MndaaXl3TWl1d05pc3RzR2Nzc0RNckxyRWtBUlFyTGJCb0xMQXpLN0EwS3kyd2FTeXdNeXV3TlNzdHNHb3NzRE1yc0RZckxiQnJMQ3V3Q0dXd0F5UlFlTEFCRlRBdEFBQkx1QURJVWxpeEFRR09XYmtJQUFnQVl5Q3dBU05FSUxBREkzQ3dEa1VnSUV1NEFBNVJTN0FHVTFwWXNEUWJzQ2haWUdZZ2lsVllzQUlsWWJBQlJXTWpZckFDSTBTekNna0ZCQ3V6Q2dzRkJDdXpEZzhGQkN0WnNnUW9DVVZTUkxNS0RRWUVLN0VHQVVTeEpBR0lVVml3UUloWXNRWURSTEVtQVloUldMZ0VBSWhZc1FZQlJGbFpXVm00QWYrRnNBU05zUVVBUkFBQUFBPT1cXFwiKSBmb3JtYXQoXFxcInRydWV0eXBlXFxcIik7IH1cXG5cXG4uaWNvbmZvbnQge1xcbiAgZm9udC1mYW1pbHk6IGljb25mb250ICFpbXBvcnRhbnQ7XFxuICBmb250LXNpemU6IDE2cHg7XFxuICBmb250LXN0eWxlOiBub3JtYWw7XFxuICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcXG4gIC13ZWJraXQtdGV4dC1zdHJva2Utd2lkdGg6IDAuMnB4O1xcbiAgLW1vei1vc3gtZm9udC1zbW9vdGhpbmc6IGdyYXlzY2FsZTsgfVxcblxcbltkYXRhLWRwcj1cXFwiMlxcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogMjhweDsgfVxcblxcbltkYXRhLWRwcj1cXFwiM1xcXCJdIC50YWItaGVhZGVyIHtcXG4gIGZvbnQtc2l6ZTogNDJweDsgfVxcblxcbltkYXRhLWRwcj1cXFwiMlxcXCJdIC50YWJoZWFkZXIgLmhsLWljb24ge1xcbiAgZm9udC1zaXplOiAyOHB4OyB9XFxuXFxuW2RhdGEtZHByPVxcXCIzXFxcIl0gLnRhYmhlYWRlciAuaGwtaWNvbiB7XFxuICBmb250LXNpemU6IDQycHg7IH1cXG5cXG5bZGF0YS1kcHI9XFxcIjJcXFwiXSAudGFiLWhlYWRlciAuZm9sZC10b2dnbGUge1xcbiAgZm9udC1zaXplOiAyOHB4OyB9XFxuXFxuW2RhdGEtZHByPVxcXCIzXFxcIl0gLnRhYi1oZWFkZXIgLmZvbGQtdG9nZ2xlIHtcXG4gIGZvbnQtc2l6ZTogNDJweDsgfVxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Nhc3MtbG9hZGVyP3NvdXJjZU1hcCEuL3NyYy9zdHlsZXMvdGFiaGVhZGVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA1MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnJlcXVpcmUoJy4uL3N0eWxlcy9zY3JvbGxlci5zY3NzJylcbnJlcXVpcmUoJ3Njcm9sbGpzJylcblxuLy8gbGliLnNjcm9sbCBldmVudHM6XG4vLyAgLSBzY3JvbGxzdGFydFxuLy8gIC0gc2Nyb2xsaW5nXG4vLyAgLSBwdWxsZG93bmVuZFxuLy8gIC0gcHVsbHVwZW5kXG4vLyAgLSBwdWxsbGVmdGVuZFxuLy8gIC0gcHVsbHJpZ2h0ZW5kXG4vLyAgLSBwdWxsZG93blxuLy8gIC0gcHVsbHVwXG4vLyAgLSBwdWxsbGVmdFxuLy8gIC0gcHVsbHJpZ2h0XG4vLyAgLSBjb250ZW50cmVmcmVzaFxuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jb21wb25lbnQnKVxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKVxuXG4vLyBhdHRyczpcbi8vICAtIHNjcm9sbC1kaXJlY2l0b246IG5vbmV8dmVydGljYWx8aG9yaXpvbnRhbCAoZGVmYXVsdCBpcyB2ZXJ0aWNhbClcbi8vICAtIHNob3ctc2Nyb2xsYmFyOiB0cnVlfGZhbHNlIChkZWZhdWx0IGlzIHRydWUpXG5mdW5jdGlvbiBTY3JvbGxlciAoZGF0YSwgbm9kZVR5cGUpIHtcbiAgdmFyIGF0dHJzID0gZGF0YS5hdHRyIHx8IHt9XG4gIHRoaXMuaXRlbXMgPSBbXVxuICB0aGlzLnRvdGFsV2lkdGggPSAwXG4gIHRoaXMuc2Nyb2xsRGlyZWN0aW9uID0gYXR0cnMuc2Nyb2xsRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPyAnaG9yaXpvbnRhbCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgOiAndmVydGljYWwnXG4gIHRoaXMuc2hvd1Njcm9sbGJhciA9IGF0dHJzLnNob3dTY3JvbGxiYXIgfHwgdHJ1ZVxuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhLCBub2RlVHlwZSlcbn1cblxuU2Nyb2xsZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDb21wb25lbnQucHJvdG90eXBlKVxuXG5TY3JvbGxlci5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKG5vZGVUeXBlKSB7XG4gIHZhciBTY3JvbGwgPSBsaWIuc2Nyb2xsXG4gIHZhciBub2RlID0gQ29tcG9uZW50LnByb3RvdHlwZS5jcmVhdGUuY2FsbCh0aGlzLCBub2RlVHlwZSlcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKCd3ZWV4LWNvbnRhaW5lcicsICdzY3JvbGwtd3JhcCcpXG4gIHRoaXMuc2Nyb2xsRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIHRoaXMuc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QuYWRkKFxuICAgICd3ZWV4LWNvbnRhaW5lcicsXG4gICAgJ3Njcm9sbC1lbGVtZW50JyxcbiAgICB0aGlzLnNjcm9sbERpcmVjdGlvblxuICApXG4gIG5vZGUuYXBwZW5kQ2hpbGQodGhpcy5zY3JvbGxFbGVtZW50KVxuICB0aGlzLnNjcm9sbGVyID0gbmV3IFNjcm9sbCh7XG4gICAgc2Nyb2xsRWxlbWVudDogdGhpcy5zY3JvbGxFbGVtZW50LFxuICAgIGRpcmVjdGlvbjogdGhpcy5zY3JvbGxEaXJlY3Rpb24gPT09ICd2ZXJ0aWNhbCcgPyAneScgOiAneCdcbiAgfSlcbiAgdGhpcy5zY3JvbGxlci5pbml0KClcbiAgcmV0dXJuIG5vZGVcbn1cblxuU2Nyb2xsZXIucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoZXZ0cykge1xuICBDb21wb25lbnQucHJvdG90eXBlLmJpbmRFdmVudHMuY2FsbCh0aGlzLCBldnRzKVxuICAvLyB0byBlbmFibGUgbGF6eWxvYWQgZm9yIEltYWdlc1xuICB0aGlzLnNjcm9sbGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbGluZycsIGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIHNvID0gZS5zY3JvbGxPYmpcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ3Njcm9sbCcsIHtcbiAgICAgIG9yaWdpbmFsVHlwZTogJ3Njcm9sbGluZycsXG4gICAgICBzY3JvbGxUb3A6IHNvLmdldFNjcm9sbFRvcCgpLFxuICAgICAgc2Nyb2xsTGVmdDogc28uZ2V0U2Nyb2xsTGVmdCgpXG4gICAgfSwge1xuICAgICAgYnViYmxlczogdHJ1ZVxuICAgIH0pXG4gIH0uYmluZCh0aGlzKSlcbn1cblxuU2Nyb2xsZXIucHJvdG90eXBlLmFwcGVuZENoaWxkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgdmFyIGNoaWxkID0gY29tcG9uZW50TWFuYWdlci5jcmVhdGVFbGVtZW50KGRhdGEpXG4gIHRoaXMuc2Nyb2xsRWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZC5ub2RlKVxuXG4gIHZhciBjaGlsZFdpZHRoID0gY2hpbGQubm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aFxuICB0aGlzLnRvdGFsV2lkdGggKz0gY2hpbGRXaWR0aFxuICAvLyBpZiBkaXJlY3Rpb24gaXMgaG9yaXpvbnRhbCB0aGVuIHRoZSB3aWR0aCBvZiBzY3JvbGxFbGVtZW50XG4gIC8vIHNob3VsZCBiZSBzZXQgbWFudWFsbHkgZHVlIHRvIGZsZXhib3gncyBydWxlIChjaGlsZCBlbGVtZW50c1xuICAvLyB3aWxsIG5vdCBleGNlZWQgYm94J3Mgd2lkdGggYnV0IHRvIHNocmluayB0byBhZGFwdCkuXG4gIGlmICh0aGlzLnNjcm9sbERpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgdGhpcy5zY3JvbGxFbGVtZW50LnN0eWxlLndpZHRoID0gdGhpcy50b3RhbFdpZHRoICsgJ3B4J1xuICB9XG5cbiAgLy8gdXBkYXRlIHRoaXMuZGF0YS5jaGlsZHJlblxuICBpZiAoIWNoaWxkcmVuIHx8ICFjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICB0aGlzLmRhdGEuY2hpbGRyZW4gPSBbZGF0YV1cbiAgfSBlbHNlIHtcbiAgICBjaGlsZHJlbi5wdXNoKGRhdGEpXG4gIH1cblxuICB0aGlzLml0ZW1zLnB1c2goY2hpbGQpXG4gIHJldHVybiBjaGlsZFxufVxuXG5TY3JvbGxlci5wcm90b3R5cGUuaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGNoaWxkLCBiZWZvcmUpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIHZhciBpID0gMFxuICB2YXIgaXNBcHBlbmQgPSBmYWxzZVxuXG4gIC8vIHVwZGF0ZSB0aGlzLmRhdGEuY2hpbGRyZW5cbiAgaWYgKCFjaGlsZHJlbiB8fCAhY2hpbGRyZW4ubGVuZ3RoIHx8ICFiZWZvcmUpIHtcbiAgICBpc0FwcGVuZCA9IHRydWVcbiAgfSBlbHNlIHtcbiAgICBmb3IgKHZhciBsID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBpZiAoY2hpbGRyZW5baV0ucmVmID09PSBjaGlsZC5kYXRhLnJlZikge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaSA9PT0gbCkge1xuICAgICAgaXNBcHBlbmQgPSB0cnVlXG4gICAgfVxuICB9XG5cbiAgaWYgKGlzQXBwZW5kKSB7XG4gICAgdGhpcy5zY3JvbGxFbGVtZW50LmFwcGVuZENoaWxkKGNoaWxkLm5vZGUpXG4gICAgY2hpbGRyZW4ucHVzaChjaGlsZC5kYXRhKVxuICAgIHRoaXMuaXRlbXMucHVzaChjaGlsZClcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnNjcm9sbEVsZW1lbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLm5vZGUsIGJlZm9yZS5ub2RlKVxuICAgIGNoaWxkcmVuLnNwbGljZShpLCAwLCBjaGlsZC5kYXRhKVxuICAgIHRoaXMuaXRlbXMuc3BsaWNlKGksIDAsIGNoaWxkKVxuICB9XG59XG5cblNjcm9sbGVyLnByb3RvdHlwZS5yZW1vdmVDaGlsZCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNoaWxkcmVuID0gdGhpcy5kYXRhLmNoaWxkcmVuXG4gIC8vIHJlbW92ZSBmcm9tIHRoaXMuZGF0YS5jaGlsZHJlblxuICB2YXIgaSA9IDBcbiAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICBpZiAoY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgZm9yICh2YXIgbCA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgaWYgKGNoaWxkcmVuW2ldLnJlZiA9PT0gY2hpbGQuZGF0YS5yZWYpIHtcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGkgPCBsKSB7XG4gICAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMSlcbiAgICAgIHRoaXMuaXRlbXMuc3BsaWNlKGksIDEpXG4gICAgfVxuICB9XG4gIC8vIHJlbW92ZSBmcm9tIGNvbXBvbmVudE1hcCByZWN1cnNpdmVseVxuICBjb21wb25lbnRNYW5hZ2VyLnJlbW92ZUVsZW1lbnRCeVJlZihjaGlsZC5kYXRhLnJlZilcbiAgdGhpcy5zY3JvbGxFbGVtZW50LnJlbW92ZUNoaWxkKGNoaWxkLm5vZGUpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2Nyb2xsZXJcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9zY3JvbGxlci5qc1xuICoqIG1vZHVsZSBpZCA9IDUxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vc2Nyb2xsZXIuc2Nzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3Njcm9sbGVyLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3Njcm9sbGVyLnNjc3NcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvc3R5bGVzL3Njcm9sbGVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA1MlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCIuc2Nyb2xsLXdyYXAge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICBvdmVyZmxvdzogaGlkZGVuOyB9XFxuXFxuLnNjcm9sbC1lbGVtZW50Lmhvcml6b250YWwge1xcbiAgLXdlYmtpdC1ib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogcm93O1xcbiAgZmxleC1kaXJlY3Rpb246IHJvdzsgfVxcblxcbi5zY3JvbGwtZWxlbWVudC52ZXJ0aWNhbCB7XFxuICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xcbiAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9zY3JvbGxlci5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0MsZUFBZTtFQUNmLGlCQUFpQixFQUNqQjs7QUFFRDtFQUVJLCtCQUErQjtFQUMvQiw0QkFBNEI7RUFDNUIsb0JBQW9CLEVBQ3JCOztBQUxIO0VBT0ksNkJBQTZCO0VBQzdCLCtCQUErQjtFQUMvQix1QkFBdUIsRUFDeEJcIixcImZpbGVcIjpcInNjcm9sbGVyLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLnNjcm9sbC13cmFwIHtcXG5cXHRkaXNwbGF5OiBibG9jaztcXG5cXHRvdmVyZmxvdzogaGlkZGVuO1xcbn1cXG5cXG4uc2Nyb2xsLWVsZW1lbnQge1xcbiAgJi5ob3Jpem9udGFsIHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiBob3Jpem9udGFsO1xcbiAgICAtd2Via2l0LWZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XFxuICB9XFxuICAmLnZlcnRpY2FsIHtcXG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcXG4gICAgLXdlYmtpdC1mbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcbiAgfVxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9zcmMvc3R5bGVzL3Njcm9sbGVyLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA1M1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpXG5cbi8vIGF0dHJzOlxuLy8gICAtIHR5cGU6IHRleHR8cGFzc3dvcmR8dGVsfGVtYWlsfHVybFxuLy8gICAtIHZhbHVlXG4vLyAgIC0gcGxhY2Vob2xkZXJcbi8vICAgLSBkaXNhYmxlZFxuLy8gICAtIGF1dG9mb2N1c1xuZnVuY3Rpb24gSW5wdXQgKGRhdGEpIHtcbiAgdmFyIGF0dHJzID0gZGF0YS5hdHRyIHx8IHt9XG4gIHRoaXMudHlwZSA9IGF0dHJzLnR5cGUgfHwgJ3RleHQnXG4gIHRoaXMudmFsdWUgPSBhdHRycy52YWx1ZVxuICB0aGlzLnBsYWNlaG9sZGVyID0gYXR0cnMucGxhY2Vob2xkZXJcbiAgdGhpcy5hdXRvZm9jdXMgPSBhdHRycy5hdXRvZm9jdXMgJiYgKGF0dHJzLmF1dG9mb2N1cyAhPT0gJ2ZhbHNlJylcbiAgICAgICAgICAgICAgICAgICAgPyB0cnVlXG4gICAgICAgICAgICAgICAgICAgIDogZmFsc2VcbiAgQXRvbWljLmNhbGwodGhpcywgZGF0YSlcbn1cblxuSW5wdXQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5JbnB1dC5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0JylcbiAgdmFyIHV1aWQgPSBNYXRoLmZsb29yKDEwMDAwMDAwMDAwMDAwICogTWF0aC5yYW5kb20oKSkgKyBEYXRlLm5vdygpXG4gIHRoaXMuY2xhc3NOYW1lID0gJ3dlZXgtaXB0LScgKyB1dWlkXG4gIHRoaXMuc3R5bGVJZCA9ICd3ZWV4LXN0eWxlLScgKyB1dWlkXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCh0aGlzLmNsYXNzTmFtZSlcbiAgbm9kZS5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCB0aGlzLnR5cGUpXG4gIG5vZGUudHlwZSA9IHRoaXMudHlwZVxuICAvLyBGb3IgdGhlIGNvbnNpc3RlbmN5IG9mIGlucHV0IGNvbXBvbmVudCdzIHdpZHRoLlxuICAvLyBUaGUgZGF0ZSBhbmQgdGltZSB0eXBlIG9mIGlucHV0IHdpbGwgaGF2ZSBhIGJpZ2dlciB3aWR0aFxuICAvLyB3aGVuIHRoZSAnYm94LXNpemluZycgaXMgbm90IHNldCB0byAnYm9yZGVyLWJveCdcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKCd3ZWV4LWVsZW1lbnQnKVxuICB0aGlzLnZhbHVlICYmIChub2RlLnZhbHVlID0gdGhpcy52YWx1ZSlcbiAgdGhpcy5wbGFjZWhvbGRlciAmJiAobm9kZS5wbGFjZWhvbGRlciA9IHRoaXMucGxhY2Vob2xkZXIpXG4gIHJldHVybiBub2RlXG59XG5cbklucHV0LnByb3RvdHlwZS51cGRhdGVTdHlsZSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICBBdG9taWMucHJvdG90eXBlLnVwZGF0ZVN0eWxlLmNhbGwodGhpcywgc3R5bGUpXG4gIGlmIChzdHlsZSAmJiBzdHlsZS5wbGFjZWhvbGRlckNvbG9yKSB7XG4gICAgdGhpcy5wbGFjZWhvbGRlckNvbG9yID0gc3R5bGUucGxhY2Vob2xkZXJDb2xvclxuICAgIHRoaXMuc2V0UGxhY2Vob2xkZXJDb2xvcigpXG4gIH1cbn1cblxuSW5wdXQucHJvdG90eXBlLmF0dHIgPSB7XG4gIGRpc2FibGVkOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdGhpcy5ub2RlLmRpc2FibGVkID0gdmFsICYmIHZhbCAhPT0gJ2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICA/IHRydWVcbiAgICAgICAgICAgICAgICAgICAgOiBmYWxzZVxuICB9XG59XG5cbklucHV0LnByb3RvdHlwZS5zZXRQbGFjZWhvbGRlckNvbG9yID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMucGxhY2Vob2xkZXJDb2xvcikge1xuICAgIHJldHVyblxuICB9XG4gIHZhciB2ZW5kb3JzID0gW1xuICAgICc6Oi13ZWJraXQtaW5wdXQtcGxhY2Vob2xkZXInLFxuICAgICc6LW1vei1wbGFjZWhvbGRlcicsXG4gICAgJzo6LW1vei1wbGFjZWhvbGRlcicsXG4gICAgJzotbXMtaW5wdXQtcGxhY2Vob2xkZXInLFxuICAgICc6cGxhY2Vob2xkZXItc2hvd24nXG4gIF1cbiAgdmFyIGNzcyA9ICcnXG4gIHZhciBjc3NSdWxlID0gJ2NvbG9yOiAnICsgdGhpcy5wbGFjZWhvbGRlckNvbG9yICsgJzsnXG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmVuZG9ycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBjc3MgKz0gJy4nICsgdGhpcy5jbGFzc05hbWUgKyB2ZW5kb3JzW2ldICsgJ3snXG4gICAgICAgICAgICsgY3NzUnVsZSArICd9J1xuICB9XG4gIHV0aWxzLmFwcGVuZFN0eWxlKGNzcywgdGhpcy5zdHlsZUlkLCB0cnVlKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IElucHV0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvaW5wdXQuanNcbiAqKiBtb2R1bGUgaWQgPSA1NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2NvbXBvbmVudCcpXG52YXIgc2VuZGVyID0gcmVxdWlyZSgnLi4vYnJpZGdlL3NlbmRlcicpXG5cbi8vIGF0dHJzOlxuLy8gICAtIG9wdGlvbnM6IHRoZSBvcHRpb25zIHRvIGJlIGxpc3RlZCwgYXMgYSBhcnJheSBvZiBzdHJpbmdzLlxuLy8gICAtIHNlbGVjdGVkSW5kZXg6IHRoZSBzZWxlY3RlZCBvcHRpb25zJyBpbmRleCBudW1iZXIuXG4vLyAgIC0gZGlzYWJsZWRcbmZ1bmN0aW9uIFNlbGVjdCAoZGF0YSkge1xuICB2YXIgYXR0cnMgPSBkYXRhLmF0dHIgfHwge31cbiAgdGhpcy5vcHRpb25zID0gW11cbiAgdGhpcy5zZWxlY3RlZEluZGV4ID0gMFxuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5TZWxlY3QucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5TZWxlY3QucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzZWxlY3QnKVxuICB2YXIgdXVpZCA9IE1hdGguZmxvb3IoMTAwMDAwMDAwMDAwMDAgKiBNYXRoLnJhbmRvbSgpKSArIERhdGUubm93KClcbiAgdGhpcy5jbGFzc05hbWUgPSAnd2VleC1zbGN0LScgKyB1dWlkXG4gIHRoaXMuc3R5bGVJZCA9ICd3ZWV4LXN0eWxlLScgKyB1dWlkXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCh0aGlzLmNsYXNzTmFtZSlcbiAgLy8gRm9yIHRoZSBjb25zaXN0ZW5jeSBvZiBpbnB1dCBjb21wb25lbnQncyB3aWR0aC5cbiAgLy8gVGhlIGRhdGUgYW5kIHRpbWUgdHlwZSBvZiBpbnB1dCB3aWxsIGhhdmUgYSBiaWdnZXIgd2lkdGhcbiAgLy8gd2hlbiB0aGUgJ2JveC1zaXppbmcnIGlzIG5vdCBzZXQgdG8gJ2JvcmRlci1ib3gnXG4gIG5vZGUuc3R5bGVbJ2JveC1zaXppbmcnXSA9ICdib3JkZXItYm94J1xuICByZXR1cm4gbm9kZVxufVxuXG5TZWxlY3QucHJvdG90eXBlLmF0dHIgPSB7XG4gIGRpc2FibGVkOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdGhpcy5ub2RlLmRpc2FibGVkID0gdmFsICYmIHZhbCAhPT0gJ2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICA/IHRydWVcbiAgICAgICAgICAgICAgICAgICAgOiBmYWxzZVxuICB9LFxuICBvcHRpb25zOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWwpICE9PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgdGhpcy5vcHRpb25zID0gdmFsXG4gICAgdGhpcy5ub2RlLmlubmVySFRNTCA9ICcnXG4gICAgdGhpcy5jcmVhdGVPcHRpb25zKHZhbClcbiAgfSxcbiAgc2VsZWN0ZWRJbmRleDogZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhbCA9IHBhcnNlSW50KHZhbClcbiAgICBpZiAodHlwZW9mIHZhbCAhPT0gJ251bWJlcicgfHwgdmFsICE9PSB2YWwgfHwgdmFsID49IHRoaXMub3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB0aGlzLm5vZGUudmFsdWUgPSB0aGlzLm9wdGlvbnNbdmFsXVxuICB9XG59XG5cblNlbGVjdC5wcm90b3R5cGUuYmluZEV2ZW50cyA9IGZ1bmN0aW9uIChldnRzKSB7XG4gIHZhciBpc0xpc3RlblRvQ2hhbmdlID0gZmFsc2VcbiAgQXRvbWljLnByb3RvdHlwZS5iaW5kRXZlbnRzLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgZXZ0cy5maWx0ZXIoZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICB2YXIgcGFzcyA9IHZhbCAhPT0gJ2NoYW5nZSdcbiAgICAgICAgIXBhc3MgJiYgKGlzTGlzdGVuVG9DaGFuZ2UgPSB0cnVlKVxuICAgICAgICByZXR1cm4gcGFzc1xuICAgICAgfSkpXG4gIGlmIChpc0xpc3RlblRvQ2hhbmdlKSB7XG4gICAgdGhpcy5ub2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uIChlKSB7XG4gICAgICBlLmluZGV4ID0gdGhpcy5vcHRpb25zLmluZGV4T2YodGhpcy5ub2RlLnZhbHVlKVxuICAgICAgc2VuZGVyLmZpcmVFdmVudCh0aGlzLmRhdGEucmVmLCAnY2hhbmdlJywgZSlcbiAgICB9LmJpbmQodGhpcykpXG4gIH1cbn1cblxuU2VsZWN0LnByb3RvdHlwZS5jcmVhdGVPcHRpb25zID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgdmFyIG9wdERvYyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKVxuICB2YXIgb3B0XG4gIGZvciAodmFyIGkgPSAwLCBsID0gb3B0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBvcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKVxuICAgIG9wdC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShvcHRzW2ldKSlcbiAgICBvcHREb2MuYXBwZW5kQ2hpbGQob3B0KVxuICB9XG4gIHRoaXMubm9kZS5hcHBlbmRDaGlsZChvcHREb2MpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2VsZWN0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvc2VsZWN0LmpzXG4gKiogbW9kdWxlIGlkID0gNTVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgQXRvbWljID0gcmVxdWlyZSgnLi9hdG9taWMnKVxuXG4vLyBhdHRyczpcbi8vICAgLSB2YWx1ZVxuLy8gICAtIGRpc2FibGVkXG5mdW5jdGlvbiBEYXRlcGlja2VyIChkYXRhKSB7XG4gIEF0b21pYy5jYWxsKHRoaXMsIGRhdGEpXG59XG5cbkRhdGVwaWNrZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5EYXRlcGlja2VyLnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKVxuICB2YXIgdXVpZCA9IE1hdGguZmxvb3IoMTAwMDAwMDAwMDAwMDAgKiBNYXRoLnJhbmRvbSgpKSArIERhdGUubm93KClcbiAgdGhpcy5jbGFzc05hbWUgPSAnd2VleC1pcHQtJyArIHV1aWRcbiAgdGhpcy5zdHlsZUlkID0gJ3dlZXgtc3R5bGUtJyArIHV1aWRcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKHRoaXMuY2xhc3NOYW1lKVxuICBub2RlLnNldEF0dHJpYnV0ZSgndHlwZScsICdkYXRlJylcbiAgbm9kZS50eXBlID0gJ2RhdGUnXG4gIC8vIEZvciB0aGUgY29uc2lzdGVuY3kgb2YgaW5wdXQgY29tcG9uZW50J3Mgd2lkdGguXG4gIC8vIFRoZSBkYXRlIGFuZCB0aW1lIHR5cGUgb2YgaW5wdXQgd2lsbCBoYXZlIGEgYmlnZ2VyIHdpZHRoXG4gIC8vIHdoZW4gdGhlICdib3gtc2l6aW5nJyBpcyBub3Qgc2V0IHRvICdib3JkZXItYm94J1xuICBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtZWxlbWVudCcpXG4gIHJldHVybiBub2RlXG59XG5cbkRhdGVwaWNrZXIucHJvdG90eXBlLmF0dHIgPSB7XG4gIGRpc2FibGVkOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdGhpcy5ub2RlLmRpc2FibGVkID0gdmFsICYmIHZhbCAhPT0gJ2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICA/IHRydWVcbiAgICAgICAgICAgICAgICAgICAgOiBmYWxzZVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRGF0ZXBpY2tlclxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2RhdGVwaWNrZXIuanNcbiAqKiBtb2R1bGUgaWQgPSA1NlxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG5cbi8vIGF0dHJzOlxuLy8gICAtIHZhbHVlXG4vLyAgIC0gZGlzYWJsZWRcbmZ1bmN0aW9uIFRpbWVwaWNrZXIgKGRhdGEpIHtcbiAgQXRvbWljLmNhbGwodGhpcywgZGF0YSlcbn1cblxuVGltZXBpY2tlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEF0b21pYy5wcm90b3R5cGUpXG5cblRpbWVwaWNrZXIucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpXG4gIHZhciB1dWlkID0gTWF0aC5mbG9vcigxMDAwMDAwMDAwMDAwMCAqIE1hdGgucmFuZG9tKCkpICsgRGF0ZS5ub3coKVxuICB0aGlzLmNsYXNzTmFtZSA9ICd3ZWV4LWlwdC0nICsgdXVpZFxuICB0aGlzLnN0eWxlSWQgPSAnd2VleC1zdHlsZS0nICsgdXVpZFxuICBub2RlLmNsYXNzTGlzdC5hZGQodGhpcy5jbGFzc05hbWUpXG4gIG5vZGUuc2V0QXR0cmlidXRlKCd0eXBlJywgJ3RpbWUnKVxuICBub2RlLnR5cGUgPSAndGltZSdcbiAgLy8gRm9yIHRoZSBjb25zaXN0ZW5jeSBvZiBpbnB1dCBjb21wb25lbnQncyB3aWR0aC5cbiAgLy8gVGhlIGRhdGUgYW5kIHRpbWUgdHlwZSBvZiBpbnB1dCB3aWxsIGhhdmUgYSBiaWdnZXIgd2lkdGhcbiAgLy8gd2hlbiB0aGUgJ2JveC1zaXppbmcnIGlzIG5vdCBzZXQgdG8gJ2JvcmRlci1ib3gnXG4gIG5vZGUuY2xhc3NMaXN0LmFkZCgnd2VleC1lbGVtZW50JylcbiAgcmV0dXJuIG5vZGVcbn1cblxuVGltZXBpY2tlci5wcm90b3R5cGUuYXR0ciA9IHtcbiAgZGlzYWJsZWQ6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICB0aGlzLm5vZGUuZGlzYWJsZWQgPSB2YWwgJiYgdmFsICE9PSAnZmFsc2UnXG4gICAgICAgICAgICAgICAgICAgID8gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICA6IGZhbHNlXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUaW1lcGlja2VyXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvdGltZXBpY2tlci5qc1xuICoqIG1vZHVsZSBpZCA9IDU3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIEF0b21pYyA9IHJlcXVpcmUoJy4vYXRvbWljJylcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJylcbnJlcXVpcmUoJy4uL3N0eWxlcy92aWRlby5zY3NzJylcblxuLy8gYXR0cnM6XG4vLyAgIC0gYXV0b1BsYXk6IHRydWUgfCBmYWxzZSAoZGVmYXVsdDogZmFsc2UpXG4vLyAgIC0gcGxheVN0YXR1czogcGxheSB8IHBhdXNlIHwgc3RvcFxuLy8gICAtIHNyYzoge3N0cmluZ31cbi8vICAgLSBwb3N0ZXI6IHtzdHJpbmd9XG4vLyAgIC0gbG9vcDogdHJ1ZSB8IGZhbHNlIChkZWZhdWx0OiBmYWxzZSlcbi8vICAgLSBtdXRlZDogdHJ1ZSB8IGZhbHNlIChkZWZhdWx0OiBmYWxzZSlcbi8vIGV2ZW50czpcbi8vICAgLSBzdGFydFxuLy8gICAtIHBhdXNlXG4vLyAgIC0gZmluaXNoXG4vLyAgIC0gZmFpbFxuZnVuY3Rpb24gVmlkZW8gKGRhdGEpIHtcbiAgdmFyIGF1dG9QbGF5ID0gZGF0YS5hdHRyLmF1dG9QbGF5XG4gIHZhciBwbGF5U3RhdHVzID0gZGF0YS5hdHRyLnBsYXlTdGF0dXNcbiAgdGhpcy5hdXRvUGxheSA9IGF1dG9QbGF5ID09PSB0cnVlIHx8IGF1dG9QbGF5ID09PSAndHJ1ZSdcbiAgaWYgKHBsYXlTdGF0dXMgIT09ICdwbGF5J1xuICAgICAgJiYgcGxheVN0YXR1cyAhPT0gJ3N0b3AnXG4gICAgICAmJiBwbGF5U3RhdHVzICE9PSAncGF1c2UnKSB7XG4gICAgdGhpcy5wbGF5U3RhdHVzID0gJ3BhdXNlJ1xuICB9IGVsc2Uge1xuICAgIHRoaXMucGxheVN0YXR1cyA9IHBsYXlTdGF0dXNcbiAgfVxuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5WaWRlby5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEF0b21pYy5wcm90b3R5cGUpXG5cblZpZGVvLnByb3RvdHlwZS5hdHRyID0ge1xuICBwbGF5U3RhdHVzOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgaWYgKHZhbCAhPT0gJ3BsYXknICYmIHZhbCAhPT0gJ3N0b3AnICYmIHZhbCAhPT0gJ3BhdXNlJykge1xuICAgICAgdmFsID0gJ3BhdXNlJ1xuICAgIH1cbiAgICBpZiAodGhpcy5wbGF5U3RhdHVzID09PSB2YWwpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB0aGlzLnBsYXlTdGF0dXMgPSB2YWxcbiAgICB0aGlzLm5vZGUuc2V0QXR0cmlidXRlKCdwbGF5LXN0YXR1cycsIHZhbClcbiAgICB0aGlzW3RoaXMucGxheVN0YXR1c10oKVxuICB9LFxuICBhdXRvUGxheTogZnVuY3Rpb24gKHZhbCkge1xuICAgIC8vIERPIE5PVEhJTkdcbiAgfVxufVxuXG5WaWRlby5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJylcbiAgbm9kZS5jbGFzc0xpc3QuYWRkKCd3ZWV4LXZpZGVvJywgJ3dlZXgtZWxlbWVudCcpXG4gIG5vZGUuY29udHJvbHMgPSB0cnVlXG4gIG5vZGUuYXV0b3BsYXkgPSB0aGlzLmF1dG9QbGF5XG4gIG5vZGUuc2V0QXR0cmlidXRlKCdwbGF5LXN0YXR1cycsIHRoaXMucGxheVN0YXR1cylcbiAgdGhpcy5ub2RlID0gbm9kZVxuICBpZiAodGhpcy5hdXRvUGxheSAmJiB0aGlzLnBsYXlTdGF0dXMgPT09ICdwbGF5Jykge1xuICAgIHRoaXMucGxheSgpXG4gIH1cbiAgcmV0dXJuIG5vZGVcbn1cblxuVmlkZW8ucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoZXZ0cykge1xuICBBdG9taWMucHJvdG90eXBlLmJpbmRFdmVudHMuY2FsbCh0aGlzLCBldnRzKVxuXG4gIC8vIGNvbnZlcnQgdzNjLXZpZGVvIGV2ZW50cyB0byB3ZWV4LXZpZGVvIGV2ZW50cy5cbiAgdmFyIGV2dHNNYXAgPSB7XG4gICAgc3RhcnQ6ICdwbGF5JyxcbiAgICBmaW5pc2g6ICdlbmRlZCcsXG4gICAgZmFpbDogJ2Vycm9yJ1xuICB9XG4gIGZvciAodmFyIGV2dE5hbWUgaW4gZXZ0c01hcCkge1xuICAgIHRoaXMubm9kZS5hZGRFdmVudExpc3RlbmVyKGV2dHNNYXBbZXZ0TmFtZV0sIGZ1bmN0aW9uICh0eXBlLCBlKSB7XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQodHlwZSwgZS5kYXRhKVxuICAgIH0uYmluZCh0aGlzLCBldnROYW1lKSlcbiAgfVxufVxuXG5WaWRlby5wcm90b3R5cGUucGxheSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNyYyA9IHRoaXMubm9kZS5nZXRBdHRyaWJ1dGUoJ3NyYycpXG4gIGlmICghc3JjKSB7XG4gICAgc3JjID0gdGhpcy5ub2RlLmdldEF0dHJpYnV0ZSgnZGF0YS1zcmMnKVxuICAgIHNyYyAmJiB0aGlzLm5vZGUuc2V0QXR0cmlidXRlKCdzcmMnLCBzcmMpXG4gIH1cbiAgdGhpcy5ub2RlLnBsYXkoKVxufVxuXG5WaWRlby5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMubm9kZS5wYXVzZSgpXG59XG5cblZpZGVvLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLm5vZGUucGF1c2UoKVxuICB0aGlzLm5vZGUuYXV0b3BsYXkgPSBmYWxzZVxuICB0aGlzLm5vZGUuc2V0QXR0cmlidXRlKCdkYXRhLXNyYycsIHRoaXMubm9kZS5zcmMpXG4gIHRoaXMubm9kZS5zcmMgPSAnJ1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZGVvXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvdmlkZW8uanNcbiAqKiBtb2R1bGUgaWQgPSA1OFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3ZpZGVvLnNjc3NcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL25vZGVfbW9kdWxlcy9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi92aWRlby5zY3NzXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL25vZGVfbW9kdWxlcy9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi92aWRlby5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy92aWRlby5zY3NzXG4gKiogbW9kdWxlIGlkID0gNTlcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiLndlZXgtdmlkZW8ge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy92aWRlby5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0MsdUJBQXVCLEVBQ3ZCXCIsXCJmaWxlXCI6XCJ2aWRlby5zY3NzXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi53ZWV4LXZpZGVvIHtcXG5cXHRiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwO1xcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9zcmMvc3R5bGVzL3ZpZGVvLnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA2MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBBdG9taWMgPSByZXF1aXJlKCcuL2F0b21pYycpXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpXG5yZXF1aXJlKCcuLi9zdHlsZXMvc3dpdGNoLnNjc3MnKVxuXG52YXIgZGVmYXVsdHMgPSB7XG4gIGNvbG9yOiAnIzY0YmQ2MydcbiAgLCBzZWNvbmRhcnlDb2xvcjogJyNkZmRmZGYnXG4gICwgamFja0NvbG9yOiAnI2ZmZidcbiAgLCBqYWNrU2Vjb25kYXJ5Q29sb3I6IG51bGxcbiAgLCBjbGFzc05hbWU6ICd3ZWV4LXN3aXRjaCdcbiAgLCBkaXNhYmxlZE9wYWNpdHk6IDAuNVxuICAsIHNwZWVkOiAnMC40cydcbiAgLCB3aWR0aDogMTAwXG4gICwgaGVpZ2h0OiA2MFxuICAvLyBpcyB3aWR0aCBhbmQgaGVpZ2h0IHNjYWxhYmxlID9cbiAgLCBzY2FsYWJsZTogZmFsc2Vcbn1cblxuLy8gYXR0cnM6XG4vLyAgIC0gY2hlY2tlZDogaWYgaXMgY2hlY2tlZC5cbi8vICAgLSBkaXNhYmxlZDogaWYgdHJ1ZSwgdGhpcyBjb21wb25lbnQgaXMgbm90IGF2YWlsYWJsZSBmb3IgaW50ZXJhY3Rpb24uXG5mdW5jdGlvbiBTd2l0Y2ggKGRhdGEpIHtcbiAgdGhpcy5vcHRpb25zID0gdXRpbHMuZXh0ZW5kKHt9LCBkZWZhdWx0cylcbiAgdGhpcy5jaGVja2VkID0gZGF0YS5hdHRyLmNoZWNrZWRcbiAgICAgICYmIGRhdGEuYXR0ci5jaGVja2VkICE9PSAnZmFsc2UnID8gdHJ1ZSA6IGZhbHNlXG4gIHRoaXMuZGF0YSA9IGRhdGFcbiAgdGhpcy53aWR0aCA9IHRoaXMub3B0aW9ucy53aWR0aCAqIGRhdGEuc2NhbGVcbiAgdGhpcy5oZWlnaHQgPSB0aGlzLm9wdGlvbnMuaGVpZ2h0ICogZGF0YS5zY2FsZVxuICBBdG9taWMuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5Td2l0Y2gucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShBdG9taWMucHJvdG90eXBlKVxuXG5Td2l0Y2gucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJylcbiAgdGhpcy5qYWNrID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc21hbGwnKVxuICBub2RlLmFwcGVuZENoaWxkKHRoaXMuamFjaylcbiAgbm9kZS5jbGFzc05hbWUgPSB0aGlzLm9wdGlvbnMuY2xhc3NOYW1lXG4gIHRoaXMubm9kZSA9IG5vZGVcbiAgdGhpcy5hdHRyLmRpc2FibGVkLmNhbGwodGhpcywgdGhpcy5kYXRhLmF0dHIuZGlzYWJsZWQpXG4gIHJldHVybiBub2RlXG59XG5cblN3aXRjaC5wcm90b3R5cGUub25BcHBlbmQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2V0U2l6ZSgpXG4gIHRoaXMuc2V0UG9zaXRpb24oKVxufVxuXG5Td2l0Y2gucHJvdG90eXBlLmF0dHIgPSB7XG4gIGRpc2FibGVkOiBmdW5jdGlvbiAodmFsKSB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IHZhbCAmJiB2YWwgIT09ICdmYWxzZSdcbiAgICAgICAgICAgICAgICAgICAgPyB0cnVlXG4gICAgICAgICAgICAgICAgICAgIDogZmFsc2VcbiAgICB0aGlzLmRpc2FibGVkID8gdGhpcy5kaXNhYmxlKCkgOiB0aGlzLmVuYWJsZSgpXG4gIH1cbn1cblxuU3dpdGNoLnByb3RvdHlwZS5zZXRTaXplID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbWluID0gTWF0aC5taW4odGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpXG4gIHZhciBtYXggPSBNYXRoLm1heCh0aGlzLndpZHRoLCB0aGlzLmhlaWdodClcbiAgdGhpcy5ub2RlLnN0eWxlLndpZHRoID0gbWF4ICsgJ3B4J1xuICB0aGlzLm5vZGUuc3R5bGUuaGVpZ2h0ID0gbWluICsgJ3B4J1xuICB0aGlzLm5vZGUuc3R5bGUuYm9yZGVyUmFkaXVzID0gbWluIC8gMiArICdweCdcbiAgdGhpcy5qYWNrLnN0eWxlLndpZHRoXG4gICAgICA9IHRoaXMuamFjay5zdHlsZS5oZWlnaHRcbiAgICAgID0gbWluICsgJ3B4J1xufVxuXG5Td2l0Y2gucHJvdG90eXBlLnNldFBvc2l0aW9uID0gZnVuY3Rpb24gKGNsaWNrZWQpIHtcbiAgdmFyIGNoZWNrZWQgPSB0aGlzLmNoZWNrZWRcbiAgdmFyIG5vZGUgPSB0aGlzLm5vZGVcbiAgdmFyIGphY2sgPSB0aGlzLmphY2tcblxuICBpZiAoY2xpY2tlZCAmJiBjaGVja2VkKSB7XG4gICAgY2hlY2tlZCA9IGZhbHNlXG4gIH0gZWxzZSBpZiAoY2xpY2tlZCAmJiAhY2hlY2tlZCkge1xuICAgIGNoZWNrZWQgPSB0cnVlXG4gIH1cblxuICBpZiAoY2hlY2tlZCA9PT0gdHJ1ZSkge1xuICAgIHRoaXMuY2hlY2tlZCA9IHRydWVcblxuICAgIGlmICh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSkge1xuICAgICAgamFjay5zdHlsZS5sZWZ0ID0gcGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUobm9kZSkud2lkdGgpXG4gICAgICAgICAgICAgICAgICAgICAgICAtIHBhcnNlSW50KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGphY2spLndpZHRoKSArICdweCdcbiAgICB9IGVsc2Uge1xuICAgICAgamFjay5zdHlsZS5sZWZ0ID0gcGFyc2VJbnQobm9kZS5jdXJyZW50U3R5bGVbJ3dpZHRoJ10pXG4gICAgICAgICAgICAgICAgICAgICAgICAtIHBhcnNlSW50KGphY2suY3VycmVudFN0eWxlWyd3aWR0aCddKSArICdweCdcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMuY29sb3IgJiYgdGhpcy5jb2xvcml6ZSgpXG4gICAgdGhpcy5zZXRTcGVlZCgpXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5jaGVja2VkID0gZmFsc2VcbiAgICBqYWNrLnN0eWxlLmxlZnQgPSAwXG4gICAgbm9kZS5zdHlsZS5ib3hTaGFkb3cgPSAnaW5zZXQgMCAwIDAgMCAnICsgdGhpcy5vcHRpb25zLnNlY29uZGFyeUNvbG9yXG4gICAgbm9kZS5zdHlsZS5ib3JkZXJDb2xvciA9IHRoaXMub3B0aW9ucy5zZWNvbmRhcnlDb2xvclxuICAgIG5vZGUuc3R5bGUuYmFja2dyb3VuZENvbG9yXG4gICAgICAgID0gKHRoaXMub3B0aW9ucy5zZWNvbmRhcnlDb2xvciAhPT0gZGVmYXVsdHMuc2Vjb25kYXJ5Q29sb3IpXG4gICAgICAgICAgPyB0aGlzLm9wdGlvbnMuc2Vjb25kYXJ5Q29sb3JcbiAgICAgICAgICA6ICcjZmZmJ1xuICAgIGphY2suc3R5bGUuYmFja2dyb3VuZENvbG9yXG4gICAgICAgID0gKHRoaXMub3B0aW9ucy5qYWNrU2Vjb25kYXJ5Q29sb3IgIT09IHRoaXMub3B0aW9ucy5qYWNrQ29sb3IpXG4gICAgICAgICAgPyB0aGlzLm9wdGlvbnMuamFja1NlY29uZGFyeUNvbG9yXG4gICAgICAgICAgOiB0aGlzLm9wdGlvbnMuamFja0NvbG9yXG4gICAgdGhpcy5zZXRTcGVlZCgpXG4gIH1cbn1cblxuU3dpdGNoLnByb3RvdHlwZS5jb2xvcml6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vZGVIZWlnaHQgPSB0aGlzLm5vZGUub2Zmc2V0SGVpZ2h0IC8gMlxuXG4gIHRoaXMubm9kZS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLm9wdGlvbnMuY29sb3JcbiAgdGhpcy5ub2RlLnN0eWxlLmJvcmRlckNvbG9yID0gdGhpcy5vcHRpb25zLmNvbG9yXG4gIHRoaXMubm9kZS5zdHlsZS5ib3hTaGFkb3cgPSAnaW5zZXQgMCAwIDAgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBub2RlSGVpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICdweCAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHRoaXMub3B0aW9ucy5jb2xvclxuICB0aGlzLmphY2suc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5vcHRpb25zLmphY2tDb2xvclxufVxuXG5Td2l0Y2gucHJvdG90eXBlLnNldFNwZWVkID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3dpdGNoZXJQcm9wID0ge31cbiAgdmFyIGphY2tQcm9wID0ge1xuICAgICAgJ2JhY2tncm91bmQtY29sb3InOiB0aGlzLm9wdGlvbnMuc3BlZWRcbiAgICAgICwgbGVmdDogdGhpcy5vcHRpb25zLnNwZWVkLnJlcGxhY2UoL1thLXpdLywgJycpIC8gMiArICdzJ1xuICAgIH1cblxuICBpZiAodGhpcy5jaGVja2VkKSB7XG4gICAgc3dpdGNoZXJQcm9wID0ge1xuICAgICAgYm9yZGVyOiB0aGlzLm9wdGlvbnMuc3BlZWRcbiAgICAgICwgJ2JveC1zaGFkb3cnOiB0aGlzLm9wdGlvbnMuc3BlZWRcbiAgICAgICwgJ2JhY2tncm91bmQtY29sb3InOiB0aGlzLm9wdGlvbnMuc3BlZWQucmVwbGFjZSgvW2Etel0vLCAnJykgKiAzICsgJ3MnXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHN3aXRjaGVyUHJvcCA9IHtcbiAgICAgIGJvcmRlcjogdGhpcy5vcHRpb25zLnNwZWVkXG4gICAgICAsICdib3gtc2hhZG93JzogdGhpcy5vcHRpb25zLnNwZWVkXG4gICAgfVxuICB9XG5cbiAgdXRpbHMudHJhbnNpdGlvbml6ZSh0aGlzLm5vZGUsIHN3aXRjaGVyUHJvcClcbiAgdXRpbHMudHJhbnNpdGlvbml6ZSh0aGlzLmphY2ssIGphY2tQcm9wKVxufVxuXG5Td2l0Y2gucHJvdG90eXBlLmRpc2FibGUgPSBmdW5jdGlvbiAoKSB7XG4gICF0aGlzLmRpc2FibGVkICYmICh0aGlzLmRpc2FibGVkID0gdHJ1ZSlcbiAgdGhpcy5ub2RlLnN0eWxlLm9wYWNpdHkgPSBkZWZhdWx0cy5kaXNhYmxlZE9wYWNpdHlcbiAgdGhpcy5ub2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5nZXRDbGlja0hhbmRsZXIoKSlcbn1cblxuU3dpdGNoLnByb3RvdHlwZS5lbmFibGUgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZGlzYWJsZWQgJiYgKHRoaXMuZGlzYWJsZWQgPSBmYWxzZSlcbiAgdGhpcy5ub2RlLnN0eWxlLm9wYWNpdHkgPSAxXG4gIHRoaXMubm9kZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuZ2V0Q2xpY2tIYW5kbGVyKCkpXG59XG5cblN3aXRjaC5wcm90b3R5cGUuZ2V0Q2xpY2tIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuX2NsaWNrSGFuZGxlcikge1xuICAgIHRoaXMuX2NsaWNrSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHZhciBwYXJlbnQgPSB0aGlzLm5vZGUucGFyZW50Tm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKClcbiAgICAgIC8vIHZhciBsYWJlbFBhcmVudCA9IChwYXJlbnQgPT09ICdsYWJlbCcpID8gZmFsc2UgOiB0cnVlXG4gICAgICB0aGlzLnNldFBvc2l0aW9uKHRydWUpXG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ2NoYW5nZScsIHtcbiAgICAgICAgY2hlY2tlZDogdGhpcy5jaGVja2VkXG4gICAgICB9KVxuICAgIH0uYmluZCh0aGlzKVxuICB9XG4gIHJldHVybiB0aGlzLl9jbGlja0hhbmRsZXJcbn1cblxuU3dpdGNoLnByb3RvdHlwZS5zdHlsZVxuICAgID0gdXRpbHMuZXh0ZW5kKE9iamVjdC5jcmVhdGUoQXRvbWljLnByb3RvdHlwZS5zdHlsZSksIHtcblxuICAgICAgd2lkdGg6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuc2NhbGFibGUpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICB2YWwgPSBwYXJzZUZsb2F0KHZhbClcbiAgICAgICAgaWYgKHZhbCAhPT0gdmFsIHx8IHZhbCA8IDApIHsgLy8gTmFOXG4gICAgICAgICAgdmFsID0gdGhpcy5vcHRpb25zLndpZHRoXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy53aWR0aCA9IHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgICAgICB0aGlzLnNldFNpemUoKVxuICAgICAgfSxcblxuICAgICAgaGVpZ2h0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLnNjYWxhYmxlKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgdmFsID0gcGFyc2VGbG9hdCh2YWwpXG4gICAgICAgIGlmICh2YWwgIT09IHZhbCB8fCB2YWwgPCAwKSB7IC8vIE5hTlxuICAgICAgICAgIHZhbCA9IHRoaXMub3B0aW9ucy5oZWlnaHRcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmhlaWdodCA9IHZhbCAqIHRoaXMuZGF0YS5zY2FsZVxuICAgICAgICB0aGlzLnNldFNpemUoKVxuICAgICAgfVxuXG4gICAgfSlcblxubW9kdWxlLmV4cG9ydHMgPSBTd2l0Y2hcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvY29tcG9uZW50cy9zd2l0Y2guanNcbiAqKiBtb2R1bGUgaWQgPSA2MVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3N3aXRjaC5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9ub2RlX21vZHVsZXMvc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vc3dpdGNoLnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3N3aXRjaC5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL3N0eWxlcy9zd2l0Y2guc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDYyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi8qIHN3aXRjaCBkZWZhdWx0cy4gKi9cXG4ud2VleC1zd2l0Y2gge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcXG4gIGJvcmRlcjogMXB4IHNvbGlkICNkZmRmZGY7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcbiAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcXG4gIC1raHRtbC11c2VyLXNlbGVjdDogbm9uZTtcXG4gIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICB1c2VyLXNlbGVjdDogbm9uZTtcXG4gIGJveC1zaXppbmc6IGNvbnRlbnQtYm94O1xcbiAgYmFja2dyb3VuZC1jbGlwOiBjb250ZW50LWJveDsgfVxcblxcbi53ZWV4LXN3aXRjaCA+IHNtYWxsIHtcXG4gIGJhY2tncm91bmQ6ICNmZmY7XFxuICBib3JkZXItcmFkaXVzOiAxMDAlO1xcbiAgYm94LXNoYWRvdzogMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC40KTtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogMDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvc3JjL3N0eWxlcy9zd2l0Y2guc2Nzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQSxzQkFBc0I7QUFFdEI7RUFDRSx1QkFBdUI7RUFDdkIsMEJBQTBCO0VBQzFCLGdCQUFnQjtFQUNoQixzQkFBc0I7RUFDdEIsbUJBQW1CO0VBQ25CLHVCQUF1QjtFQUV2Qix1QkFBdUI7RUFDdkIseUJBQXlCO0VBQ3pCLDBCQUEwQjtFQUMxQixzQkFBc0I7RUFDdEIsa0JBQWtCO0VBQ2xCLHdCQUF3QjtFQUN4Qiw2QkFBNkIsRUFDOUI7O0FBRUQ7RUFDRSxpQkFBaUI7RUFDakIsb0JBQW9CO0VBQ3BCLHlDQUEwQjtFQUMxQixtQkFBbUI7RUFDbkIsT0FBTyxFQUNSXCIsXCJmaWxlXCI6XCJzd2l0Y2guc2Nzc1wiLFwic291cmNlc0NvbnRlbnRcIjpbXCIvKiBzd2l0Y2ggZGVmYXVsdHMuICovXFxuXFxuLndlZXgtc3dpdGNoIHtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XFxuICBib3JkZXI6IDFweCBzb2xpZCAjZGZkZmRmO1xcbiAgY3Vyc29yOiBwb2ludGVyO1xcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcXG5cXG4gIC1tb3otdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAta2h0bWwtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgLW1zLXVzZXItc2VsZWN0OiBub25lO1xcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XFxuICBib3gtc2l6aW5nOiBjb250ZW50LWJveDtcXG4gIGJhY2tncm91bmQtY2xpcDogY29udGVudC1ib3g7XFxufVxcblxcbi53ZWV4LXN3aXRjaCA+IHNtYWxsIHtcXG4gIGJhY2tncm91bmQ6ICNmZmY7XFxuICBib3JkZXItcmFkaXVzOiAxMDAlO1xcbiAgYm94LXNoYWRvdzogMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC40KTtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogMDtcXG59XFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vc3JjL3N0eWxlcy9zd2l0Y2guc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDYzXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcblxuLy8gYXR0cnM6XG4vLyAgIC0gaHJlZlxuZnVuY3Rpb24gQSAoZGF0YSkge1xuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhKVxufVxuXG5BLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxuQS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKVxuICBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtY29udGFpbmVyJylcbiAgdGhpcy5ub2RlID0gbm9kZVxuICB0aGlzLnN0eWxlLmFsaWduSXRlbXMuY2FsbCh0aGlzLCAnY2VudGVyJylcbiAgdGhpcy5zdHlsZS5qdXN0aWZ5Q29udGVudC5jYWxsKHRoaXMsICdjZW50ZXInKVxuICB0aGlzLm5vZGUuc3R5bGUudGV4dERlY29yYXRpb24gPSAnbm9uZSdcbiAgcmV0dXJuIG5vZGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBBXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vc3JjL2NvbXBvbmVudHMvYS5qc1xuICoqIG1vZHVsZSBpZCA9IDY0XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4vY29tcG9uZW50JylcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJylcblxudmFyIElEX1BSRUZJWCA9ICd3ZWV4X2VtYmVkXydcblxuZnVuY3Rpb24gX2dlbmVyYXRlSWQoKSB7XG4gIHJldHVybiBJRF9QUkVGSVggKyB1dGlscy5nZXRSYW5kb20oMTApXG59XG5cbmZ1bmN0aW9uIEVtYmVkIChkYXRhLCBub2RlVHlwZSkge1xuICB2YXIgYXR0ciA9IGRhdGEuYXR0clxuICBpZiAoYXR0cikge1xuICAgIHRoaXMuc291cmNlID0gYXR0ci5zcmNcbiAgICB0aGlzLmxvYWRlciA9IGF0dHIubG9hZGUgfHwgJ3hocidcbiAgfVxuICBDb21wb25lbnQuY2FsbCh0aGlzLCBkYXRhLCBub2RlVHlwZSlcbiAgdGhpcy5pbml0V2VleCgpXG59XG5cbkVtYmVkLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ29tcG9uZW50LnByb3RvdHlwZSlcblxuRW1iZWQucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcblxuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG5vZGUuaWQgPSB0aGlzLmlkXG4gIG5vZGUuc3R5bGUub3ZlcmZsb3cgPSAnc2Nyb2xsJ1xuICAvLyBub2RlLmNsYXNzTGlzdC5hZGQoJ3dlZXgtY29udGFpbmVyJylcbiAgcmV0dXJuIG5vZGVcbn1cblxuRW1iZWQucHJvdG90eXBlLmluaXRXZWV4ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmlkID0gX2dlbmVyYXRlSWQoKVxuICB0aGlzLm5vZGUuaWQgPSB0aGlzLmlkXG4gIHZhciBjb25maWcgPSB7XG4gICAgYXBwSWQ6IHRoaXMuaWQsXG4gICAgc291cmNlOiB0aGlzLnNvdXJjZSxcbiAgICBsb2FkZXI6IHRoaXMubG9hZGVyLFxuICAgIHdpZHRoOiB0aGlzLm5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGgsXG4gICAgcm9vdElkOiB0aGlzLmlkXG4gIH1cbiAgd2luZG93LndlZXguaW5pdChjb25maWcpXG59XG5cbkVtYmVkLnByb3RvdHlwZS5kZXN0cm95V2VleCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5pZCAmJiB3aW5kb3cuZGVzdHJveUluc3RhbmNlKHRoaXMuaWQpXG4gIC8vIFRPRE86IHVuYmluZCBldmVudHMgYW5kIGNsZWFyIGRvbXMuXG4gIHRoaXMubm9kZS5pbm5lckhUTUwgPSAnJ1xufVxuXG5FbWJlZC5wcm90b3R5cGUucmVsb2FkV2VleCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5kZXN0cm95V2VleCgpXG4gIHRoaXMuaW5pdFdlZXgoKVxufVxuXG4vLyBzcmMgaXMgbm90IHVwZGF0YWJsZSB0ZW1wb3JhcmlseVxuLy8gRW1iZWQucHJvdG90eXBlLmF0dHIgPSB7XG4vLyAgIHNyYzogZnVuY3Rpb24gKHZhbHVlKSB7XG4vLyAgICAgdGhpcy5zcmMgPSB2YWx1ZVxuLy8gICAgIHRoaXMucmVsb2FkV2VleCgpXG4vLyAgIH1cbi8vIH1cblxubW9kdWxlLmV4cG9ydHMgPSBFbWJlZFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9jb21wb25lbnRzL2VtYmVkLmpzXG4gKiogbW9kdWxlIGlkID0gNjVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsInZhciBkb20gPSByZXF1aXJlKCcuL2RvbScpXG52YXIgZXZlbnQgPSByZXF1aXJlKCcuL2V2ZW50JylcbnZhciBwYWdlSW5mbyA9IHJlcXVpcmUoJy4vcGFnZUluZm8nKVxudmFyIHN0cmVhbSA9IHJlcXVpcmUoJy4vc3RyZWFtJylcbnZhciBtb2RhbCA9IHJlcXVpcmUoJy4vbW9kYWwnKVxudmFyIGFuaW1hdGlvbiA9IHJlcXVpcmUoJy4vYW5pbWF0aW9uJylcblxudmFyIGFwaSA9IHtcbiAgaW5pdDogZnVuY3Rpb24gKFdlZXgpIHtcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdkb20nLCBkb20sIGRvbS5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdldmVudCcsIGV2ZW50LCBldmVudC5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdwYWdlSW5mbycsIHBhZ2VJbmZvLCBwYWdlSW5mby5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdzdHJlYW0nLCBzdHJlYW0sIHN0cmVhbS5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdtb2RhbCcsIG1vZGFsLCBtb2RhbC5fbWV0YSlcbiAgICBXZWV4LnJlZ2lzdGVyQXBpTW9kdWxlKCdhbmltYXRpb24nLCBhbmltYXRpb24sIGFuaW1hdGlvbi5fbWV0YSlcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFwaVxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL2luZGV4LmpzXG4gKiogbW9kdWxlIGlkID0gNjZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgbWVzc2FnZVF1ZXVlID0gcmVxdWlyZSgnLi4vbWVzc2FnZVF1ZXVlJylcbnZhciBGcmFtZVVwZGF0ZXIgPSByZXF1aXJlKCcuLi9mcmFtZVVwZGF0ZXInKVxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvY29tcG9uZW50JylcbnZhciBzY3JvbGwgPSByZXF1aXJlKCdzY3JvbGwtdG8nKVxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG4vLyB2YXIgV2VleCA9IHJlcXVpcmUoJy4uL3dlZXgnKVxuXG52YXIgZG9tID0ge1xuXG4gIC8qKlxuICAgKiBjcmVhdGVCb2R5OiBjcmVhdGUgcm9vdCBjb21wb25lbnRcbiAgICogQHBhcmFtICB7b2JqZWN0fSBlbGVtZW50XG4gICAqICAgIGNvbnRhaW5lcnxsaXN0dmlld3xzY3JvbGx2aWV3XG4gICAqIEByZXR1cm4ge1t0eXBlXX0gICAgICBbZGVzY3JpcHRpb25dXG4gICAqL1xuICBjcmVhdGVCb2R5OiBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICBlbGVtZW50LnNjYWxlID0gdGhpcy5zY2FsZVxuICAgIGVsZW1lbnQuaW5zdGFuY2VJZCA9IGNvbXBvbmVudE1hbmFnZXIuaW5zdGFuY2VJZFxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLmNyZWF0ZUJvZHkoZWxlbWVudClcbiAgfSxcblxuICBhZGRFbGVtZW50OiBmdW5jdGlvbiAocGFyZW50UmVmLCBlbGVtZW50LCBpbmRleCkge1xuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICBlbGVtZW50LnNjYWxlID0gdGhpcy5zY2FsZVxuICAgIGVsZW1lbnQuaW5zdGFuY2VJZCA9IGNvbXBvbmVudE1hbmFnZXIuaW5zdGFuY2VJZFxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLmFkZEVsZW1lbnQocGFyZW50UmVmLCBlbGVtZW50LCBpbmRleClcbiAgfSxcblxuICByZW1vdmVFbGVtZW50OiBmdW5jdGlvbiAocmVmKSB7XG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLnJlbW92ZUVsZW1lbnQocmVmKVxuICB9LFxuXG4gIG1vdmVFbGVtZW50OiBmdW5jdGlvbiAocmVmLCBwYXJlbnRSZWYsIGluZGV4KSB7XG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLm1vdmVFbGVtZW50KHJlZiwgcGFyZW50UmVmLCBpbmRleClcbiAgfSxcblxuICBhZGRFdmVudDogZnVuY3Rpb24gKHJlZiwgdHlwZSkge1xuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICByZXR1cm4gY29tcG9uZW50TWFuYWdlci5hZGRFdmVudChyZWYsIHR5cGUpXG4gIH0sXG5cbiAgcmVtb3ZlRXZlbnQ6IGZ1bmN0aW9uIChyZWYsIHR5cGUpIHtcbiAgICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG4gICAgcmV0dXJuIGNvbXBvbmVudE1hbmFnZXIucmVtb3ZlRXZlbnQocmVmLCB0eXBlKVxuICB9LFxuXG4gIC8qKlxuICAgKiB1cGRhdGVBdHRyczogdXBkYXRlIGF0dHJpYnV0ZXMgb2YgY29tcG9uZW50XG4gICAqIEBwYXJhbSAge3N0cmluZ30gcmVmXG4gICAqIEBwYXJhbSAge29ian0gYXR0clxuICAgKi9cbiAgdXBkYXRlQXR0cnM6IGZ1bmN0aW9uIChyZWYsIGF0dHIpIHtcbiAgICB2YXIgY29tcG9uZW50TWFuYWdlciA9IHRoaXMuZ2V0Q29tcG9uZW50TWFuYWdlcigpXG4gICAgcmV0dXJuIGNvbXBvbmVudE1hbmFnZXIudXBkYXRlQXR0cnMocmVmLCBhdHRyKVxuICB9LFxuXG4gIC8qKlxuICAgKiB1cGRhdGVTdHlsZTogdWRwYXRlIHN0eWxlIG9mIGNvbXBvbmVudFxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVmXG4gICAqIEBwYXJhbSB7b2JqfSBzdHlsZVxuICAgKi9cbiAgdXBkYXRlU3R5bGU6IGZ1bmN0aW9uIChyZWYsIHN0eWxlKSB7XG4gICAgdmFyIGNvbXBvbmVudE1hbmFnZXIgPSB0aGlzLmdldENvbXBvbmVudE1hbmFnZXIoKVxuICAgIHJldHVybiBjb21wb25lbnRNYW5hZ2VyLnVwZGF0ZVN0eWxlKHJlZiwgc3R5bGUpXG4gIH0sXG5cbiAgY3JlYXRlRmluaXNoOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gVE9ET1xuICAgIC8vIEZyYW1lVXBkYXRlci5wYXVzZSgpXG4gIH0sXG5cbiAgcmVmcmVzaEZpbmlzaDogZnVuY3Rpb24gKCkge1xuICAgIC8vIFRPRE9cbiAgfSxcblxuICAvKipcbiAgICogc2Nyb2xsVG9FbGVtZW50XG4gICAqIEBwYXJhbSAge3N0cmluZ30gcmVmXG4gICAqIEBwYXJhbSAge29ian0gb3B0aW9ucyB7b2Zmc2V0Ok51bWJlcn1cbiAgICogICBwczogc2Nyb2xsLXRvIGhhcyAnZWFzZScgYW5kICdkdXJhdGlvbicobXMpIGFzIG9wdGlvbnMuXG4gICAqL1xuICBzY3JvbGxUb0VsZW1lbnQ6IGZ1bmN0aW9uIChyZWYsIG9wdGlvbnMpIHtcbiAgICAhb3B0aW9ucyAmJiAob3B0aW9ucyA9IHt9KVxuICAgIHZhciBjb21wb25lbnRNYW5hZ2VyID0gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKClcbiAgICB2YXIgZWxlbSA9IGNvbXBvbmVudE1hbmFnZXIuZ2V0RWxlbWVudEJ5UmVmKHJlZilcbiAgICBpZiAoZWxlbSkge1xuICAgICAgdmFyIG9mZnNldFRvcCA9IGVsZW0ubm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3BcbiAgICAgICAgICArIGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wXG4gICAgICB2YXIgb2Zmc2V0ID0gKE51bWJlcihvcHRpb25zLm9mZnNldCkgfHwgMCkgKiB0aGlzLnNjYWxlXG4gICAgICB2YXIgdHdlZW4gPSBzY3JvbGwoMCwgb2Zmc2V0VG9wICsgb2Zmc2V0LCBvcHRpb25zKVxuICAgICAgLy8gdHdlZW4ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIH0pXG4gICAgfVxuICB9XG5cbn1cblxuZG9tLl9tZXRhID0ge1xuICBkb206IFt7XG4gICAgbmFtZTogJ2NyZWF0ZUJvZHknLFxuICAgIGFyZ3M6IFsnb2JqZWN0J11cbiAgfSwge1xuICAgIG5hbWU6ICdhZGRFbGVtZW50JyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnLCAnbnVtYmVyJ11cbiAgfSwge1xuICAgIG5hbWU6ICdyZW1vdmVFbGVtZW50JyxcbiAgICBhcmdzOiBbJ3N0cmluZyddXG4gIH0sIHtcbiAgICBuYW1lOiAnbW92ZUVsZW1lbnQnLFxuICAgIGFyZ3M6IFsnc3RyaW5nJywgJ3N0cmluZycsICdudW1iZXInXVxuICB9LCB7XG4gICAgbmFtZTogJ2FkZEV2ZW50JyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdzdHJpbmcnXVxuICB9LCB7XG4gICAgbmFtZTogJ3JlbW92ZUV2ZW50JyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdzdHJpbmcnXVxuICB9LCB7XG4gICAgbmFtZTogJ3VwZGF0ZUF0dHJzJyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnXVxuICB9LCB7XG4gICAgbmFtZTogJ3VwZGF0ZVN0eWxlJyxcbiAgICBhcmdzOiBbJ3N0cmluZycsICdvYmplY3QnXVxuICB9LCB7XG4gICAgbmFtZTogJ2NyZWF0ZUZpbmlzaCcsXG4gICAgYXJnczogW11cbiAgfSwge1xuICAgIG5hbWU6ICdyZWZyZXNoRmluaXNoJyxcbiAgICBhcmdzOiBbXVxuICB9LCB7XG4gICAgbmFtZTogJ3Njcm9sbFRvRWxlbWVudCcsXG4gICAgYXJnczogWydzdHJpbmcnLCAnb2JqZWN0J11cbiAgfV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkb21cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL2RvbS5qc1xuICoqIG1vZHVsZSBpZCA9IDY3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIFR3ZWVuID0gcmVxdWlyZSgndHdlZW4nKTtcbnZhciByYWYgPSByZXF1aXJlKCdyYWYnKTtcblxuLyoqXG4gKiBFeHBvc2UgYHNjcm9sbFRvYC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNjcm9sbFRvO1xuXG4vKipcbiAqIFNjcm9sbCB0byBgKHgsIHkpYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0geFxuICogQHBhcmFtIHtOdW1iZXJ9IHlcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gc2Nyb2xsVG8oeCwgeSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBzdGFydCBwb3NpdGlvblxuICB2YXIgc3RhcnQgPSBzY3JvbGwoKTtcblxuICAvLyBzZXR1cCB0d2VlblxuICB2YXIgdHdlZW4gPSBUd2VlbihzdGFydClcbiAgICAuZWFzZShvcHRpb25zLmVhc2UgfHwgJ291dC1jaXJjJylcbiAgICAudG8oeyB0b3A6IHksIGxlZnQ6IHggfSlcbiAgICAuZHVyYXRpb24ob3B0aW9ucy5kdXJhdGlvbiB8fCAxMDAwKTtcblxuICAvLyBzY3JvbGxcbiAgdHdlZW4udXBkYXRlKGZ1bmN0aW9uKG8pe1xuICAgIHdpbmRvdy5zY3JvbGxUbyhvLmxlZnQgfCAwLCBvLnRvcCB8IDApO1xuICB9KTtcblxuICAvLyBoYW5kbGUgZW5kXG4gIHR3ZWVuLm9uKCdlbmQnLCBmdW5jdGlvbigpe1xuICAgIGFuaW1hdGUgPSBmdW5jdGlvbigpe307XG4gIH0pO1xuXG4gIC8vIGFuaW1hdGVcbiAgZnVuY3Rpb24gYW5pbWF0ZSgpIHtcbiAgICByYWYoYW5pbWF0ZSk7XG4gICAgdHdlZW4udXBkYXRlKCk7XG4gIH1cblxuICBhbmltYXRlKCk7XG4gIFxuICByZXR1cm4gdHdlZW47XG59XG5cbi8qKlxuICogUmV0dXJuIHNjcm9sbCBwb3NpdGlvbi5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzY3JvbGwoKSB7XG4gIHZhciB5ID0gd2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3A7XG4gIHZhciB4ID0gd2luZG93LnBhZ2VYT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0O1xuICByZXR1cm4geyB0b3A6IHksIGxlZnQ6IHggfTtcbn1cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L3Njcm9sbC10by9pbmRleC5qc1xuICoqIG1vZHVsZSBpZCA9IDY4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2VtaXR0ZXInKTtcbnZhciBjbG9uZSA9IHJlcXVpcmUoJ2Nsb25lJyk7XG52YXIgdHlwZSA9IHJlcXVpcmUoJ3R5cGUnKTtcbnZhciBlYXNlID0gcmVxdWlyZSgnZWFzZScpO1xuXG4vKipcbiAqIEV4cG9zZSBgVHdlZW5gLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gVHdlZW47XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgVHdlZW5gIHdpdGggYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IG9ialxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBUd2VlbihvYmopIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFR3ZWVuKSkgcmV0dXJuIG5ldyBUd2VlbihvYmopO1xuICB0aGlzLl9mcm9tID0gb2JqO1xuICB0aGlzLmVhc2UoJ2xpbmVhcicpO1xuICB0aGlzLmR1cmF0aW9uKDUwMCk7XG59XG5cbi8qKlxuICogTWl4aW4gZW1pdHRlci5cbiAqL1xuXG5FbWl0dGVyKFR3ZWVuLnByb3RvdHlwZSk7XG5cbi8qKlxuICogUmVzZXQgdGhlIHR3ZWVuLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuVHdlZW4ucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5pc0FycmF5ID0gJ2FycmF5JyA9PT0gdHlwZSh0aGlzLl9mcm9tKTtcbiAgdGhpcy5fY3VyciA9IGNsb25lKHRoaXMuX2Zyb20pO1xuICB0aGlzLl9kb25lID0gZmFsc2U7XG4gIHRoaXMuX3N0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFR3ZWVuIHRvIGBvYmpgIGFuZCByZXNldCBpbnRlcm5hbCBzdGF0ZS5cbiAqXG4gKiAgICB0d2Vlbi50byh7IHg6IDUwLCB5OiAxMDAgfSlcbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gb2JqXG4gKiBAcmV0dXJuIHtUd2Vlbn0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Ud2Vlbi5wcm90b3R5cGUudG8gPSBmdW5jdGlvbihvYmope1xuICB0aGlzLnJlc2V0KCk7XG4gIHRoaXMuX3RvID0gb2JqO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IGR1cmF0aW9uIHRvIGBtc2AgWzUwMF0uXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtUd2Vlbn0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Ud2Vlbi5wcm90b3R5cGUuZHVyYXRpb24gPSBmdW5jdGlvbihtcyl7XG4gIHRoaXMuX2R1cmF0aW9uID0gbXM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgZWFzaW5nIGZ1bmN0aW9uIHRvIGBmbmAuXG4gKlxuICogICAgdHdlZW4uZWFzZSgnaW4tb3V0LXNpbmUnKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBmblxuICogQHJldHVybiB7VHdlZW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblR3ZWVuLnByb3RvdHlwZS5lYXNlID0gZnVuY3Rpb24oZm4pe1xuICBmbiA9ICdmdW5jdGlvbicgPT0gdHlwZW9mIGZuID8gZm4gOiBlYXNlW2ZuXTtcbiAgaWYgKCFmbikgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBlYXNpbmcgZnVuY3Rpb24nKTtcbiAgdGhpcy5fZWFzZSA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU3RvcCB0aGUgdHdlZW4gYW5kIGltbWVkaWF0ZWx5IGVtaXQgXCJzdG9wXCIgYW5kIFwiZW5kXCIuXG4gKlxuICogQHJldHVybiB7VHdlZW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblR3ZWVuLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5zdG9wcGVkID0gdHJ1ZTtcbiAgdGhpcy5fZG9uZSA9IHRydWU7XG4gIHRoaXMuZW1pdCgnc3RvcCcpO1xuICB0aGlzLmVtaXQoJ2VuZCcpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUGVyZm9ybSBhIHN0ZXAuXG4gKlxuICogQHJldHVybiB7VHdlZW59IHNlbGZcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblR3ZWVuLnByb3RvdHlwZS5zdGVwID0gZnVuY3Rpb24oKXtcbiAgaWYgKHRoaXMuX2RvbmUpIHJldHVybjtcblxuICAvLyBkdXJhdGlvblxuICB2YXIgZHVyYXRpb24gPSB0aGlzLl9kdXJhdGlvbjtcbiAgdmFyIG5vdyA9IERhdGUubm93KCk7XG4gIHZhciBkZWx0YSA9IG5vdyAtIHRoaXMuX3N0YXJ0O1xuICB2YXIgZG9uZSA9IGRlbHRhID49IGR1cmF0aW9uO1xuXG4gIC8vIGNvbXBsZXRlXG4gIGlmIChkb25lKSB7XG4gICAgdGhpcy5fZnJvbSA9IHRoaXMuX3RvO1xuICAgIHRoaXMuX3VwZGF0ZSh0aGlzLl90byk7XG4gICAgdGhpcy5fZG9uZSA9IHRydWU7XG4gICAgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHR3ZWVuXG4gIHZhciBmcm9tID0gdGhpcy5fZnJvbTtcbiAgdmFyIHRvID0gdGhpcy5fdG87XG4gIHZhciBjdXJyID0gdGhpcy5fY3VycjtcbiAgdmFyIGZuID0gdGhpcy5fZWFzZTtcbiAgdmFyIHAgPSAobm93IC0gdGhpcy5fc3RhcnQpIC8gZHVyYXRpb247XG4gIHZhciBuID0gZm4ocCk7XG5cbiAgLy8gYXJyYXlcbiAgaWYgKHRoaXMuaXNBcnJheSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZnJvbS5sZW5ndGg7ICsraSkge1xuICAgICAgY3VycltpXSA9IGZyb21baV0gKyAodG9baV0gLSBmcm9tW2ldKSAqIG47XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlKGN1cnIpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gb2JqZWNoXG4gIGZvciAodmFyIGsgaW4gZnJvbSkge1xuICAgIGN1cnJba10gPSBmcm9tW2tdICsgKHRvW2tdIC0gZnJvbVtrXSkgKiBuO1xuICB9XG5cbiAgdGhpcy5fdXBkYXRlKGN1cnIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHVwZGF0ZSBmdW5jdGlvbiB0byBgZm5gIG9yXG4gKiB3aGVuIG5vIGFyZ3VtZW50IGlzIGdpdmVuIHRoaXMgcGVyZm9ybXNcbiAqIGEgXCJzdGVwXCIuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge1R3ZWVufSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblR3ZWVuLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihmbil7XG4gIGlmICgwID09IGFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLnN0ZXAoKTtcbiAgdGhpcy5fdXBkYXRlID0gZm47XG4gIHJldHVybiB0aGlzO1xufTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jb21wb25lbnQtdHdlZW4vaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSA2OVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiXG4vKipcbiAqIEV4cG9zZSBgRW1pdHRlcmAuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBFbWl0dGVyO1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRW1pdHRlcihvYmopIHtcbiAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XG59O1xuXG4vKipcbiAqIE1peGluIHRoZSBlbWl0dGVyIHByb3BlcnRpZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gbWl4aW4ob2JqKSB7XG4gIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xuICAgIG9ialtrZXldID0gRW1pdHRlci5wcm90b3R5cGVba2V5XTtcbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub24gPVxuRW1pdHRlci5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgKHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdKVxuICAgIC5wdXNoKGZuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICogdGltZSB0aGVuIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgZnVuY3Rpb24gb24oKSB7XG4gICAgdGhpcy5vZmYoZXZlbnQsIG9uKTtcbiAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgb24uZm4gPSBmbjtcbiAgdGhpcy5vbihldmVudCwgb24pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcbiAqIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICAvLyBhbGxcbiAgaWYgKDAgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc3BlY2lmaWMgZXZlbnRcbiAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF07XG4gIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gIGlmICgxID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHJlbW92ZSBzcGVjaWZpYyBoYW5kbGVyXG4gIHZhciBjYjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICBjYiA9IGNhbGxiYWNrc1tpXTtcbiAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xuICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge01peGVkfSAuLi5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuICAgICwgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcblxuICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgY2FsbGJhY2tzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjYWxsYmFja3MubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmV0dXJuIGFycmF5IG9mIGNhbGxiYWNrcyBmb3IgYGV2ZW50YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0FycmF5fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCl7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW107XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgcmV0dXJuICEhIHRoaXMubGlzdGVuZXJzKGV2ZW50KS5sZW5ndGg7XG59O1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSA3MFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciB0eXBlO1xudHJ5IHtcbiAgdHlwZSA9IHJlcXVpcmUoJ2NvbXBvbmVudC10eXBlJyk7XG59IGNhdGNoIChfKSB7XG4gIHR5cGUgPSByZXF1aXJlKCd0eXBlJyk7XG59XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZTtcblxuLyoqXG4gKiBDbG9uZXMgb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBhbnkgb2JqZWN0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGNsb25lKG9iail7XG4gIHN3aXRjaCAodHlwZShvYmopKSB7XG4gICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgIHZhciBjb3B5ID0ge307XG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgIGNvcHlba2V5XSA9IGNsb25lKG9ialtrZXldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGNvcHk7XG5cbiAgICBjYXNlICdhcnJheSc6XG4gICAgICB2YXIgY29weSA9IG5ldyBBcnJheShvYmoubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gb2JqLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBjb3B5W2ldID0gY2xvbmUob2JqW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb3B5O1xuXG4gICAgY2FzZSAncmVnZXhwJzpcbiAgICAgIC8vIGZyb20gbWlsbGVybWVkZWlyb3MvYW1kLXV0aWxzIC0gTUlUXG4gICAgICB2YXIgZmxhZ3MgPSAnJztcbiAgICAgIGZsYWdzICs9IG9iai5tdWx0aWxpbmUgPyAnbScgOiAnJztcbiAgICAgIGZsYWdzICs9IG9iai5nbG9iYWwgPyAnZycgOiAnJztcbiAgICAgIGZsYWdzICs9IG9iai5pZ25vcmVDYXNlID8gJ2knIDogJyc7XG4gICAgICByZXR1cm4gbmV3IFJlZ0V4cChvYmouc291cmNlLCBmbGFncyk7XG5cbiAgICBjYXNlICdkYXRlJzpcbiAgICAgIHJldHVybiBuZXcgRGF0ZShvYmouZ2V0VGltZSgpKTtcblxuICAgIGRlZmF1bHQ6IC8vIHN0cmluZywgbnVtYmVyLCBib29sZWFuLCDigKZcbiAgICAgIHJldHVybiBvYmo7XG4gIH1cbn1cblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2NvbXBvbmVudC1jbG9uZS9pbmRleC5qc1xuICoqIG1vZHVsZSBpZCA9IDcxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvKipcbiAqIHRvU3RyaW5nIHJlZi5cbiAqL1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKipcbiAqIFJldHVybiB0aGUgdHlwZSBvZiBgdmFsYC5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSB2YWxcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih2YWwpe1xuICBzd2l0Y2ggKHRvU3RyaW5nLmNhbGwodmFsKSkge1xuICAgIGNhc2UgJ1tvYmplY3QgRGF0ZV0nOiByZXR1cm4gJ2RhdGUnO1xuICAgIGNhc2UgJ1tvYmplY3QgUmVnRXhwXSc6IHJldHVybiAncmVnZXhwJztcbiAgICBjYXNlICdbb2JqZWN0IEFyZ3VtZW50c10nOiByZXR1cm4gJ2FyZ3VtZW50cyc7XG4gICAgY2FzZSAnW29iamVjdCBBcnJheV0nOiByZXR1cm4gJ2FycmF5JztcbiAgICBjYXNlICdbb2JqZWN0IEVycm9yXSc6IHJldHVybiAnZXJyb3InO1xuICB9XG5cbiAgaWYgKHZhbCA9PT0gbnVsbCkgcmV0dXJuICdudWxsJztcbiAgaWYgKHZhbCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJ3VuZGVmaW5lZCc7XG4gIGlmICh2YWwgIT09IHZhbCkgcmV0dXJuICduYW4nO1xuICBpZiAodmFsICYmIHZhbC5ub2RlVHlwZSA9PT0gMSkgcmV0dXJuICdlbGVtZW50JztcblxuICB2YWwgPSB2YWwudmFsdWVPZlxuICAgID8gdmFsLnZhbHVlT2YoKVxuICAgIDogT2JqZWN0LnByb3RvdHlwZS52YWx1ZU9mLmFwcGx5KHZhbClcblxuICByZXR1cm4gdHlwZW9mIHZhbDtcbn07XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jb21wb25lbnQtdHlwZS9pbmRleC5qc1xuICoqIG1vZHVsZSBpZCA9IDcyXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJcbi8vIGVhc2luZyBmdW5jdGlvbnMgZnJvbSBcIlR3ZWVuLmpzXCJcblxuZXhwb3J0cy5saW5lYXIgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIG47XG59O1xuXG5leHBvcnRzLmluUXVhZCA9IGZ1bmN0aW9uKG4pe1xuICByZXR1cm4gbiAqIG47XG59O1xuXG5leHBvcnRzLm91dFF1YWQgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIG4gKiAoMiAtIG4pO1xufTtcblxuZXhwb3J0cy5pbk91dFF1YWQgPSBmdW5jdGlvbihuKXtcbiAgbiAqPSAyO1xuICBpZiAobiA8IDEpIHJldHVybiAwLjUgKiBuICogbjtcbiAgcmV0dXJuIC0gMC41ICogKC0tbiAqIChuIC0gMikgLSAxKTtcbn07XG5cbmV4cG9ydHMuaW5DdWJlID0gZnVuY3Rpb24obil7XG4gIHJldHVybiBuICogbiAqIG47XG59O1xuXG5leHBvcnRzLm91dEN1YmUgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIC0tbiAqIG4gKiBuICsgMTtcbn07XG5cbmV4cG9ydHMuaW5PdXRDdWJlID0gZnVuY3Rpb24obil7XG4gIG4gKj0gMjtcbiAgaWYgKG4gPCAxKSByZXR1cm4gMC41ICogbiAqIG4gKiBuO1xuICByZXR1cm4gMC41ICogKChuIC09IDIgKSAqIG4gKiBuICsgMik7XG59O1xuXG5leHBvcnRzLmluUXVhcnQgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIG4gKiBuICogbiAqIG47XG59O1xuXG5leHBvcnRzLm91dFF1YXJ0ID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAxIC0gKC0tbiAqIG4gKiBuICogbik7XG59O1xuXG5leHBvcnRzLmluT3V0UXVhcnQgPSBmdW5jdGlvbihuKXtcbiAgbiAqPSAyO1xuICBpZiAobiA8IDEpIHJldHVybiAwLjUgKiBuICogbiAqIG4gKiBuO1xuICByZXR1cm4gLTAuNSAqICgobiAtPSAyKSAqIG4gKiBuICogbiAtIDIpO1xufTtcblxuZXhwb3J0cy5pblF1aW50ID0gZnVuY3Rpb24obil7XG4gIHJldHVybiBuICogbiAqIG4gKiBuICogbjtcbn1cblxuZXhwb3J0cy5vdXRRdWludCA9IGZ1bmN0aW9uKG4pe1xuICByZXR1cm4gLS1uICogbiAqIG4gKiBuICogbiArIDE7XG59XG5cbmV4cG9ydHMuaW5PdXRRdWludCA9IGZ1bmN0aW9uKG4pe1xuICBuICo9IDI7XG4gIGlmIChuIDwgMSkgcmV0dXJuIDAuNSAqIG4gKiBuICogbiAqIG4gKiBuO1xuICByZXR1cm4gMC41ICogKChuIC09IDIpICogbiAqIG4gKiBuICogbiArIDIpO1xufTtcblxuZXhwb3J0cy5pblNpbmUgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIDEgLSBNYXRoLmNvcyhuICogTWF0aC5QSSAvIDIgKTtcbn07XG5cbmV4cG9ydHMub3V0U2luZSA9IGZ1bmN0aW9uKG4pe1xuICByZXR1cm4gTWF0aC5zaW4obiAqIE1hdGguUEkgLyAyKTtcbn07XG5cbmV4cG9ydHMuaW5PdXRTaW5lID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAuNSAqICgxIC0gTWF0aC5jb3MoTWF0aC5QSSAqIG4pKTtcbn07XG5cbmV4cG9ydHMuaW5FeHBvID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAwID09IG4gPyAwIDogTWF0aC5wb3coMTAyNCwgbiAtIDEpO1xufTtcblxuZXhwb3J0cy5vdXRFeHBvID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAxID09IG4gPyBuIDogMSAtIE1hdGgucG93KDIsIC0xMCAqIG4pO1xufTtcblxuZXhwb3J0cy5pbk91dEV4cG8gPSBmdW5jdGlvbihuKXtcbiAgaWYgKDAgPT0gbikgcmV0dXJuIDA7XG4gIGlmICgxID09IG4pIHJldHVybiAxO1xuICBpZiAoKG4gKj0gMikgPCAxKSByZXR1cm4gLjUgKiBNYXRoLnBvdygxMDI0LCBuIC0gMSk7XG4gIHJldHVybiAuNSAqICgtTWF0aC5wb3coMiwgLTEwICogKG4gLSAxKSkgKyAyKTtcbn07XG5cbmV4cG9ydHMuaW5DaXJjID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAxIC0gTWF0aC5zcXJ0KDEgLSBuICogbik7XG59O1xuXG5leHBvcnRzLm91dENpcmMgPSBmdW5jdGlvbihuKXtcbiAgcmV0dXJuIE1hdGguc3FydCgxIC0gKC0tbiAqIG4pKTtcbn07XG5cbmV4cG9ydHMuaW5PdXRDaXJjID0gZnVuY3Rpb24obil7XG4gIG4gKj0gMlxuICBpZiAobiA8IDEpIHJldHVybiAtMC41ICogKE1hdGguc3FydCgxIC0gbiAqIG4pIC0gMSk7XG4gIHJldHVybiAwLjUgKiAoTWF0aC5zcXJ0KDEgLSAobiAtPSAyKSAqIG4pICsgMSk7XG59O1xuXG5leHBvcnRzLmluQmFjayA9IGZ1bmN0aW9uKG4pe1xuICB2YXIgcyA9IDEuNzAxNTg7XG4gIHJldHVybiBuICogbiAqICgoIHMgKyAxICkgKiBuIC0gcyk7XG59O1xuXG5leHBvcnRzLm91dEJhY2sgPSBmdW5jdGlvbihuKXtcbiAgdmFyIHMgPSAxLjcwMTU4O1xuICByZXR1cm4gLS1uICogbiAqICgocyArIDEpICogbiArIHMpICsgMTtcbn07XG5cbmV4cG9ydHMuaW5PdXRCYWNrID0gZnVuY3Rpb24obil7XG4gIHZhciBzID0gMS43MDE1OCAqIDEuNTI1O1xuICBpZiAoICggbiAqPSAyICkgPCAxICkgcmV0dXJuIDAuNSAqICggbiAqIG4gKiAoICggcyArIDEgKSAqIG4gLSBzICkgKTtcbiAgcmV0dXJuIDAuNSAqICggKCBuIC09IDIgKSAqIG4gKiAoICggcyArIDEgKSAqIG4gKyBzICkgKyAyICk7XG59O1xuXG5leHBvcnRzLmluQm91bmNlID0gZnVuY3Rpb24obil7XG4gIHJldHVybiAxIC0gZXhwb3J0cy5vdXRCb3VuY2UoMSAtIG4pO1xufTtcblxuZXhwb3J0cy5vdXRCb3VuY2UgPSBmdW5jdGlvbihuKXtcbiAgaWYgKCBuIDwgKCAxIC8gMi43NSApICkge1xuICAgIHJldHVybiA3LjU2MjUgKiBuICogbjtcbiAgfSBlbHNlIGlmICggbiA8ICggMiAvIDIuNzUgKSApIHtcbiAgICByZXR1cm4gNy41NjI1ICogKCBuIC09ICggMS41IC8gMi43NSApICkgKiBuICsgMC43NTtcbiAgfSBlbHNlIGlmICggbiA8ICggMi41IC8gMi43NSApICkge1xuICAgIHJldHVybiA3LjU2MjUgKiAoIG4gLT0gKCAyLjI1IC8gMi43NSApICkgKiBuICsgMC45Mzc1O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiA3LjU2MjUgKiAoIG4gLT0gKCAyLjYyNSAvIDIuNzUgKSApICogbiArIDAuOTg0Mzc1O1xuICB9XG59O1xuXG5leHBvcnRzLmluT3V0Qm91bmNlID0gZnVuY3Rpb24obil7XG4gIGlmIChuIDwgLjUpIHJldHVybiBleHBvcnRzLmluQm91bmNlKG4gKiAyKSAqIC41O1xuICByZXR1cm4gZXhwb3J0cy5vdXRCb3VuY2UobiAqIDIgLSAxKSAqIC41ICsgLjU7XG59O1xuXG4vLyBhbGlhc2VzXG5cbmV4cG9ydHNbJ2luLXF1YWQnXSA9IGV4cG9ydHMuaW5RdWFkO1xuZXhwb3J0c1snb3V0LXF1YWQnXSA9IGV4cG9ydHMub3V0UXVhZDtcbmV4cG9ydHNbJ2luLW91dC1xdWFkJ10gPSBleHBvcnRzLmluT3V0UXVhZDtcbmV4cG9ydHNbJ2luLWN1YmUnXSA9IGV4cG9ydHMuaW5DdWJlO1xuZXhwb3J0c1snb3V0LWN1YmUnXSA9IGV4cG9ydHMub3V0Q3ViZTtcbmV4cG9ydHNbJ2luLW91dC1jdWJlJ10gPSBleHBvcnRzLmluT3V0Q3ViZTtcbmV4cG9ydHNbJ2luLXF1YXJ0J10gPSBleHBvcnRzLmluUXVhcnQ7XG5leHBvcnRzWydvdXQtcXVhcnQnXSA9IGV4cG9ydHMub3V0UXVhcnQ7XG5leHBvcnRzWydpbi1vdXQtcXVhcnQnXSA9IGV4cG9ydHMuaW5PdXRRdWFydDtcbmV4cG9ydHNbJ2luLXF1aW50J10gPSBleHBvcnRzLmluUXVpbnQ7XG5leHBvcnRzWydvdXQtcXVpbnQnXSA9IGV4cG9ydHMub3V0UXVpbnQ7XG5leHBvcnRzWydpbi1vdXQtcXVpbnQnXSA9IGV4cG9ydHMuaW5PdXRRdWludDtcbmV4cG9ydHNbJ2luLXNpbmUnXSA9IGV4cG9ydHMuaW5TaW5lO1xuZXhwb3J0c1snb3V0LXNpbmUnXSA9IGV4cG9ydHMub3V0U2luZTtcbmV4cG9ydHNbJ2luLW91dC1zaW5lJ10gPSBleHBvcnRzLmluT3V0U2luZTtcbmV4cG9ydHNbJ2luLWV4cG8nXSA9IGV4cG9ydHMuaW5FeHBvO1xuZXhwb3J0c1snb3V0LWV4cG8nXSA9IGV4cG9ydHMub3V0RXhwbztcbmV4cG9ydHNbJ2luLW91dC1leHBvJ10gPSBleHBvcnRzLmluT3V0RXhwbztcbmV4cG9ydHNbJ2luLWNpcmMnXSA9IGV4cG9ydHMuaW5DaXJjO1xuZXhwb3J0c1snb3V0LWNpcmMnXSA9IGV4cG9ydHMub3V0Q2lyYztcbmV4cG9ydHNbJ2luLW91dC1jaXJjJ10gPSBleHBvcnRzLmluT3V0Q2lyYztcbmV4cG9ydHNbJ2luLWJhY2snXSA9IGV4cG9ydHMuaW5CYWNrO1xuZXhwb3J0c1snb3V0LWJhY2snXSA9IGV4cG9ydHMub3V0QmFjaztcbmV4cG9ydHNbJ2luLW91dC1iYWNrJ10gPSBleHBvcnRzLmluT3V0QmFjaztcbmV4cG9ydHNbJ2luLWJvdW5jZSddID0gZXhwb3J0cy5pbkJvdW5jZTtcbmV4cG9ydHNbJ291dC1ib3VuY2UnXSA9IGV4cG9ydHMub3V0Qm91bmNlO1xuZXhwb3J0c1snaW4tb3V0LWJvdW5jZSddID0gZXhwb3J0cy5pbk91dEJvdW5jZTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Vhc2UtY29tcG9uZW50L2luZGV4LmpzXG4gKiogbW9kdWxlIGlkID0gNzNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8qKlxuICogRXhwb3NlIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKWAuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZVxuICB8fCB3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lXG4gIHx8IHdpbmRvdy5tb3pSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcbiAgfHwgZmFsbGJhY2s7XG5cbi8qKlxuICogRmFsbGJhY2sgaW1wbGVtZW50YXRpb24uXG4gKi9cblxudmFyIHByZXYgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbmZ1bmN0aW9uIGZhbGxiYWNrKGZuKSB7XG4gIHZhciBjdXJyID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIHZhciBtcyA9IE1hdGgubWF4KDAsIDE2IC0gKGN1cnIgLSBwcmV2KSk7XG4gIHZhciByZXEgPSBzZXRUaW1lb3V0KGZuLCBtcyk7XG4gIHByZXYgPSBjdXJyO1xuICByZXR1cm4gcmVxO1xufVxuXG4vKipcbiAqIENhbmNlbC5cbiAqL1xuXG52YXIgY2FuY2VsID0gd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lXG4gIHx8IHdpbmRvdy53ZWJraXRDYW5jZWxBbmltYXRpb25GcmFtZVxuICB8fCB3aW5kb3cubW96Q2FuY2VsQW5pbWF0aW9uRnJhbWVcbiAgfHwgd2luZG93LmNsZWFyVGltZW91dDtcblxuZXhwb3J0cy5jYW5jZWwgPSBmdW5jdGlvbihpZCl7XG4gIGNhbmNlbC5jYWxsKHdpbmRvdywgaWQpO1xufTtcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2NvbXBvbmVudC1yYWYvaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSA3NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBldmVudCA9IHtcbiAgLyoqXG4gICAqIG9wZW5VcmxcbiAgICogQHBhcmFtICB7c3RyaW5nfSB1cmxcbiAgICovXG4gIG9wZW5VUkw6IGZ1bmN0aW9uICh1cmwpIHtcbiAgICBsb2NhdGlvbi5ocmVmID0gdXJsXG4gIH1cblxufVxuXG5ldmVudC5fbWV0YSA9IHtcbiAgZXZlbnQ6IFt7XG4gICAgbmFtZTogJ29wZW5VUkwnLFxuICAgIGFyZ3M6IFsnc3RyaW5nJ11cbiAgfV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBldmVudFxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL2V2ZW50LmpzXG4gKiogbW9kdWxlIGlkID0gNzVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgcGFnZUluZm8gPSB7XG5cbiAgc2V0VGl0bGU6IGZ1bmN0aW9uICh0aXRsZSkge1xuICAgIHRpdGxlID0gdGl0bGUgfHwgJ1dlZXggSFRNTDUnXG4gICAgdHJ5IHtcbiAgICAgIHRpdGxlID0gZGVjb2RlVVJJQ29tcG9uZW50KHRpdGxlKVxuICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgZG9jdW1lbnQudGl0bGUgPSB0aXRsZVxuICB9XG59XG5cbnBhZ2VJbmZvLl9tZXRhID0ge1xuICBwYWdlSW5mbzogW3tcbiAgICBuYW1lOiAnc2V0VGl0bGUnLFxuICAgIGFyZ3M6IFsnc3RyaW5nJ11cbiAgfV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwYWdlSW5mb1xuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL3BhZ2VJbmZvLmpzXG4gKiogbW9kdWxlIGlkID0gNzZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG4vLyByZXF1aXJlKCdodHRwdXJsJylcblxuLy8gdmFyIGpzb25wQ250ID0gMFxuXG4vLyBmdW5jdGlvbiBfc2VuZEpzb25wKGNvbmZpZywgY2FsbGJhY2tJZCkge1xuLy8gICB2YXIgY2JOYW1lID0gJ19jYWxsYmFja18nICsgKCsranNvbnBDbnQpXG4vLyAgIHZhciBzY3JpcHQsIHVybCwgaGVhZFxuLy8gICBnbG9iYWxbY2JOYW1lXSA9IChmdW5jdGlvbiAoY2IpIHtcbi8vICAgICByZXR1cm4gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4vLyAgICAgICB0aGlzLnNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZCwgcmVzcG9uc2UpXG4vLyAgICAgICBkZWxldGUgZ2xvYmFsW2NiXVxuLy8gICAgIH1cbi8vICAgfSkoY2JOYW1lKVxuLy8gICBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKVxuLy8gICB1cmwgPSBsaWIuaHR0cHVybChjb25maWcudXJsKVxuLy8gICB1cmwucGFyYW1zLmNhbGxiYWNrID0gY2JOYW1lXG4vLyAgIHNjcmlwdC50eXBlID0gJ3RleHQvamF2YXNjcmlwdCdcbi8vICAgc2NyaXB0LnNyYyA9IHVybC50b1N0cmluZygpXG4vLyAgIC8vIHNjcmlwdC5vbmVycm9yIGlzIG5vdCB3b3JraW5nIG9uIElFIG9yIHNhZmFyaS5cbi8vICAgLy8gYnV0IHRoZXkgYXJlIG5vdCBjb25zaWRlcmVkIGhlcmUuXG4vLyAgIHNjcmlwdC5vbmVycm9yID0gKGZ1bmN0aW9uIChjYikge1xuLy8gICAgIHJldHVybiBmdW5jdGlvbiAoZXJyKSB7XG4vLyAgICAgICB0aGlzLnNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZCwgZXJyKVxuLy8gICAgICAgZGVsZXRlIGdsb2JhbFtjYl1cbi8vICAgICB9XG4vLyAgIH0pKGNiTmFtZSlcbi8vICAgaGVhZCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF1cbi8vICAgaGVhZC5pbnNlcnRCZWZvcmUoc2NyaXB0LCBudWxsKVxuLy8gfVxuXG52YXIgc3RyZWFtID0ge1xuXG4gIC8qKlxuICAgKiBzZW5kSHR0cFxuICAgKiBAcGFyYW0gIHtvYmp9IHBhcmFtc1xuICAgKiAgLSBtZXRob2Q6ICdHRVQnIHwgJ1BPU1QnLFxuICAgKiAgLSB1cmw6IHVybCByZXF1ZXN0ZWRcbiAgICogQHBhcmFtICB7c3RyaW5nfSBjYWxsYmFja0lkXG4gICAqL1xuICBzZW5kSHR0cDogZnVuY3Rpb24gKHBhcmFtLCBjYWxsYmFja0lkKSB7XG4gICAgaWYgKHR5cGVvZiBwYXJhbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHBhcmFtID0gSlNPTi5wYXJzZShwYXJhbSlcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGFyYW0gIT09ICdvYmplY3QnIHx8ICFwYXJhbS51cmwpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIE5vdCB0byB1c2UganNvbnAgdG8gc2VuZCBodHRwIHJlcXVlc3Qgc2luY2UgaXQgcmVxdWlyZXMgdGhlIHNlcnZlclxuICAgIC8vIHRvIHN1cHBvcnQganNvbnAgY2FsbGJhY2sgYXQgdGhlIGZpcnN0IHBsYWNlLlxuICAgIC8vIF9zZW5kSnNvbnAuY2FsbCh0aGlzLCBwYXJhbSwgY2FsbGJhY2tJZClcblxuICAgIHZhciBzZWxmID0gdGhpc1xuICAgIHZhciBtZXRob2QgPSBwYXJhbS5tZXRob2QgfHwgJ0dFVCdcbiAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICB4aHIub3BlbihtZXRob2QsIHBhcmFtLnVybCwgdHJ1ZSlcbiAgICB4aHIub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgc2VsZi5zZW5kZXIucGVyZm9ybUNhbGxiYWNrKGNhbGxiYWNrSWQsIHRoaXMucmVzcG9uc2VUZXh0KVxuICAgIH1cbiAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgc2VsZi5zZW5kZXIucGVyZm9ybUNhbGxiYWNrKGNhbGxiYWNrSWQsIGVycm9yKVxuICAgIH1cbiAgICB4aHIuc2VuZCgpXG4gIH1cblxufVxuXG5zdHJlYW0uX21ldGEgPSB7XG4gIHN0cmVhbTogW3tcbiAgICBuYW1lOiAnc2VuZEh0dHAnLFxuICAgIGFyZ3M6IFsnb2JqZWN0JywgJ3N0cmluZyddXG4gIH1dXG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3RyZWFtXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9hcGkvc3RyZWFtLmpzXG4gKiogbW9kdWxlIGlkID0gNzdcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgc2VuZGVyID0gcmVxdWlyZSgnLi4vYnJpZGdlL3NlbmRlcicpXG52YXIgbW9kYWwgPSByZXF1aXJlKCdtb2RhbHMnKVxuXG52YXIgbXNnID0ge1xuXG4gIC8vIGR1cmF0aW9uOiBkZWZhdWx0IGlzIDAuOCBzZWNvbmRzLlxuICB0b2FzdDogZnVuY3Rpb24gKGNvbmZpZykge1xuICAgIG1vZGFsLnRvYXN0KGNvbmZpZy5tZXNzYWdlLCBjb25maWcuZHVyYXRpb24pXG4gIH0sXG5cbiAgLy8gY29uZmlnOlxuICAvLyAgLSBtZXNzYWdlOiBzdHJpbmdcbiAgLy8gIC0gb2tUaXRsZTogdGl0bGUgb2Ygb2sgYnV0dG9uXG4gIC8vICAtIGNhbGxiYWNrXG4gIGFsZXJ0OiBmdW5jdGlvbiAoY29uZmlnLCBjYWxsYmFja0lkKSB7XG4gICAgdmFyIHNlbmRlciA9ICB0aGlzLnNlbmRlclxuICAgIGNvbmZpZy5jYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZClcbiAgICB9XG4gICAgbW9kYWwuYWxlcnQoY29uZmlnKVxuICB9LFxuXG4gIC8vIGNvbmZpZzpcbiAgLy8gIC0gbWVzc2FnZTogc3RyaW5nXG4gIC8vICAtIG9rVGl0bGU6IHRpdGxlIG9mIG9rIGJ1dHRvblxuICAvLyAgLSBjYW5jZWxUaXRsZTogdGl0bGUgb2YgY2FuY2VsIGJ1dHRvblxuICAvLyAgLSBjYWxsYmFja1xuICBjb25maXJtOiBmdW5jdGlvbiAoY29uZmlnLCBjYWxsYmFja0lkKSB7XG4gICAgdmFyIHNlbmRlciA9ICB0aGlzLnNlbmRlclxuICAgIGNvbmZpZy5jYWxsYmFjayA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIHNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZCwgdmFsKVxuICAgIH1cbiAgICBtb2RhbC5jb25maXJtKGNvbmZpZylcbiAgfSxcblxuICAvLyBjb25maWc6XG4gIC8vICAtIG1lc3NhZ2U6IHN0cmluZ1xuICAvLyAgLSBva1RpdGxlOiB0aXRsZSBvZiBvayBidXR0b25cbiAgLy8gIC0gY2FuY2VsVGl0bGU6IHRpdGxlIG9mIGNhbmNlbCBidXR0b25cbiAgLy8gIC0gY2FsbGJhY2tcbiAgcHJvbXB0OiBmdW5jdGlvbiAoY29uZmlnLCBjYWxsYmFja0lkKSB7XG4gICAgdmFyIHNlbmRlciA9ICB0aGlzLnNlbmRlclxuICAgIGNvbmZpZy5jYWxsYmFjayA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIHNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZCwgdmFsKVxuICAgIH1cbiAgICBtb2RhbC5wcm9tcHQoY29uZmlnKVxuICB9XG5cbn1cblxubXNnLl9tZXRhID0ge1xuICBtb2RhbDogW3tcbiAgICBuYW1lOiAndG9hc3QnLFxuICAgIGFyZ3M6IFsnb2JqZWN0J11cbiAgfSwge1xuICAgIG5hbWU6ICdhbGVydCcsXG4gICAgYXJnczogWydvYmplY3QnLCAnc3RyaW5nJ11cbiAgfSwge1xuICAgIG5hbWU6ICdjb25maXJtJyxcbiAgICBhcmdzOiBbJ29iamVjdCcsICdzdHJpbmcnXVxuICB9LCB7XG4gICAgbmFtZTogJ3Byb21wdCcsXG4gICAgYXJnczogWydvYmplY3QnLCAnc3RyaW5nJ11cbiAgfV1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtc2dcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9zcmMvYXBpL21vZGFsLmpzXG4gKiogbW9kdWxlIGlkID0gNzhcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG52YXIgQWxlcnQgPSByZXF1aXJlKCcuL2FsZXJ0JylcbnZhciBDb25maXJtID0gcmVxdWlyZSgnLi9jb25maXJtJylcbnZhciBQcm9tcHQgPSByZXF1aXJlKCcuL3Byb21wdCcpXG52YXIgdG9hc3QgPSByZXF1aXJlKCcuL3RvYXN0JylcblxudmFyIG1vZGFsID0ge1xuXG4gIHRvYXN0OiBmdW5jdGlvbiAobXNnLCBkdXJhdGlvbikge1xuICAgIHRvYXN0LnB1c2gobXNnLCBkdXJhdGlvbilcbiAgfSxcblxuICBhbGVydDogZnVuY3Rpb24gKGNvbmZpZykge1xuICAgIG5ldyBBbGVydChjb25maWcpLnNob3coKVxuICB9LFxuXG4gIHByb21wdDogZnVuY3Rpb24gKGNvbmZpZykge1xuICAgIG5ldyBQcm9tcHQoY29uZmlnKS5zaG93KClcbiAgfSxcblxuICBjb25maXJtOiBmdW5jdGlvbiAoY29uZmlnKSB7XG4gICAgbmV3IENvbmZpcm0oY29uZmlnKS5zaG93KClcbiAgfVxuXG59XG5cbiF3aW5kb3cubGliICYmICh3aW5kb3cubGliID0ge30pXG53aW5kb3cubGliLm1vZGFsID0gbW9kYWxcblxubW9kdWxlLmV4cG9ydHMgPSBtb2RhbFxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L21vZGFscy9zcmMvaW5kZXguanNcbiAqKiBtb2R1bGUgaWQgPSA3OVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBNb2RhbCA9IHJlcXVpcmUoJy4vbW9kYWwnKVxucmVxdWlyZSgnLi4vc3R5bGVzL2FsZXJ0LnNjc3MnKVxuXG52YXIgQ09OVEVOVF9DTEFTUyA9ICdjb250ZW50J1xudmFyIE1TR19DTEFTUyA9ICdjb250ZW50LW1zZydcbnZhciBCVVRUT05fR1JPVVBfQ0xBU1MgPSAnYnRuLWdyb3VwJ1xudmFyIEJVVFRPTl9DTEFTUyA9ICdidG4nXG5cbmZ1bmN0aW9uIEFsZXJ0KGNvbmZpZykge1xuICB0aGlzLm1zZyA9IGNvbmZpZy5tZXNzYWdlIHx8ICcnXG4gIHRoaXMuY2FsbGJhY2sgPSBjb25maWcuY2FsbGJhY2tcbiAgdGhpcy5va1RpdGxlID0gY29uZmlnLm9rVGl0bGUgfHwgJ09LJ1xuICBNb2RhbC5jYWxsKHRoaXMpXG4gIHRoaXMubm9kZS5jbGFzc0xpc3QuYWRkKCdhbWZlLWFsZXJ0Jylcbn1cblxuQWxlcnQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShNb2RhbC5wcm90b3R5cGUpXG5cbkFsZXJ0LnByb3RvdHlwZS5jcmVhdGVOb2RlQ29udGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBjb250ZW50LmNsYXNzTGlzdC5hZGQoQ09OVEVOVF9DTEFTUylcbiAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKGNvbnRlbnQpXG5cbiAgdmFyIG1zZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG1zZy5jbGFzc0xpc3QuYWRkKE1TR19DTEFTUylcbiAgbXNnLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMubXNnKSlcbiAgY29udGVudC5hcHBlbmRDaGlsZChtc2cpXG5cbiAgdmFyIGJ1dHRvbkdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgYnV0dG9uR3JvdXAuY2xhc3NMaXN0LmFkZChCVVRUT05fR1JPVVBfQ0xBU1MpXG4gIHRoaXMubm9kZS5hcHBlbmRDaGlsZChidXR0b25Hcm91cClcbiAgdmFyIGJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGJ1dHRvbi5jbGFzc0xpc3QuYWRkKEJVVFRPTl9DTEFTUywgJ2FsZXJ0LW9rJylcbiAgYnV0dG9uLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMub2tUaXRsZSkpXG4gIGJ1dHRvbkdyb3VwLmFwcGVuZENoaWxkKGJ1dHRvbilcbn1cblxuQWxlcnQucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gIE1vZGFsLnByb3RvdHlwZS5iaW5kRXZlbnRzLmNhbGwodGhpcylcbiAgdmFyIGJ1dHRvbiA9IHRoaXMubm9kZS5xdWVyeVNlbGVjdG9yKCcuJyArIEJVVFRPTl9DTEFTUylcbiAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZGVzdHJveSgpXG4gICAgdGhpcy5jYWxsYmFjayAmJiB0aGlzLmNhbGxiYWNrKClcbiAgfS5iaW5kKHRoaXMpKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEFsZXJ0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3JjL2FsZXJ0LmpzXG4gKiogbW9kdWxlIGlkID0gODBcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIid1c2Ugc3RyaWN0J1xuXG5yZXF1aXJlKCcuLi9zdHlsZXMvbW9kYWwuc2NzcycpXG5cbi8vIHRoZXJlIHdpbGwgYmUgb25seSBvbmUgaW5zdGFuY2Ugb2YgbW9kYWwuXG52YXIgTU9EQUxfV1JBUF9DTEFTUyA9ICdhbWZlLW1vZGFsLXdyYXAnXG52YXIgTU9EQUxfTk9ERV9DTEFTUyA9ICdhbWZlLW1vZGFsLW5vZGUnXG5cbmZ1bmN0aW9uIE1vZGFsKCkge1xuICB0aGlzLndyYXAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKE1PREFMX1dSQVBfQ0xBU1MpXG4gIHRoaXMubm9kZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoTU9EQUxfTk9ERV9DTEFTUylcbiAgaWYgKCF0aGlzLndyYXApIHtcbiAgICB0aGlzLmNyZWF0ZVdyYXAoKVxuICB9XG4gIGlmICghdGhpcy5ub2RlKSB7XG4gICAgdGhpcy5jcmVhdGVOb2RlKClcbiAgfVxuICB0aGlzLmNsZWFyTm9kZSgpXG4gIHRoaXMuY3JlYXRlTm9kZUNvbnRlbnQoKVxuICB0aGlzLmJpbmRFdmVudHMoKVxufVxuXG5Nb2RhbC5wcm90b3R5cGUgPSB7XG5cbiAgc2hvdzogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMud3JhcC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJ1xuICAgIHRoaXMubm9kZS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJylcbiAgfSxcblxuICBkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0aGlzLndyYXApXG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0aGlzLm5vZGUpXG4gICAgdGhpcy53cmFwID0gbnVsbFxuICAgIHRoaXMubm9kZSA9IG51bGxcbiAgfSxcblxuICBjcmVhdGVXcmFwOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy53cmFwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICB0aGlzLndyYXAuY2xhc3NOYW1lID0gTU9EQUxfV1JBUF9DTEFTU1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy53cmFwKVxuICB9LFxuXG4gIGNyZWF0ZU5vZGU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLm5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgIHRoaXMubm9kZS5jbGFzc0xpc3QuYWRkKE1PREFMX05PREVfQ0xBU1MsICdoaWRlJylcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMubm9kZSlcbiAgfSxcblxuICBjbGVhck5vZGU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLm5vZGUuaW5uZXJIVE1MID0gJydcbiAgfSxcblxuICBjcmVhdGVOb2RlQ29udGVudDogZnVuY3Rpb24gKCkge1xuXG4gICAgLy8gZG8gbm90aGluZy5cbiAgICAvLyBjaGlsZCBjbGFzc2VzIGNhbiBvdmVycmlkZSB0aGlzIG1ldGhvZC5cbiAgfSxcblxuICBiaW5kRXZlbnRzOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy53cmFwLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuICAgIH0pXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBNb2RhbFxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbW9kYWxzL3NyYy9tb2RhbC5qc1xuICoqIG1vZHVsZSBpZCA9IDgxXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL21vZGFsLnNjc3NcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vLi4vc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vLi4vY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9tb2RhbC5zY3NzXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vbW9kYWwuc2Nzc1wiKTtcblx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdH0pO1xuXHR9XG5cdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbW9kYWxzL3N0eWxlcy9tb2RhbC5zY3NzXG4gKiogbW9kdWxlIGlkID0gODJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCIuYW1mZS1tb2RhbC13cmFwIHtcXG4gIGRpc3BsYXk6IG5vbmU7XFxuICBwb3NpdGlvbjogZml4ZWQ7XFxuICB6LWluZGV4OiA5OTk5OTk5OTk7XFxuICB0b3A6IDA7XFxuICBsZWZ0OiAwO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IDEwMCU7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwO1xcbiAgb3BhY2l0eTogMC41OyB9XFxuXFxuLmFtZmUtbW9kYWwtbm9kZSB7XFxuICBwb3NpdGlvbjogZml4ZWQ7XFxuICB6LWluZGV4OiA5OTk5OTk5OTk5O1xcbiAgdG9wOiA1MCU7XFxuICBsZWZ0OiA1MCU7XFxuICB3aWR0aDogNi42NjY2NjdyZW07XFxuICBtaW4taGVpZ2h0OiAyLjY2NjY2N3JlbTtcXG4gIGJvcmRlci1yYWRpdXM6IDAuMDY2NjY3cmVtO1xcbiAgLXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKTtcXG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsgfVxcbiAgLmFtZmUtbW9kYWwtbm9kZS5oaWRlIHtcXG4gICAgZGlzcGxheTogbm9uZTsgfVxcbiAgLmFtZmUtbW9kYWwtbm9kZSAuY29udGVudCB7XFxuICAgIHdpZHRoOiAxMDAlO1xcbiAgICBtaW4taGVpZ2h0OiAxLjg2NjY2N3JlbTtcXG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gICAgZm9udC1zaXplOiAwLjMycmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC40MjY2NjdyZW07XFxuICAgIHBhZGRpbmc6IDAuMjEzMzMzcmVtO1xcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2RkZDsgfVxcbiAgLmFtZmUtbW9kYWwtbm9kZSAuYnRuLWdyb3VwIHtcXG4gICAgd2lkdGg6IDEwMCU7XFxuICAgIGhlaWdodDogMC44cmVtO1xcbiAgICBmb250LXNpemU6IDAuMzczMzMzcmVtO1xcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7IH1cXG4gICAgLmFtZmUtbW9kYWwtbm9kZSAuYnRuLWdyb3VwIC5idG4ge1xcbiAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAgICAgaGVpZ2h0OiAwLjhyZW07XFxuICAgICAgbGluZS1oZWlnaHQ6IDAuOHJlbTsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9ub2RlX21vZHVsZXMvbW9kYWxzL25vZGVfbW9kdWxlcy9tb2RhbHMvc3R5bGVzL21vZGFsLnNjc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7RUFDRSxjQUFjO0VBQ2QsZ0JBQWdCO0VBQ2hCLG1CQUFtQjtFQUNuQixPQUFPO0VBQ1AsUUFBUTtFQUNSLFlBQVk7RUFDWixhQUFhO0VBQ2IsdUJBQXVCO0VBQ3ZCLGFBQWEsRUFFZDs7QUFFRDtFQUNFLGdCQUFnQjtFQUNoQixvQkFBb0I7RUFDcEIsU0FBUztFQUNULFVBQVU7RUFDVixtQkFBbUI7RUFDbkIsd0JBQXdCO0VBQ3hCLDJCQUEyQjtFQUMzQix5Q0FBNEI7RUFDNUIsaUNBQW9CO0VBQ3BCLHVCQUF1QixFQTRCeEI7RUF0Q0Q7SUFhSSxjQUNELEVBQUM7RUFkSjtJQWlCSSxZQUFZO0lBQ1osd0JBQXdCO0lBQ3hCLHVCQUF1QjtJQUN2QixtQkFBbUI7SUFDbkIseUJBQXlCO0lBQ3pCLHFCQUFxQjtJQUNyQiw4QkFBOEIsRUFDL0I7RUF4Qkg7SUEyQkksWUFBWTtJQUNaLGVBQWU7SUFDZix1QkFBdUI7SUFDdkIsbUJBQW1CLEVBT3BCO0lBckNIO01BaUNNLHVCQUF1QjtNQUN2QixlQUFlO01BQ2Ysb0JBQW9CLEVBQ3JCXCIsXCJmaWxlXCI6XCJtb2RhbC5zY3NzXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi5hbWZlLW1vZGFsLXdyYXAge1xcbiAgZGlzcGxheTogbm9uZTtcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXG4gIHotaW5kZXg6IDk5OTk5OTk5OTtcXG4gIHRvcDogMDtcXG4gIGxlZnQ6IDA7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogMTAwJTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDA7XFxuICBvcGFjaXR5OiAwLjU7XFxuXFxufVxcblxcbi5hbWZlLW1vZGFsLW5vZGUge1xcbiAgcG9zaXRpb246IGZpeGVkO1xcbiAgei1pbmRleDogOTk5OTk5OTk5OTtcXG4gIHRvcDogNTAlO1xcbiAgbGVmdDogNTAlO1xcbiAgd2lkdGg6IDYuNjY2NjY3cmVtOyAvLyA1MDBweFxcbiAgbWluLWhlaWdodDogMi42NjY2NjdyZW07IC8vIDIwMHB4XFxuICBib3JkZXItcmFkaXVzOiAwLjA2NjY2N3JlbTsgLy8gNXB4XFxuICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpO1xcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xcblxcbiAgJi5oaWRlIHtcXG4gICAgZGlzcGxheTogbm9uZVxcbiAgfVxcblxcbiAgLmNvbnRlbnQge1xcbiAgICB3aWR0aDogMTAwJTtcXG4gICAgbWluLWhlaWdodDogMS44NjY2NjdyZW07IC8vIDE0MHB4XFxuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAgIGZvbnQtc2l6ZTogMC4zMnJlbTsgLy8gMjRweFxcbiAgICBsaW5lLWhlaWdodDogMC40MjY2NjdyZW07IC8vIDMycHhcXG4gICAgcGFkZGluZzogMC4yMTMzMzNyZW07IC8vIDE2cHhcXG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNkZGQ7XFxuICB9XFxuXFxuICAuYnRuLWdyb3VwIHtcXG4gICAgd2lkdGg6IDEwMCU7XFxuICAgIGhlaWdodDogMC44cmVtOyAvLyA2MHB4XFxuICAgIGZvbnQtc2l6ZTogMC4zNzMzMzNyZW07IC8vIDI4cHhcXG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xcblxcbiAgICAuYnRuIHtcXG4gICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICAgIGhlaWdodDogMC44cmVtOyAvLyA2MHB4XFxuICAgICAgbGluZS1oZWlnaHQ6IDAuOHJlbTsgLy8gNjBweFxcbiAgICB9XFxuICB9XFxufVxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Nhc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vbW9kYWxzL3N0eWxlcy9tb2RhbC5zY3NzXG4gKiogbW9kdWxlIGlkID0gODNcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vYWxlcnQuc2Nzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL2FsZXJ0LnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9hbGVydC5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3R5bGVzL2FsZXJ0LnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA4NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi5hbWZlLWFsZXJ0IC5hbWZlLWFsZXJ0LW9rIHtcXG4gIHdpZHRoOiAxMDAlOyB9XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL25vZGVfbW9kdWxlcy9tb2RhbHMvbm9kZV9tb2R1bGVzL21vZGFscy9zdHlsZXMvYWxlcnQuc2Nzc1wiXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiQUFBQTtFQUdJLFlBQVksRUFDYlwiLFwiZmlsZVwiOlwiYWxlcnQuc2Nzc1wiLFwic291cmNlc0NvbnRlbnRcIjpbXCIuYW1mZS1hbGVydCB7XFxuXFxuICAuYW1mZS1hbGVydC1vayB7XFxuICAgIHdpZHRoOiAxMDAlO1xcbiAgfVxcbn1cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L21vZGFscy9zdHlsZXMvYWxlcnQuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDg1XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIE1vZGFsID0gcmVxdWlyZSgnLi9tb2RhbCcpXG5yZXF1aXJlKCcuLi9zdHlsZXMvY29uZmlybS5zY3NzJylcblxudmFyIENPTlRFTlRfQ0xBU1MgPSAnY29udGVudCdcbnZhciBNU0dfQ0xBU1MgPSAnY29udGVudC1tc2cnXG52YXIgQlVUVE9OX0dST1VQX0NMQVNTID0gJ2J0bi1ncm91cCdcbnZhciBCVVRUT05fQ0xBU1MgPSAnYnRuJ1xuXG5mdW5jdGlvbiBDb25maXJtKGNvbmZpZykge1xuICB0aGlzLm1zZyA9IGNvbmZpZy5tZXNzYWdlIHx8ICcnXG4gIHRoaXMuY2FsbGJhY2sgPSBjb25maWcuY2FsbGJhY2tcbiAgdGhpcy5va1RpdGxlID0gY29uZmlnLm9rVGl0bGUgfHwgJ09LJ1xuICB0aGlzLmNhbmNlbFRpdGxlID0gY29uZmlnLmNhbmNlbFRpdGxlIHx8ICdDYW5jZWwnXG4gIE1vZGFsLmNhbGwodGhpcylcbiAgdGhpcy5ub2RlLmNsYXNzTGlzdC5hZGQoJ2FtZmUtY29uZmlybScpXG59XG5cbkNvbmZpcm0ucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShNb2RhbC5wcm90b3R5cGUpXG5cbkNvbmZpcm0ucHJvdG90eXBlLmNyZWF0ZU5vZGVDb250ZW50ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgY29udGVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGNvbnRlbnQuY2xhc3NMaXN0LmFkZChDT05URU5UX0NMQVNTKVxuICB0aGlzLm5vZGUuYXBwZW5kQ2hpbGQoY29udGVudClcblxuICB2YXIgbXNnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgbXNnLmNsYXNzTGlzdC5hZGQoTVNHX0NMQVNTKVxuICBtc2cuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGhpcy5tc2cpKVxuICBjb250ZW50LmFwcGVuZENoaWxkKG1zZylcblxuICB2YXIgYnV0dG9uR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBidXR0b25Hcm91cC5jbGFzc0xpc3QuYWRkKEJVVFRPTl9HUk9VUF9DTEFTUylcbiAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKGJ1dHRvbkdyb3VwKVxuICB2YXIgYnRuT2sgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBidG5Pay5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0aGlzLm9rVGl0bGUpKVxuICBidG5Pay5jbGFzc0xpc3QuYWRkKCdidG4tb2snLCBCVVRUT05fQ0xBU1MpXG4gIHZhciBidG5DYW5jZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBidG5DYW5jZWwuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGhpcy5jYW5jZWxUaXRsZSkpXG4gIGJ0bkNhbmNlbC5jbGFzc0xpc3QuYWRkKCdidG4tY2FuY2VsJywgQlVUVE9OX0NMQVNTKVxuICBidXR0b25Hcm91cC5hcHBlbmRDaGlsZChidG5PaylcbiAgYnV0dG9uR3JvdXAuYXBwZW5kQ2hpbGQoYnRuQ2FuY2VsKVxuICB0aGlzLm5vZGUuYXBwZW5kQ2hpbGQoYnV0dG9uR3JvdXApXG59XG5cbkNvbmZpcm0ucHJvdG90eXBlLmJpbmRFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gIE1vZGFsLnByb3RvdHlwZS5iaW5kRXZlbnRzLmNhbGwodGhpcylcbiAgdmFyIGJ0bk9rID0gdGhpcy5ub2RlLnF1ZXJ5U2VsZWN0b3IoJy4nICsgQlVUVE9OX0NMQVNTICsgJy5idG4tb2snKVxuICB2YXIgYnRuQ2FuY2VsID0gdGhpcy5ub2RlLnF1ZXJ5U2VsZWN0b3IoJy4nICsgQlVUVE9OX0NMQVNTICsgJy5idG4tY2FuY2VsJylcbiAgYnRuT2suYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5kZXN0cm95KClcbiAgICB0aGlzLmNhbGxiYWNrICYmIHRoaXMuY2FsbGJhY2sodGhpcy5va1RpdGxlKVxuICB9LmJpbmQodGhpcykpXG4gIGJ0bkNhbmNlbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmRlc3Ryb3koKVxuICAgIHRoaXMuY2FsbGJhY2sgJiYgdGhpcy5jYWxsYmFjayh0aGlzLmNhbmNlbFRpdGxlKVxuICB9LmJpbmQodGhpcykpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ29uZmlybVxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbW9kYWxzL3NyYy9jb25maXJtLmpzXG4gKiogbW9kdWxlIGlkID0gODZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vY29uZmlybS5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vY29uZmlybS5zY3NzXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vY29uZmlybS5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3R5bGVzL2NvbmZpcm0uc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDg3XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiLmFtZmUtY29uZmlybSAuYnRuLWdyb3VwIC5idG4ge1xcbiAgZmxvYXQ6IGxlZnQ7XFxuICB3aWR0aDogNTAlOyB9XFxuICAuYW1mZS1jb25maXJtIC5idG4tZ3JvdXAgLmJ0bi5idG4tb2sge1xcbiAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZGRkOyB9XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL25vZGVfbW9kdWxlcy9tb2RhbHMvbm9kZV9tb2R1bGVzL21vZGFscy9zdHlsZXMvY29uZmlybS5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBS00sWUFBWTtFQUNaLFdBQVcsRUFLWjtFQVhMO0lBU08sNkJBQTZCLEVBQzdCXCIsXCJmaWxlXCI6XCJjb25maXJtLnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLmFtZmUtY29uZmlybSB7XFxuXFxuICAuYnRuLWdyb3VwIHtcXG5cXG4gICAgLmJ0biB7XFxuICAgICAgZmxvYXQ6IGxlZnQ7XFxuICAgICAgd2lkdGg6IDUwJTtcXG5cXG4gICAgICAmLmJ0bi1vayB7XFxuICAgICAgXFx0Ym9yZGVyLXJpZ2h0OiAxcHggc29saWQgI2RkZDtcXG4gICAgICB9XFxuICAgIH1cXG4gIH1cXG59XCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9tb2RhbHMvc3R5bGVzL2NvbmZpcm0uc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDg4XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIndXNlIHN0cmljdCdcblxudmFyIE1vZGFsID0gcmVxdWlyZSgnLi9tb2RhbCcpXG5yZXF1aXJlKCcuLi9zdHlsZXMvcHJvbXB0LnNjc3MnKVxuXG52YXIgQ09OVEVOVF9DTEFTUyA9ICdjb250ZW50J1xudmFyIE1TR19DTEFTUyA9ICdjb250ZW50LW1zZydcbnZhciBCVVRUT05fR1JPVVBfQ0xBU1MgPSAnYnRuLWdyb3VwJ1xudmFyIEJVVFRPTl9DTEFTUyA9ICdidG4nXG52YXIgSU5QVVRfV1JBUF9DTEFTUyA9ICdpbnB1dC13cmFwJ1xudmFyIElOUFVUX0NMQVNTID0gJ2lucHV0J1xuXG5mdW5jdGlvbiBQcm9tcHQoY29uZmlnKSB7XG4gIHRoaXMubXNnID0gY29uZmlnLm1lc3NhZ2UgfHwgJydcbiAgdGhpcy5kZWZhdWx0TXNnID0gY29uZmlnLmRlZmF1bHQgfHwgJydcbiAgdGhpcy5jYWxsYmFjayA9IGNvbmZpZy5jYWxsYmFja1xuICB0aGlzLm9rVGl0bGUgPSBjb25maWcub2tUaXRsZSB8fCAnT0snXG4gIHRoaXMuY2FuY2VsVGl0bGUgPSBjb25maWcuY2FuY2VsVGl0bGUgfHwgJ0NhbmNlbCdcbiAgTW9kYWwuY2FsbCh0aGlzKVxuICB0aGlzLm5vZGUuY2xhc3NMaXN0LmFkZCgnYW1mZS1wcm9tcHQnKVxufVxuXG5Qcm9tcHQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShNb2RhbC5wcm90b3R5cGUpXG5cblByb21wdC5wcm90b3R5cGUuY3JlYXRlTm9kZUNvbnRlbnQgPSBmdW5jdGlvbiAoKSB7XG5cbiAgdmFyIGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICBjb250ZW50LmNsYXNzTGlzdC5hZGQoQ09OVEVOVF9DTEFTUylcbiAgdGhpcy5ub2RlLmFwcGVuZENoaWxkKGNvbnRlbnQpXG5cbiAgdmFyIG1zZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIG1zZy5jbGFzc0xpc3QuYWRkKE1TR19DTEFTUylcbiAgbXNnLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMubXNnKSlcbiAgY29udGVudC5hcHBlbmRDaGlsZChtc2cpXG5cbiAgdmFyIGlucHV0V3JhcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGlucHV0V3JhcC5jbGFzc0xpc3QuYWRkKElOUFVUX1dSQVBfQ0xBU1MpXG4gIGNvbnRlbnQuYXBwZW5kQ2hpbGQoaW5wdXRXcmFwKVxuICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpXG4gIGlucHV0LmNsYXNzTGlzdC5hZGQoSU5QVVRfQ0xBU1MpXG4gIGlucHV0LnR5cGUgPSAndGV4dCdcbiAgaW5wdXQuYXV0b2ZvY3VzID0gdHJ1ZVxuICBpbnB1dC5wbGFjZWhvbGRlciA9IHRoaXMuZGVmYXVsdE1zZ1xuICBpbnB1dFdyYXAuYXBwZW5kQ2hpbGQoaW5wdXQpXG5cbiAgdmFyIGJ1dHRvbkdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgYnV0dG9uR3JvdXAuY2xhc3NMaXN0LmFkZChCVVRUT05fR1JPVVBfQ0xBU1MpXG4gIHZhciBidG5PayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGJ0bk9rLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMub2tUaXRsZSkpXG4gIGJ0bk9rLmNsYXNzTGlzdC5hZGQoJ2J0bi1vaycsIEJVVFRPTl9DTEFTUylcbiAgdmFyIGJ0bkNhbmNlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gIGJ0bkNhbmNlbC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0aGlzLmNhbmNlbFRpdGxlKSlcbiAgYnRuQ2FuY2VsLmNsYXNzTGlzdC5hZGQoJ2J0bi1jYW5jZWwnLCBCVVRUT05fQ0xBU1MpXG4gIGJ1dHRvbkdyb3VwLmFwcGVuZENoaWxkKGJ0bk9rKVxuICBidXR0b25Hcm91cC5hcHBlbmRDaGlsZChidG5DYW5jZWwpXG4gIHRoaXMubm9kZS5hcHBlbmRDaGlsZChidXR0b25Hcm91cClcbn1cblxuUHJvbXB0LnByb3RvdHlwZS5iaW5kRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICBNb2RhbC5wcm90b3R5cGUuYmluZEV2ZW50cy5jYWxsKHRoaXMpXG4gIHZhciBidG5PayA9IHRoaXMubm9kZS5xdWVyeVNlbGVjdG9yKCcuJyArIEJVVFRPTl9DTEFTUyArICcuYnRuLW9rJylcbiAgdmFyIGJ0bkNhbmNlbCA9IHRoaXMubm9kZS5xdWVyeVNlbGVjdG9yKCcuJyArIEJVVFRPTl9DTEFTUyArICcuYnRuLWNhbmNlbCcpXG4gIHZhciB0aGF0ID0gdGhpc1xuICBidG5Pay5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXQnKS52YWx1ZVxuICAgIHRoaXMuZGVzdHJveSgpXG4gICAgdGhpcy5jYWxsYmFjayAmJiB0aGlzLmNhbGxiYWNrKHtcbiAgICAgIHJlc3VsdDogdGhhdC5va1RpdGxlLFxuICAgICAgZGF0YTogdmFsXG4gICAgfSlcbiAgfS5iaW5kKHRoaXMpKVxuICBidG5DYW5jZWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0JykudmFsdWVcbiAgICB0aGlzLmRlc3Ryb3koKVxuICAgIHRoaXMuY2FsbGJhY2sgJiYgdGhpcy5jYWxsYmFjayh7XG4gICAgICByZXN1bHQ6IHRoYXQuY2FuY2VsVGl0bGVcbiAgICB9KVxuICB9LmJpbmQodGhpcykpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvbXB0XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3JjL3Byb21wdC5qc1xuICoqIG1vZHVsZSBpZCA9IDg5XG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3Byb21wdC5zY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vcHJvbXB0LnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi9wcm9tcHQuc2Nzc1wiKTtcblx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdH0pO1xuXHR9XG5cdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL34vbW9kYWxzL3N0eWxlcy9wcm9tcHQuc2Nzc1xuICoqIG1vZHVsZSBpZCA9IDkwXG4gKiogbW9kdWxlIGNodW5rcyA9IDBcbiAqKi8iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiLmFtZmUtcHJvbXB0IC5pbnB1dC13cmFwIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICB3aWR0aDogMTAwJTtcXG4gIHBhZGRpbmc6IDAuMjRyZW0gMC4yMTMzMzNyZW0gMC4yMTMzMzNyZW07XFxuICBoZWlnaHQ6IDAuOTZyZW07IH1cXG4gIC5hbWZlLXByb21wdCAuaW5wdXQtd3JhcCAuaW5wdXQge1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICB3aWR0aDogMTAwJTtcXG4gICAgaGVpZ2h0OiAwLjU2cmVtO1xcbiAgICBsaW5lLWhlaWdodDogMC41NnJlbTtcXG4gICAgZm9udC1zaXplOiAwLjMycmVtOyB9XFxuXFxuLmFtZmUtcHJvbXB0IC5idG4tZ3JvdXAgLmJ0biB7XFxuICBmbG9hdDogbGVmdDtcXG4gIHdpZHRoOiA1MCU7IH1cXG4gIC5hbWZlLXByb21wdCAuYnRuLWdyb3VwIC5idG4uYnRuLW9rIHtcXG4gICAgYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgI2RkZDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9ub2RlX21vZHVsZXMvbW9kYWxzL25vZGVfbW9kdWxlcy9tb2RhbHMvc3R5bGVzL3Byb21wdC5zY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBR0ksdUJBQXVCO0VBQ3ZCLFlBQVk7RUFDWix5Q0FBeUM7RUFDekMsZ0JBQWdCLEVBU2pCO0VBZkg7SUFTTSx1QkFBdUI7SUFDdkIsWUFBWTtJQUNaLGdCQUFnQjtJQUNoQixxQkFBcUI7SUFDckIsbUJBQW1CLEVBQ3BCOztBQWRMO0VBb0JNLFlBQVk7RUFDWixXQUFXLEVBS1o7RUExQkw7SUF3QlEsNkJBQTZCLEVBQzlCXCIsXCJmaWxlXCI6XCJwcm9tcHQuc2Nzc1wiLFwic291cmNlc0NvbnRlbnRcIjpbXCIuYW1mZS1wcm9tcHQge1xcblxcbiAgLmlucHV0LXdyYXAge1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICB3aWR0aDogMTAwJTtcXG4gICAgcGFkZGluZzogMC4yNHJlbSAwLjIxMzMzM3JlbSAwLjIxMzMzM3JlbTsgLy8gMThweCAxNnB4IDE2cHhcXG4gICAgaGVpZ2h0OiAwLjk2cmVtOyAvLyA3NHB4XFxuXFxuICAgIC5pbnB1dCB7XFxuICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gICAgICB3aWR0aDogMTAwJTtcXG4gICAgICBoZWlnaHQ6IDAuNTZyZW07IC8vIDQycHhcXG4gICAgICBsaW5lLWhlaWdodDogMC41NnJlbTsgLy8gNDJweFxcbiAgICAgIGZvbnQtc2l6ZTogMC4zMnJlbTsgLy8gMjRweFxcbiAgICB9XFxuICB9XFxuXFxuICAuYnRuLWdyb3VwIHtcXG5cXG4gICAgLmJ0biB7XFxuICAgICAgZmxvYXQ6IGxlZnQ7XFxuICAgICAgd2lkdGg6IDUwJTtcXG5cXG4gICAgICAmLmJ0bi1vayB7XFxuICAgICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZGRkO1xcbiAgICAgIH1cXG4gICAgfVxcbiAgfVxcbn1cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8qKioqKioqKioqKioqKioqKlxuICoqIFdFQlBBQ0sgRk9PVEVSXG4gKiogLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9zYXNzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L21vZGFscy9zdHlsZXMvcHJvbXB0LnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA5MVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnJlcXVpcmUoJy4uL3N0eWxlcy90b2FzdC5zY3NzJylcblxudmFyIHF1ZXVlID0gW11cbnZhciB0aW1lclxudmFyIGlzUHJvY2Vzc2luZyA9IGZhbHNlXG52YXIgdG9hc3RXaW5cbnZhciBUT0FTVF9XSU5fQ0xBU1NfTkFNRSA9ICdhbWZlLXRvYXN0J1xuXG52YXIgREVGQVVMVF9EVVJBVElPTiA9IDAuOFxuXG5mdW5jdGlvbiBzaG93VG9hc3RXaW5kb3cobXNnLCBjYWxsYmFjaykge1xuICB2YXIgaGFuZGxlVHJhbnNpdGlvbkVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0b2FzdFdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgaGFuZGxlVHJhbnNpdGlvbkVuZClcbiAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpXG4gIH1cbiAgaWYgKCF0b2FzdFdpbikge1xuICAgIHRvYXN0V2luID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICB0b2FzdFdpbi5jbGFzc0xpc3QuYWRkKFRPQVNUX1dJTl9DTEFTU19OQU1FLCAnaGlkZScpXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0b2FzdFdpbilcbiAgfVxuICB0b2FzdFdpbi5pbm5lckhUTUwgPSBtc2dcbiAgdG9hc3RXaW4uYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIGhhbmRsZVRyYW5zaXRpb25FbmQpXG4gIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIHRvYXN0V2luLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKVxuICB9LCAwKVxufVxuXG5mdW5jdGlvbiBoaWRlVG9hc3RXaW5kb3coY2FsbGJhY2spIHtcbiAgdmFyIGhhbmRsZVRyYW5zaXRpb25FbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdG9hc3RXaW4ucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIGhhbmRsZVRyYW5zaXRpb25FbmQpXG4gICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICB9XG4gIGlmICghdG9hc3RXaW4pIHtcbiAgICByZXR1cm5cbiAgfVxuICB0b2FzdFdpbi5hZGRFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgaGFuZGxlVHJhbnNpdGlvbkVuZClcbiAgdG9hc3RXaW4uY2xhc3NMaXN0LmFkZCgnaGlkZScpXG59XG5cbnZhciB0b2FzdCA9IHtcblxuICBwdXNoOiBmdW5jdGlvbiAobXNnLCBkdXJhdGlvbikge1xuICAgIHF1ZXVlLnB1c2goe1xuICAgICAgbXNnOiBtc2csXG4gICAgICBkdXJhdGlvbjogZHVyYXRpb24gfHwgREVGQVVMVF9EVVJBVElPTlxuICAgIH0pXG4gICAgdGhpcy5zaG93KClcbiAgfSxcblxuICBzaG93OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzXG5cbiAgICAvLyBBbGwgbWVzc2FnZXMgaGFkIGJlZW4gdG9hc3RlZCBhbHJlYWR5LCBzbyByZW1vdmUgdGhlIHRvYXN0IHdpbmRvdyxcbiAgICBpZiAoIXF1ZXVlLmxlbmd0aCkge1xuICAgICAgdG9hc3RXaW4gJiYgdG9hc3RXaW4ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0b2FzdFdpbilcbiAgICAgIHRvYXN0V2luID0gbnVsbFxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gdGhlIHByZXZpb3VzIHRvYXN0IGlzIG5vdCBlbmRlZCB5ZXQuXG4gICAgaWYgKGlzUHJvY2Vzc2luZykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlzUHJvY2Vzc2luZyA9IHRydWVcblxuICAgIHZhciB0b2FzdEluZm8gPSBxdWV1ZS5zaGlmdCgpXG4gICAgc2hvd1RvYXN0V2luZG93KHRvYXN0SW5mby5tc2csIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRpbWVyID0gbnVsbFxuICAgICAgICBoaWRlVG9hc3RXaW5kb3coZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlzUHJvY2Vzc2luZyA9IGZhbHNlXG4gICAgICAgICAgdGhhdC5zaG93KClcbiAgICAgICAgfSlcbiAgICAgIH0sIHRvYXN0SW5mby5kdXJhdGlvbiAqIDEwMDApXG4gICAgfSlcbiAgfVxuXG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBwdXNoOiB0b2FzdC5wdXNoLmJpbmQodG9hc3QpXG59XG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3JjL3RvYXN0LmpzXG4gKiogbW9kdWxlIGlkID0gOTJcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vc2Fzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vdG9hc3Quc2Nzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL3Nhc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuL3RvYXN0LnNjc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi9zYXNzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi90b2FzdC5zY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9tb2RhbHMvc3R5bGVzL3RvYXN0LnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA5M1xuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi5hbWZlLXRvYXN0IHtcXG4gIGZvbnQtc2l6ZTogMC4zMnJlbTtcXG4gIGxpbmUtaGVpZ2h0OiAwLjQyNjY2N3JlbTtcXG4gIHBvc2l0aW9uOiBmaXhlZDtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBtYXgtd2lkdGg6IDgwJTtcXG4gIGJvdHRvbTogMi42NjY2NjdyZW07XFxuICBsZWZ0OiA1MCU7XFxuICBwYWRkaW5nOiAwLjIxMzMzM3JlbTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICMwMDA7XFxuICBjb2xvcjogI2ZmZjtcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXG4gIG9wYWNpdHk6IDAuNjtcXG4gIHRyYW5zaXRpb246IGFsbCAwLjRzIGVhc2UtaW4tb3V0O1xcbiAgYm9yZGVyLXJhZGl1czogMC4wNjY2NjdyZW07XFxuICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcXG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTsgfVxcblxcbi5hbWZlLXRvYXN0LmhpZGUge1xcbiAgb3BhY2l0eTogMDsgfVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9ub2RlX21vZHVsZXMvbW9kYWxzL25vZGVfbW9kdWxlcy9tb2RhbHMvc3R5bGVzL3RvYXN0LnNjc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7RUFDQyxtQkFBbUI7RUFDbkIseUJBQXlCO0VBQ3pCLGdCQUFnQjtFQUNoQix1QkFBdUI7RUFDdkIsZUFBZTtFQUNmLG9CQUFvQjtFQUNwQixVQUFVO0VBQ1YscUJBQXFCO0VBQ3JCLHVCQUF1QjtFQUN2QixZQUFZO0VBQ1osbUJBQW1CO0VBQ25CLGFBQWE7RUFDYixpQ0FBaUM7RUFDakMsMkJBQTJCO0VBQzNCLG9DQUE2QjtFQUM1Qiw0QkFBcUIsRUFDdEI7O0FBRUQ7RUFDQyxXQUFXLEVBQ1hcIixcImZpbGVcIjpcInRvYXN0LnNjc3NcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLmFtZmUtdG9hc3Qge1xcblxcdGZvbnQtc2l6ZTogMC4zMnJlbTsgLy8gMjRweFxcblxcdGxpbmUtaGVpZ2h0OiAwLjQyNjY2N3JlbTsgLy8gMzJweFxcblxcdHBvc2l0aW9uOiBmaXhlZDtcXG5cXHRib3gtc2l6aW5nOiBib3JkZXItYm94O1xcblxcdG1heC13aWR0aDogODAlO1xcblxcdGJvdHRvbTogMi42NjY2NjdyZW07IC8vIDIwMHB4XFxuXFx0bGVmdDogNTAlO1xcblxcdHBhZGRpbmc6IDAuMjEzMzMzcmVtOyAvLyAxNnB4XFxuXFx0YmFja2dyb3VuZC1jb2xvcjogIzAwMDtcXG5cXHRjb2xvcjogI2ZmZjtcXG5cXHR0ZXh0LWFsaWduOiBjZW50ZXI7XFxuXFx0b3BhY2l0eTogMC42O1xcblxcdHRyYW5zaXRpb246IGFsbCAwLjRzIGVhc2UtaW4tb3V0O1xcblxcdGJvcmRlci1yYWRpdXM6IDAuMDY2NjY3cmVtOyAvLyA1cHhcXG5cXHQtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcXG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcXG59XFxuXFxuLmFtZmUtdG9hc3QuaGlkZSB7XFxuXFx0b3BhY2l0eTogMDtcXG59XCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vc2Fzcy1sb2FkZXI/c291cmNlTWFwIS4vfi9tb2RhbHMvc3R5bGVzL3RvYXN0LnNjc3NcbiAqKiBtb2R1bGUgaWQgPSA5NFxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiJ3VzZSBzdHJpY3QnXG5cbnZhciBTZW5kZXIgPSByZXF1aXJlKCcuLi9icmlkZ2Uvc2VuZGVyJylcblxudmFyIF9kYXRhID0ge31cblxudmFyIGFuaW1hdGlvbiA9IHtcblxuICAvKipcbiAgICogdHJhbnNpdGlvblxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHJlZiAgICAgICAgW2Rlc2NyaXB0aW9uXVxuICAgKiBAcGFyYW0gIHtvYmp9IGNvbmZpZyAgICAgW2Rlc2NyaXB0aW9uXVxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IGNhbGxiYWNrSWQgW2Rlc2NyaXB0aW9uXVxuICAgKi9cbiAgdHJhbnNpdGlvbjogZnVuY3Rpb24gKHJlZiwgY29uZmlnLCBjYWxsYmFja0lkKSB7XG4gICAgdmFyIHJlZkRhdGEgPSBfZGF0YVtyZWZdXG4gICAgdmFyIHN0eWxlc0tleSA9IEpTT04uc3RyaW5naWZ5KGNvbmZpZy5zdHlsZXMpXG4gICAgdmFyIHdlZXhJbnN0YW5jZSA9IHRoaXNcbiAgICAvLyBJZiB0aGUgc2FtZSBjb21wb25lbnQgcGVyZm9ybSBhIGFuaW1hdGlvbiB3aXRoIGV4YWN0bHkgdGhlIHNhbWVcbiAgICAvLyBzdHlsZXMgaW4gYSBzZXF1ZW5jZSB3aXRoIHNvIHNob3J0IGludGVydmFsIHRoYXQgdGhlIHByZXYgYW5pbWF0aW9uXG4gICAgLy8gaXMgc3RpbGwgaW4gcGxheWluZywgdGhlbiB0aGUgbmV4dCBhbmltYXRpb24gc2hvdWxkIGJlIGlnbm9yZWQuXG4gICAgaWYgKHJlZkRhdGEgJiYgcmVmRGF0YVtzdHlsZXNLZXldKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCFyZWZEYXRhKSB7XG4gICAgICByZWZEYXRhID0gX2RhdGFbcmVmXSA9IHt9XG4gICAgfVxuICAgIHJlZkRhdGFbc3R5bGVzS2V5XSA9IHRydWVcbiAgICByZXR1cm4gdGhpcy5nZXRDb21wb25lbnRNYW5hZ2VyKCkudHJhbnNpdGlvbihyZWYsIGNvbmZpZywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gUmVtb3ZlIHRoZSBzdHlsZXNLZXkgaW4gcmVmRGF0YSBzbyB0aGF0IHRoZSBzYW1lIGFuaW1hdGlvblxuICAgICAgLy8gY2FuIGJlIHBsYXllZCBhZ2FpbiBhZnRlciBjdXJyZW50IGFuaW1hdGlvbiBpcyBhbHJlYWR5IGZpbmlzaGVkLlxuICAgICAgZGVsZXRlIHJlZkRhdGFbc3R5bGVzS2V5XVxuICAgICAgd2VleEluc3RhbmNlLnNlbmRlci5wZXJmb3JtQ2FsbGJhY2soY2FsbGJhY2tJZClcbiAgICB9KVxuICB9XG5cbn1cblxuYW5pbWF0aW9uLl9tZXRhID0ge1xuICBhbmltYXRpb246IFt7XG4gICAgbmFtZTogJ3RyYW5zaXRpb24nLFxuICAgIGFyZ3M6IFsnc3RyaW5nJywgJ29iamVjdCcsICdzdHJpbmcnXVxuICB9XVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFuaW1hdGlvblxuXG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3NyYy9hcGkvYW5pbWF0aW9uLmpzXG4gKiogbW9kdWxlIGlkID0gOTVcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyIsIih0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykgJiYgKHdpbmRvdyA9IHtjdHJsOiB7fSwgbGliOiB7fX0pOyF3aW5kb3cuY3RybCAmJiAod2luZG93LmN0cmwgPSB7fSk7IXdpbmRvdy5saWIgJiYgKHdpbmRvdy5saWIgPSB7fSk7IWZ1bmN0aW9uKGEsYil7ZnVuY3Rpb24gYyhhKXtPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyxcInZhbFwiLHt2YWx1ZTphLnRvU3RyaW5nKCksZW51bWVyYWJsZTohMH0pLHRoaXMuZ3Q9ZnVuY3Rpb24oYSl7cmV0dXJuIGMuY29tcGFyZSh0aGlzLGEpPjB9LHRoaXMuZ3RlPWZ1bmN0aW9uKGEpe3JldHVybiBjLmNvbXBhcmUodGhpcyxhKT49MH0sdGhpcy5sdD1mdW5jdGlvbihhKXtyZXR1cm4gYy5jb21wYXJlKHRoaXMsYSk8MH0sdGhpcy5sdGU9ZnVuY3Rpb24oYSl7cmV0dXJuIGMuY29tcGFyZSh0aGlzLGEpPD0wfSx0aGlzLmVxPWZ1bmN0aW9uKGEpe3JldHVybiAwPT09Yy5jb21wYXJlKHRoaXMsYSl9fWIuZW52PWIuZW52fHx7fSxjLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnZhbH0sYy5wcm90b3R5cGUudmFsdWVPZj1mdW5jdGlvbigpe2Zvcih2YXIgYT10aGlzLnZhbC5zcGxpdChcIi5cIiksYj1bXSxjPTA7YzxhLmxlbmd0aDtjKyspe3ZhciBkPXBhcnNlSW50KGFbY10sMTApO2lzTmFOKGQpJiYoZD0wKTt2YXIgZT1kLnRvU3RyaW5nKCk7ZS5sZW5ndGg8NSYmKGU9QXJyYXkoNi1lLmxlbmd0aCkuam9pbihcIjBcIikrZSksYi5wdXNoKGUpLDE9PT1iLmxlbmd0aCYmYi5wdXNoKFwiLlwiKX1yZXR1cm4gcGFyc2VGbG9hdChiLmpvaW4oXCJcIikpfSxjLmNvbXBhcmU9ZnVuY3Rpb24oYSxiKXthPWEudG9TdHJpbmcoKS5zcGxpdChcIi5cIiksYj1iLnRvU3RyaW5nKCkuc3BsaXQoXCIuXCIpO2Zvcih2YXIgYz0wO2M8YS5sZW5ndGh8fGM8Yi5sZW5ndGg7YysrKXt2YXIgZD1wYXJzZUludChhW2NdLDEwKSxlPXBhcnNlSW50KGJbY10sMTApO2lmKHdpbmRvdy5pc05hTihkKSYmKGQ9MCksd2luZG93LmlzTmFOKGUpJiYoZT0wKSxlPmQpcmV0dXJuLTE7aWYoZD5lKXJldHVybiAxfXJldHVybiAwfSxiLnZlcnNpb249ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBjKGEpfX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSksZnVuY3Rpb24oYSxiKXtiLmVudj1iLmVudnx8e307dmFyIGM9YS5sb2NhdGlvbi5zZWFyY2gucmVwbGFjZSgvXlxcPy8sXCJcIik7aWYoYi5lbnYucGFyYW1zPXt9LGMpZm9yKHZhciBkPWMuc3BsaXQoXCImXCIpLGU9MDtlPGQubGVuZ3RoO2UrKyl7ZFtlXT1kW2VdLnNwbGl0KFwiPVwiKTt0cnl7Yi5lbnYucGFyYW1zW2RbZV1bMF1dPWRlY29kZVVSSUNvbXBvbmVudChkW2VdWzFdKX1jYXRjaChmKXtiLmVudi5wYXJhbXNbZFtlXVswXV09ZFtlXVsxXX19fSh3aW5kb3csd2luZG93LmxpYnx8KHdpbmRvdy5saWI9e30pKSxmdW5jdGlvbihhLGIpe2IuZW52PWIuZW52fHx7fTt2YXIgYyxkPWEubmF2aWdhdG9yLnVzZXJBZ2VudDtpZihjPWQubWF0Y2goL1dpbmRvd3NcXHNQaG9uZVxccyg/Ok9TXFxzKT8oW1xcZFxcLl0rKS8pKWIuZW52Lm9zPXtuYW1lOlwiV2luZG93cyBQaG9uZVwiLGlzV2luZG93c1Bob25lOiEwLHZlcnNpb246Y1sxXX07ZWxzZSBpZihkLm1hdGNoKC9TYWZhcmkvKSYmKGM9ZC5tYXRjaCgvQW5kcm9pZFtcXHNcXC9dKFtcXGRcXC5dKykvKSkpYi5lbnYub3M9e3ZlcnNpb246Y1sxXX0sZC5tYXRjaCgvTW9iaWxlXFxzK1NhZmFyaS8pPyhiLmVudi5vcy5uYW1lPVwiQW5kcm9pZFwiLGIuZW52Lm9zLmlzQW5kcm9pZD0hMCk6KGIuZW52Lm9zLm5hbWU9XCJBbmRyb2lkUGFkXCIsYi5lbnYub3MuaXNBbmRyb2lkUGFkPSEwKTtlbHNlIGlmKGM9ZC5tYXRjaCgvKGlQaG9uZXxpUGFkfGlQb2QpLykpe3ZhciBlPWNbMV07Yz1kLm1hdGNoKC9PUyAoW1xcZF9cXC5dKykgbGlrZSBNYWMgT1MgWC8pLGIuZW52Lm9zPXtuYW1lOmUsaXNJUGhvbmU6XCJpUGhvbmVcIj09PWV8fFwiaVBvZFwiPT09ZSxpc0lQYWQ6XCJpUGFkXCI9PT1lLGlzSU9TOiEwLHZlcnNpb246Y1sxXS5zcGxpdChcIl9cIikuam9pbihcIi5cIil9fWVsc2UgYi5lbnYub3M9e25hbWU6XCJ1bmtub3duXCIsdmVyc2lvbjpcIjAuMC4wXCJ9O2IudmVyc2lvbiYmKGIuZW52Lm9zLnZlcnNpb249Yi52ZXJzaW9uKGIuZW52Lm9zLnZlcnNpb24pKX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSksZnVuY3Rpb24oYSxiKXtiLmVudj1iLmVudnx8e307dmFyIGMsZD1hLm5hdmlnYXRvci51c2VyQWdlbnQ7KGM9ZC5tYXRjaCgvKD86VUNXRUJ8VUNCcm93c2VyXFwvKShbXFxkXFwuXSspLykpP2IuZW52LmJyb3dzZXI9e25hbWU6XCJVQ1wiLGlzVUM6ITAsdmVyc2lvbjpjWzFdfTooYz1kLm1hdGNoKC9NUVFCcm93c2VyXFwvKFtcXGRcXC5dKykvKSk/Yi5lbnYuYnJvd3Nlcj17bmFtZTpcIlFRXCIsaXNRUTohMCx2ZXJzaW9uOmNbMV19OihjPWQubWF0Y2goL0ZpcmVmb3hcXC8oW1xcZFxcLl0rKS8pKT9iLmVudi5icm93c2VyPXtuYW1lOlwiRmlyZWZveFwiLGlzRmlyZWZveDohMCx2ZXJzaW9uOmNbMV19OihjPWQubWF0Y2goL01TSUVcXHMoW1xcZFxcLl0rKS8pKXx8KGM9ZC5tYXRjaCgvSUVNb2JpbGVcXC8oW1xcZFxcLl0rKS8pKT8oYi5lbnYuYnJvd3Nlcj17dmVyc2lvbjpjWzFdfSxkLm1hdGNoKC9JRU1vYmlsZS8pPyhiLmVudi5icm93c2VyLm5hbWU9XCJJRU1vYmlsZVwiLGIuZW52LmJyb3dzZXIuaXNJRU1vYmlsZT0hMCk6KGIuZW52LmJyb3dzZXIubmFtZT1cIklFXCIsYi5lbnYuYnJvd3Nlci5pc0lFPSEwKSxkLm1hdGNoKC9BbmRyb2lkfGlQaG9uZS8pJiYoYi5lbnYuYnJvd3Nlci5pc0lFTGlrZVdlYmtpdD0hMCkpOihjPWQubWF0Y2goLyg/OkNocm9tZXxDcmlPUylcXC8oW1xcZFxcLl0rKS8pKT8oYi5lbnYuYnJvd3Nlcj17bmFtZTpcIkNocm9tZVwiLGlzQ2hyb21lOiEwLHZlcnNpb246Y1sxXX0sZC5tYXRjaCgvVmVyc2lvblxcL1tcXGQrXFwuXStcXHMqQ2hyb21lLykmJihiLmVudi5icm93c2VyLm5hbWU9XCJDaHJvbWUgV2Vidmlld1wiLGIuZW52LmJyb3dzZXIuaXNXZWJ2aWV3PSEwKSk6ZC5tYXRjaCgvU2FmYXJpLykmJihjPWQubWF0Y2goL0FuZHJvaWRbXFxzXFwvXShbXFxkXFwuXSspLykpP2IuZW52LmJyb3dzZXI9e25hbWU6XCJBbmRyb2lkXCIsaXNBbmRyb2lkOiEwLHZlcnNpb246Y1sxXX06ZC5tYXRjaCgvaVBob25lfGlQYWR8aVBvZC8pP2QubWF0Y2goL1NhZmFyaS8pPyhjPWQubWF0Y2goL1ZlcnNpb25cXC8oW1xcZFxcLl0rKS8pLGIuZW52LmJyb3dzZXI9e25hbWU6XCJTYWZhcmlcIixpc1NhZmFyaTohMCx2ZXJzaW9uOmNbMV19KTooYz1kLm1hdGNoKC9PUyAoW1xcZF9cXC5dKykgbGlrZSBNYWMgT1MgWC8pLGIuZW52LmJyb3dzZXI9e25hbWU6XCJpT1MgV2Vidmlld1wiLGlzV2VidmlldzohMCx2ZXJzaW9uOmNbMV0ucmVwbGFjZSgvXFxfL2csXCIuXCIpfSk6Yi5lbnYuYnJvd3Nlcj17bmFtZTpcInVua25vd25cIix2ZXJzaW9uOlwiMC4wLjBcIn0sYi52ZXJzaW9uJiYoYi5lbnYuYnJvd3Nlci52ZXJzaW9uPWIudmVyc2lvbihiLmVudi5icm93c2VyLnZlcnNpb24pKX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSksZnVuY3Rpb24oYSxiKXtiLmVudj1iLmVudnx8e307dmFyIGM9YS5uYXZpZ2F0b3IudXNlckFnZW50O2MubWF0Y2goL1dlaWJvL2kpP2IuZW52LnRoaXJkYXBwPXthcHBuYW1lOlwiV2VpYm9cIixpc1dlaWJvOiEwfTpjLm1hdGNoKC9NaWNyb01lc3Nlbmdlci9pKT9iLmVudi50aGlyZGFwcD17YXBwbmFtZTpcIldlaXhpblwiLGlzV2VpeGluOiEwfTpiLmVudi50aGlyZGFwcD0hMX0od2luZG93LHdpbmRvdy5saWJ8fCh3aW5kb3cubGliPXt9KSksZnVuY3Rpb24oYSxiKXtiLmVudj1iLmVudnx8e307dmFyIGMsZCxlPWEubmF2aWdhdG9yLnVzZXJBZ2VudDsoZD1lLm1hdGNoKC9XaW5kVmFuZVtcXC9cXHNdKFtcXGRcXC5cXF9dKykvKSkmJihjPWRbMV0pO3ZhciBmPSExLGc9XCJcIixoPVwiXCIsaT1cIlwiOyhkPWUubWF0Y2goL0FsaUFwcFxcKChbQS1aXFwtXSspXFwvKFtcXGRcXC5dKylcXCkvaSkpJiYoZj0hMCxnPWRbMV0saT1kWzJdLGg9Zy5pbmRleE9mKFwiLVBEXCIpPjA/Yi5lbnYub3MuaXNJT1M/XCJpUGFkXCI6Yi5lbnYub3MuaXNBbmRyb2lkP1wiQW5kcm9pZFBhZFwiOmIuZW52Lm9zLm5hbWU6Yi5lbnYub3MubmFtZSksIWcmJmUuaW5kZXhPZihcIlRCSU9TXCIpPjAmJihnPVwiVEJcIiksZj9iLmVudi5hbGlhcHA9e3dpbmR2YW5lOmIudmVyc2lvbihjfHxcIjAuMC4wXCIpLGFwcG5hbWU6Z3x8XCJ1bmtvd25cIix2ZXJzaW9uOmIudmVyc2lvbihpfHxcIjAuMC4wXCIpLHBsYXRmb3JtOmh8fGIuZW52Lm9zLm5hbWV9OmIuZW52LmFsaWFwcD0hMSxiLmVudi50YW9iYW9BcHA9Yi5lbnYuYWxpYXBwfSh3aW5kb3csd2luZG93LmxpYnx8KHdpbmRvdy5saWI9e30pKTs7bW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cubGliWydlbnYnXTtcblxuXG4vKioqKioqKioqKioqKioqKipcbiAqKiBXRUJQQUNLIEZPT1RFUlxuICoqIC4vfi9lbnZkL2J1aWxkL2VudmQuY29tbW9uLmpzXG4gKiogbW9kdWxlIGlkID0gOTZcbiAqKiBtb2R1bGUgY2h1bmtzID0gMFxuICoqLyJdLCJzb3VyY2VSb290IjoiIn0=
\ No newline at end of file
diff --git a/weex-loader/test/lib/jsfm.js b/weex-loader/test/lib/jsfm.js
new file mode 100644
index 0000000..a65edda
--- /dev/null
+++ b/weex-loader/test/lib/jsfm.js
@@ -0,0 +1,7847 @@
+(this.nativeLog || function(s) {console.log(s)})('START JS FRAMEWORK: 0.13.7');
+/******/ (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__) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
+  
+  __webpack_require__(1);
+  
+  var _framework = __webpack_require__(76);
+  
+  var framework = _interopRequireWildcard(_framework);
+  
+  var _package = __webpack_require__(105);
+  
+  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+  
+  var _loop = function _loop(methodName) {
+      global[methodName] = function () {
+          var ret = framework[methodName].apply(framework, arguments);
+          if (ret instanceof Error) {
+              console.error(ret.toString());
+          } else if (ret instanceof Array) {
+              ret.forEach(function (r) {
+                  if (r instanceof Error) {
+                      console.error(r.toString());
+                  }
+              });
+          }
+          return ret;
+      };
+  };
+  
+  for (var methodName in framework) {
+      _loop(methodName);
+  }
+  
+  Object.assign(global, {
+      frameworkVersion: _package.version,
+      needTransformerVersion: _package.optionalDependencies['weex-transformer']
+  });
+  
+  /**
+   * register methods
+   */
+  var methods = __webpack_require__(106);
+  var _global = global;
+  var registerMethods = _global.registerMethods;
+  
+  registerMethods(methods);
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  __webpack_require__(2);
+  
+  __webpack_require__(40);
+  
+  __webpack_require__(74);
+  
+  __webpack_require__(75);
+
+/***/ },
+/* 2 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  __webpack_require__(3);
+
+/***/ },
+/* 3 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  __webpack_require__(4);
+  module.exports = __webpack_require__(7).Object.assign;
+
+/***/ },
+/* 4 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // 19.1.3.1 Object.assign(target, source)
+  var $export = __webpack_require__(5);
+  
+  $export($export.S + $export.F, 'Object', { assign: __webpack_require__(23) });
+
+/***/ },
+/* 5 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var global = __webpack_require__(6),
+      core = __webpack_require__(7),
+      hide = __webpack_require__(8),
+      redefine = __webpack_require__(18),
+      ctx = __webpack_require__(21),
+      PROTOTYPE = 'prototype';
+  
+  var $export = function $export(type, name, source) {
+    var IS_FORCED = type & $export.F,
+        IS_GLOBAL = type & $export.G,
+        IS_STATIC = type & $export.S,
+        IS_PROTO = type & $export.P,
+        IS_BIND = type & $export.B,
+        target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE],
+        exports = IS_GLOBAL ? core : core[name] || (core[name] = {}),
+        expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}),
+        key,
+        own,
+        out,
+        exp;
+    if (IS_GLOBAL) source = name;
+    for (key in source) {
+      // contains in native
+      own = !IS_FORCED && target && target[key] !== undefined;
+      // export native or passed
+      out = (own ? target : source)[key];
+      // bind timers to global for call from export context
+      exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
+      // extend global
+      if (target) redefine(target, key, out, type & $export.U);
+      // export
+      if (exports[key] != out) hide(exports, key, exp);
+      if (IS_PROTO && expProto[key] != out) expProto[key] = out;
+    }
+  };
+  global.core = core;
+  // type bitmap
+  $export.F = 1; // forced
+  $export.G = 2; // global
+  $export.S = 4; // static
+  $export.P = 8; // proto
+  $export.B = 16; // bind
+  $export.W = 32; // wrap
+  $export.U = 64; // safe
+  $export.R = 128; // real proto method for `library`
+  module.exports = $export;
+
+/***/ },
+/* 6 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
+  var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
+  if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
+
+/***/ },
+/* 7 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  var core = module.exports = { version: '2.1.5' };
+  if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
+
+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var dP = __webpack_require__(9),
+      createDesc = __webpack_require__(17);
+  module.exports = __webpack_require__(13) ? function (object, key, value) {
+    return dP.f(object, key, createDesc(1, value));
+  } : function (object, key, value) {
+    object[key] = value;
+    return object;
+  };
+
+/***/ },
+/* 9 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var anObject = __webpack_require__(10),
+      IE8_DOM_DEFINE = __webpack_require__(12),
+      toPrimitive = __webpack_require__(16),
+      dP = Object.defineProperty;
+  
+  exports.f = __webpack_require__(13) ? Object.defineProperty : function defineProperty(O, P, Attributes) {
+    anObject(O);
+    P = toPrimitive(P, true);
+    anObject(Attributes);
+    if (IE8_DOM_DEFINE) try {
+      return dP(O, P, Attributes);
+    } catch (e) {/* empty */}
+    if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
+    if ('value' in Attributes) O[P] = Attributes.value;
+    return O;
+  };
+
+/***/ },
+/* 10 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var isObject = __webpack_require__(11);
+  module.exports = function (it) {
+    if (!isObject(it)) throw TypeError(it + ' is not an object!');
+    return it;
+  };
+
+/***/ },
+/* 11 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
+  
+  module.exports = function (it) {
+    return (typeof it === 'undefined' ? 'undefined' : _typeof(it)) === 'object' ? it !== null : typeof it === 'function';
+  };
+
+/***/ },
+/* 12 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  module.exports = !__webpack_require__(13) && !__webpack_require__(14)(function () {
+    return Object.defineProperty(__webpack_require__(15)('div'), 'a', { get: function get() {
+        return 7;
+      } }).a != 7;
+  });
+
+/***/ },
+/* 13 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // Thank's IE8 for his funny defineProperty
+  module.exports = !__webpack_require__(14)(function () {
+    return Object.defineProperty({}, 'a', { get: function get() {
+        return 7;
+      } }).a != 7;
+  });
+
+/***/ },
+/* 14 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  module.exports = function (exec) {
+    try {
+      return !!exec();
+    } catch (e) {
+      return true;
+    }
+  };
+
+/***/ },
+/* 15 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var isObject = __webpack_require__(11),
+      document = __webpack_require__(6).document
+  // in old IE typeof document.createElement is 'object'
+  ,
+      is = isObject(document) && isObject(document.createElement);
+  module.exports = function (it) {
+    return is ? document.createElement(it) : {};
+  };
+
+/***/ },
+/* 16 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // 7.1.1 ToPrimitive(input [, PreferredType])
+  var isObject = __webpack_require__(11);
+  // instead of the ES6 spec version, we didn't implement @@toPrimitive case
+  // and the second argument - flag - preferred type is a string
+  module.exports = function (it, S) {
+    if (!isObject(it)) return it;
+    var fn, val;
+    if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
+    if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;
+    if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
+    throw TypeError("Can't convert object to primitive value");
+  };
+
+/***/ },
+/* 17 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  module.exports = function (bitmap, value) {
+    return {
+      enumerable: !(bitmap & 1),
+      configurable: !(bitmap & 2),
+      writable: !(bitmap & 4),
+      value: value
+    };
+  };
+
+/***/ },
+/* 18 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var global = __webpack_require__(6),
+      hide = __webpack_require__(8),
+      has = __webpack_require__(19),
+      SRC = __webpack_require__(20)('src'),
+      TO_STRING = 'toString',
+      $toString = Function[TO_STRING],
+      TPL = ('' + $toString).split(TO_STRING);
+  
+  __webpack_require__(7).inspectSource = function (it) {
+    return $toString.call(it);
+  };
+  
+  (module.exports = function (O, key, val, safe) {
+    var isFunction = typeof val == 'function';
+    if (isFunction) has(val, 'name') || hide(val, 'name', key);
+    if (O[key] === val) return;
+    if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
+    if (O === global) {
+      O[key] = val;
+    } else {
+      if (!safe) {
+        delete O[key];
+        hide(O, key, val);
+      } else {
+        if (O[key]) O[key] = val;else hide(O, key, val);
+      }
+    }
+    // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
+  })(Function.prototype, TO_STRING, function toString() {
+    return typeof this == 'function' && this[SRC] || $toString.call(this);
+  });
+
+/***/ },
+/* 19 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  var hasOwnProperty = {}.hasOwnProperty;
+  module.exports = function (it, key) {
+    return hasOwnProperty.call(it, key);
+  };
+
+/***/ },
+/* 20 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  var id = 0,
+      px = Math.random();
+  module.exports = function (key) {
+    return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
+  };
+
+/***/ },
+/* 21 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // optional / simple context binding
+  var aFunction = __webpack_require__(22);
+  module.exports = function (fn, that, length) {
+    aFunction(fn);
+    if (that === undefined) return fn;
+    switch (length) {
+      case 1:
+        return function (a) {
+          return fn.call(that, a);
+        };
+      case 2:
+        return function (a, b) {
+          return fn.call(that, a, b);
+        };
+      case 3:
+        return function (a, b, c) {
+          return fn.call(that, a, b, c);
+        };
+    }
+    return function () /* ...args */{
+      return fn.apply(that, arguments);
+    };
+  };
+
+/***/ },
+/* 22 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  module.exports = function (it) {
+    if (typeof it != 'function') throw TypeError(it + ' is not a function!');
+    return it;
+  };
+
+/***/ },
+/* 23 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  // 19.1.2.1 Object.assign(target, source, ...)
+  
+  var getKeys = __webpack_require__(24),
+      gOPS = __webpack_require__(37),
+      pIE = __webpack_require__(38),
+      toObject = __webpack_require__(39),
+      IObject = __webpack_require__(27),
+      $assign = Object.assign;
+  
+  // should work with symbols and should have deterministic property order (V8 bug)
+  module.exports = !$assign || __webpack_require__(14)(function () {
+    var A = {},
+        B = {},
+        S = Symbol(),
+        K = 'abcdefghijklmnopqrst';
+    A[S] = 7;
+    K.split('').forEach(function (k) {
+      B[k] = k;
+    });
+    return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
+  }) ? function assign(target, source) {
+    // eslint-disable-line no-unused-vars
+    var T = toObject(target),
+        aLen = arguments.length,
+        index = 1,
+        getSymbols = gOPS.f,
+        isEnum = pIE.f;
+    while (aLen > index) {
+      var S = IObject(arguments[index++]),
+          keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S),
+          length = keys.length,
+          j = 0,
+          key;
+      while (length > j) {
+        if (isEnum.call(S, key = keys[j++])) T[key] = S[key];
+      }
+    }return T;
+  } : $assign;
+
+/***/ },
+/* 24 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // 19.1.2.14 / 15.2.3.14 Object.keys(O)
+  var $keys = __webpack_require__(25),
+      enumBugKeys = __webpack_require__(36);
+  
+  module.exports = Object.keys || function keys(O) {
+    return $keys(O, enumBugKeys);
+  };
+
+/***/ },
+/* 25 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var has = __webpack_require__(19),
+      toIObject = __webpack_require__(26),
+      arrayIndexOf = __webpack_require__(30)(false),
+      IE_PROTO = __webpack_require__(34)('IE_PROTO');
+  
+  module.exports = function (object, names) {
+    var O = toIObject(object),
+        i = 0,
+        result = [],
+        key;
+    for (key in O) {
+      if (key != IE_PROTO) has(O, key) && result.push(key);
+    } // Don't enum bug & hidden keys
+    while (names.length > i) {
+      if (has(O, key = names[i++])) {
+        ~arrayIndexOf(result, key) || result.push(key);
+      }
+    }return result;
+  };
+
+/***/ },
+/* 26 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // to indexed object, toObject with fallback for non-array-like ES3 strings
+  var IObject = __webpack_require__(27),
+      defined = __webpack_require__(29);
+  module.exports = function (it) {
+    return IObject(defined(it));
+  };
+
+/***/ },
+/* 27 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // fallback for non-array-like ES3 and non-enumerable old V8 strings
+  var cof = __webpack_require__(28);
+  module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
+    return cof(it) == 'String' ? it.split('') : Object(it);
+  };
+
+/***/ },
+/* 28 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  var toString = {}.toString;
+  
+  module.exports = function (it) {
+    return toString.call(it).slice(8, -1);
+  };
+
+/***/ },
+/* 29 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  // 7.2.1 RequireObjectCoercible(argument)
+  module.exports = function (it) {
+    if (it == undefined) throw TypeError("Can't call method on  " + it);
+    return it;
+  };
+
+/***/ },
+/* 30 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // false -> Array#indexOf
+  // true  -> Array#includes
+  var toIObject = __webpack_require__(26),
+      toLength = __webpack_require__(31),
+      toIndex = __webpack_require__(33);
+  module.exports = function (IS_INCLUDES) {
+    return function ($this, el, fromIndex) {
+      var O = toIObject($this),
+          length = toLength(O.length),
+          index = toIndex(fromIndex, length),
+          value;
+      // Array#includes uses SameValueZero equality algorithm
+      if (IS_INCLUDES && el != el) while (length > index) {
+        value = O[index++];
+        if (value != value) return true;
+        // Array#toIndex ignores holes, Array#includes - not
+      } else for (; length > index; index++) {
+          if (IS_INCLUDES || index in O) {
+            if (O[index] === el) return IS_INCLUDES || index;
+          }
+        }return !IS_INCLUDES && -1;
+    };
+  };
+
+/***/ },
+/* 31 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // 7.1.15 ToLength
+  var toInteger = __webpack_require__(32),
+      min = Math.min;
+  module.exports = function (it) {
+    return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
+  };
+
+/***/ },
+/* 32 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  // 7.1.4 ToInteger
+  var ceil = Math.ceil,
+      floor = Math.floor;
+  module.exports = function (it) {
+    return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
+  };
+
+/***/ },
+/* 33 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var toInteger = __webpack_require__(32),
+      max = Math.max,
+      min = Math.min;
+  module.exports = function (index, length) {
+    index = toInteger(index);
+    return index < 0 ? max(index + length, 0) : min(index, length);
+  };
+
+/***/ },
+/* 34 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var shared = __webpack_require__(35)('keys'),
+      uid = __webpack_require__(20);
+  module.exports = function (key) {
+    return shared[key] || (shared[key] = uid(key));
+  };
+
+/***/ },
+/* 35 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var global = __webpack_require__(6),
+      SHARED = '__core-js_shared__',
+      store = global[SHARED] || (global[SHARED] = {});
+  module.exports = function (key) {
+    return store[key] || (store[key] = {});
+  };
+
+/***/ },
+/* 36 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  // IE 8- don't enum bug keys
+  module.exports = 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'.split(',');
+
+/***/ },
+/* 37 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  exports.f = Object.getOwnPropertySymbols;
+
+/***/ },
+/* 38 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  exports.f = {}.propertyIsEnumerable;
+
+/***/ },
+/* 39 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // 7.1.13 ToObject(argument)
+  var defined = __webpack_require__(29);
+  module.exports = function (it) {
+    return Object(defined(it));
+  };
+
+/***/ },
+/* 40 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
+  
+  // fix Promise Problem on JSContext of iOS7~8
+  // @see https://bugs.webkit.org/show_bug.cgi?id=135866
+  global.Promise = null;
+  __webpack_require__(41);
+  __webpack_require__(44);
+  __webpack_require__(55);
+  __webpack_require__(59);
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 41 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  // 19.1.3.6 Object.prototype.toString()
+  
+  var classof = __webpack_require__(42),
+      test = {};
+  test[__webpack_require__(43)('toStringTag')] = 'z';
+  if (test + '' != '[object z]') {
+    __webpack_require__(18)(Object.prototype, 'toString', function toString() {
+      return '[object ' + classof(this) + ']';
+    }, true);
+  }
+
+/***/ },
+/* 42 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // getting tag from 19.1.3.6 Object.prototype.toString()
+  var cof = __webpack_require__(28),
+      TAG = __webpack_require__(43)('toStringTag')
+  // ES3 wrong here
+  ,
+      ARG = cof(function () {
+    return arguments;
+  }()) == 'Arguments';
+  
+  // fallback for IE11 Script Access Denied error
+  var tryGet = function tryGet(it, key) {
+    try {
+      return it[key];
+    } catch (e) {/* empty */}
+  };
+  
+  module.exports = function (it) {
+    var O, T, B;
+    return it === undefined ? 'Undefined' : it === null ? 'Null'
+    // @@toStringTag case
+    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
+    // builtinTag case
+    : ARG ? cof(O)
+    // ES3 arguments fallback
+    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
+  };
+
+/***/ },
+/* 43 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var store = __webpack_require__(35)('wks'),
+      uid = __webpack_require__(20),
+      _Symbol = __webpack_require__(6).Symbol,
+      USE_SYMBOL = typeof _Symbol == 'function';
+  module.exports = function (name) {
+    return store[name] || (store[name] = USE_SYMBOL && _Symbol[name] || (USE_SYMBOL ? _Symbol : uid)('Symbol.' + name));
+  };
+
+/***/ },
+/* 44 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var $at = __webpack_require__(45)(true);
+  
+  // 21.1.3.27 String.prototype[@@iterator]()
+  __webpack_require__(46)(String, 'String', function (iterated) {
+    this._t = String(iterated); // target
+    this._i = 0; // next index
+    // 21.1.5.2.1 %StringIteratorPrototype%.next()
+  }, function () {
+    var O = this._t,
+        index = this._i,
+        point;
+    if (index >= O.length) return { value: undefined, done: true };
+    point = $at(O, index);
+    this._i += point.length;
+    return { value: point, done: false };
+  });
+
+/***/ },
+/* 45 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var toInteger = __webpack_require__(32),
+      defined = __webpack_require__(29);
+  // true  -> String#at
+  // false -> String#codePointAt
+  module.exports = function (TO_STRING) {
+    return function (that, pos) {
+      var s = String(defined(that)),
+          i = toInteger(pos),
+          l = s.length,
+          a,
+          b;
+      if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
+      a = s.charCodeAt(i);
+      return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
+    };
+  };
+
+/***/ },
+/* 46 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var LIBRARY = __webpack_require__(47),
+      $export = __webpack_require__(5),
+      redefine = __webpack_require__(18),
+      hide = __webpack_require__(8),
+      has = __webpack_require__(19),
+      Iterators = __webpack_require__(48),
+      $iterCreate = __webpack_require__(49),
+      setToStringTag = __webpack_require__(53),
+      getPrototypeOf = __webpack_require__(54),
+      ITERATOR = __webpack_require__(43)('iterator'),
+      BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`
+  ,
+      FF_ITERATOR = '@@iterator',
+      KEYS = 'keys',
+      VALUES = 'values';
+  
+  var returnThis = function returnThis() {
+    return this;
+  };
+  
+  module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
+    $iterCreate(Constructor, NAME, next);
+    var getMethod = function getMethod(kind) {
+      if (!BUGGY && kind in proto) return proto[kind];
+      switch (kind) {
+        case KEYS:
+          return function keys() {
+            return new Constructor(this, kind);
+          };
+        case VALUES:
+          return function values() {
+            return new Constructor(this, kind);
+          };
+      }return function entries() {
+        return new Constructor(this, kind);
+      };
+    };
+    var TAG = NAME + ' Iterator',
+        DEF_VALUES = DEFAULT == VALUES,
+        VALUES_BUG = false,
+        proto = Base.prototype,
+        $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT],
+        $default = $native || getMethod(DEFAULT),
+        $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined,
+        $anyNative = NAME == 'Array' ? proto.entries || $native : $native,
+        methods,
+        key,
+        IteratorPrototype;
+    // Fix native
+    if ($anyNative) {
+      IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));
+      if (IteratorPrototype !== Object.prototype) {
+        // Set @@toStringTag to native iterators
+        setToStringTag(IteratorPrototype, TAG, true);
+        // fix for some old engines
+        if (!LIBRARY && !has(IteratorPrototype, ITERATOR)) hide(IteratorPrototype, ITERATOR, returnThis);
+      }
+    }
+    // fix Array#{values, @@iterator}.name in V8 / FF
+    if (DEF_VALUES && $native && $native.name !== VALUES) {
+      VALUES_BUG = true;
+      $default = function values() {
+        return $native.call(this);
+      };
+    }
+    // Define iterator
+    if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
+      hide(proto, ITERATOR, $default);
+    }
+    // Plug for library
+    Iterators[NAME] = $default;
+    Iterators[TAG] = returnThis;
+    if (DEFAULT) {
+      methods = {
+        values: DEF_VALUES ? $default : getMethod(VALUES),
+        keys: IS_SET ? $default : getMethod(KEYS),
+        entries: $entries
+      };
+      if (FORCED) for (key in methods) {
+        if (!(key in proto)) redefine(proto, key, methods[key]);
+      } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
+    }
+    return methods;
+  };
+
+/***/ },
+/* 47 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  module.exports = false;
+
+/***/ },
+/* 48 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  module.exports = {};
+
+/***/ },
+/* 49 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var create = __webpack_require__(50),
+      descriptor = __webpack_require__(17),
+      setToStringTag = __webpack_require__(53),
+      IteratorPrototype = {};
+  
+  // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
+  __webpack_require__(8)(IteratorPrototype, __webpack_require__(43)('iterator'), function () {
+    return this;
+  });
+  
+  module.exports = function (Constructor, NAME, next) {
+    Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });
+    setToStringTag(Constructor, NAME + ' Iterator');
+  };
+
+/***/ },
+/* 50 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
+  var anObject = __webpack_require__(10),
+      dPs = __webpack_require__(51),
+      enumBugKeys = __webpack_require__(36),
+      IE_PROTO = __webpack_require__(34)('IE_PROTO'),
+      Empty = function Empty() {/* empty */},
+      PROTOTYPE = 'prototype';
+  
+  // Create object with fake `null` prototype: use iframe Object with cleared prototype
+  var _createDict = function createDict() {
+    // Thrash, waste and sodomy: IE GC bug
+    var iframe = __webpack_require__(15)('iframe'),
+        i = enumBugKeys.length,
+        gt = '>',
+        iframeDocument;
+    iframe.style.display = 'none';
+    __webpack_require__(52).appendChild(iframe);
+    iframe.src = 'javascript:'; // eslint-disable-line no-script-url
+    // createDict = iframe.contentWindow.Object;
+    // html.removeChild(iframe);
+    iframeDocument = iframe.contentWindow.document;
+    iframeDocument.open();
+    iframeDocument.write('<script>document.F=Object</script' + gt);
+    iframeDocument.close();
+    _createDict = iframeDocument.F;
+    while (i--) {
+      delete _createDict[PROTOTYPE][enumBugKeys[i]];
+    }return _createDict();
+  };
+  
+  module.exports = Object.create || function create(O, Properties) {
+    var result;
+    if (O !== null) {
+      Empty[PROTOTYPE] = anObject(O);
+      result = new Empty();
+      Empty[PROTOTYPE] = null;
+      // add "__proto__" for Object.getPrototypeOf polyfill
+      result[IE_PROTO] = O;
+    } else result = _createDict();
+    return Properties === undefined ? result : dPs(result, Properties);
+  };
+
+/***/ },
+/* 51 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var dP = __webpack_require__(9),
+      anObject = __webpack_require__(10),
+      getKeys = __webpack_require__(24);
+  
+  module.exports = __webpack_require__(13) ? Object.defineProperties : function defineProperties(O, Properties) {
+    anObject(O);
+    var keys = getKeys(Properties),
+        length = keys.length,
+        i = 0,
+        P;
+    while (length > i) {
+      dP.f(O, P = keys[i++], Properties[P]);
+    }return O;
+  };
+
+/***/ },
+/* 52 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  module.exports = __webpack_require__(6).document && document.documentElement;
+
+/***/ },
+/* 53 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var def = __webpack_require__(9).f,
+      has = __webpack_require__(19),
+      TAG = __webpack_require__(43)('toStringTag');
+  
+  module.exports = function (it, tag, stat) {
+    if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });
+  };
+
+/***/ },
+/* 54 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
+  var has = __webpack_require__(19),
+      toObject = __webpack_require__(39),
+      IE_PROTO = __webpack_require__(34)('IE_PROTO'),
+      ObjectProto = Object.prototype;
+  
+  module.exports = Object.getPrototypeOf || function (O) {
+    O = toObject(O);
+    if (has(O, IE_PROTO)) return O[IE_PROTO];
+    if (typeof O.constructor == 'function' && O instanceof O.constructor) {
+      return O.constructor.prototype;
+    }return O instanceof Object ? ObjectProto : null;
+  };
+
+/***/ },
+/* 55 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var $iterators = __webpack_require__(56),
+      redefine = __webpack_require__(18),
+      global = __webpack_require__(6),
+      hide = __webpack_require__(8),
+      Iterators = __webpack_require__(48),
+      wks = __webpack_require__(43),
+      ITERATOR = wks('iterator'),
+      TO_STRING_TAG = wks('toStringTag'),
+      ArrayValues = Iterators.Array;
+  
+  for (var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++) {
+    var NAME = collections[i],
+        Collection = global[NAME],
+        proto = Collection && Collection.prototype,
+        key;
+    if (proto) {
+      if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);
+      if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);
+      Iterators[NAME] = ArrayValues;
+      for (key in $iterators) {
+        if (!proto[key]) redefine(proto, key, $iterators[key], true);
+      }
+    }
+  }
+
+/***/ },
+/* 56 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var addToUnscopables = __webpack_require__(57),
+      step = __webpack_require__(58),
+      Iterators = __webpack_require__(48),
+      toIObject = __webpack_require__(26);
+  
+  // 22.1.3.4 Array.prototype.entries()
+  // 22.1.3.13 Array.prototype.keys()
+  // 22.1.3.29 Array.prototype.values()
+  // 22.1.3.30 Array.prototype[@@iterator]()
+  module.exports = __webpack_require__(46)(Array, 'Array', function (iterated, kind) {
+    this._t = toIObject(iterated); // target
+    this._i = 0; // next index
+    this._k = kind; // kind
+    // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
+  }, function () {
+    var O = this._t,
+        kind = this._k,
+        index = this._i++;
+    if (!O || index >= O.length) {
+      this._t = undefined;
+      return step(1);
+    }
+    if (kind == 'keys') return step(0, index);
+    if (kind == 'values') return step(0, O[index]);
+    return step(0, [index, O[index]]);
+  }, 'values');
+  
+  // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
+  Iterators.Arguments = Iterators.Array;
+  
+  addToUnscopables('keys');
+  addToUnscopables('values');
+  addToUnscopables('entries');
+
+/***/ },
+/* 57 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // 22.1.3.31 Array.prototype[@@unscopables]
+  var UNSCOPABLES = __webpack_require__(43)('unscopables'),
+      ArrayProto = Array.prototype;
+  if (ArrayProto[UNSCOPABLES] == undefined) __webpack_require__(8)(ArrayProto, UNSCOPABLES, {});
+  module.exports = function (key) {
+    ArrayProto[UNSCOPABLES][key] = true;
+  };
+
+/***/ },
+/* 58 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  module.exports = function (done, value) {
+    return { value: value, done: !!done };
+  };
+
+/***/ },
+/* 59 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var LIBRARY = __webpack_require__(47),
+      global = __webpack_require__(6),
+      ctx = __webpack_require__(21),
+      classof = __webpack_require__(42),
+      $export = __webpack_require__(5),
+      isObject = __webpack_require__(11),
+      anObject = __webpack_require__(10),
+      aFunction = __webpack_require__(22),
+      anInstance = __webpack_require__(60),
+      forOf = __webpack_require__(61),
+      setProto = __webpack_require__(65).set,
+      speciesConstructor = __webpack_require__(67),
+      task = __webpack_require__(68).set,
+      microtask = __webpack_require__(70),
+      PROMISE = 'Promise',
+      TypeError = global.TypeError,
+      process = global.process,
+      $Promise = global[PROMISE],
+      process = global.process,
+      isNode = classof(process) == 'process',
+      empty = function empty() {/* empty */},
+      Internal,
+      GenericPromiseCapability,
+      Wrapper;
+  
+  var USE_NATIVE = !!function () {
+    try {
+      // correct subclassing with @@species support
+      var promise = $Promise.resolve(1),
+          FakePromise = (promise.constructor = {})[__webpack_require__(43)('species')] = function (exec) {
+        exec(empty, empty);
+      };
+      // unhandled rejections tracking support, NodeJS Promise without it fails @@species test
+      return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
+    } catch (e) {/* empty */}
+  }();
+  
+  // helpers
+  var sameConstructor = function sameConstructor(a, b) {
+    // with library wrapper special case
+    return a === b || a === $Promise && b === Wrapper;
+  };
+  var isThenable = function isThenable(it) {
+    var then;
+    return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
+  };
+  var newPromiseCapability = function newPromiseCapability(C) {
+    return sameConstructor($Promise, C) ? new PromiseCapability(C) : new GenericPromiseCapability(C);
+  };
+  var PromiseCapability = GenericPromiseCapability = function GenericPromiseCapability(C) {
+    var resolve, reject;
+    this.promise = new C(function ($$resolve, $$reject) {
+      if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
+      resolve = $$resolve;
+      reject = $$reject;
+    });
+    this.resolve = aFunction(resolve);
+    this.reject = aFunction(reject);
+  };
+  var perform = function perform(exec) {
+    try {
+      exec();
+    } catch (e) {
+      return { error: e };
+    }
+  };
+  var notify = function notify(promise, isReject) {
+    if (promise._n) return;
+    promise._n = true;
+    var chain = promise._c;
+    microtask(function () {
+      var value = promise._v,
+          ok = promise._s == 1,
+          i = 0;
+      var run = function run(reaction) {
+        var handler = ok ? reaction.ok : reaction.fail,
+            resolve = reaction.resolve,
+            reject = reaction.reject,
+            domain = reaction.domain,
+            result,
+            then;
+        try {
+          if (handler) {
+            if (!ok) {
+              if (promise._h == 2) onHandleUnhandled(promise);
+              promise._h = 1;
+            }
+            if (handler === true) result = value;else {
+              if (domain) domain.enter();
+              result = handler(value);
+              if (domain) domain.exit();
+            }
+            if (result === reaction.promise) {
+              reject(TypeError('Promise-chain cycle'));
+            } else if (then = isThenable(result)) {
+              then.call(result, resolve, reject);
+            } else resolve(result);
+          } else reject(value);
+        } catch (e) {
+          reject(e);
+        }
+      };
+      while (chain.length > i) {
+        run(chain[i++]);
+      } // variable length - can't use forEach
+      promise._c = [];
+      promise._n = false;
+      if (isReject && !promise._h) onUnhandled(promise);
+    });
+  };
+  var onUnhandled = function onUnhandled(promise) {
+    task.call(global, function () {
+      var value = promise._v,
+          abrupt,
+          handler,
+          console;
+      if (isUnhandled(promise)) {
+        abrupt = perform(function () {
+          if (isNode) {
+            process.emit('unhandledRejection', value, promise);
+          } else if (handler = global.onunhandledrejection) {
+            handler({ promise: promise, reason: value });
+          } else if ((console = global.console) && console.error) {
+            console.error('Unhandled promise rejection', value);
+          }
+        });
+        // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
+        promise._h = isNode || isUnhandled(promise) ? 2 : 1;
+      }promise._a = undefined;
+      if (abrupt) throw abrupt.error;
+    });
+  };
+  var isUnhandled = function isUnhandled(promise) {
+    if (promise._h == 1) return false;
+    var chain = promise._a || promise._c,
+        i = 0,
+        reaction;
+    while (chain.length > i) {
+      reaction = chain[i++];
+      if (reaction.fail || !isUnhandled(reaction.promise)) return false;
+    }return true;
+  };
+  var onHandleUnhandled = function onHandleUnhandled(promise) {
+    task.call(global, function () {
+      var handler;
+      if (isNode) {
+        process.emit('rejectionHandled', promise);
+      } else if (handler = global.onrejectionhandled) {
+        handler({ promise: promise, reason: promise._v });
+      }
+    });
+  };
+  var $reject = function $reject(value) {
+    var promise = this;
+    if (promise._d) return;
+    promise._d = true;
+    promise = promise._w || promise; // unwrap
+    promise._v = value;
+    promise._s = 2;
+    if (!promise._a) promise._a = promise._c.slice();
+    notify(promise, true);
+  };
+  var $resolve = function $resolve(value) {
+    var promise = this,
+        then;
+    if (promise._d) return;
+    promise._d = true;
+    promise = promise._w || promise; // unwrap
+    try {
+      if (promise === value) throw TypeError("Promise can't be resolved itself");
+      if (then = isThenable(value)) {
+        microtask(function () {
+          var wrapper = { _w: promise, _d: false }; // wrap
+          try {
+            then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
+          } catch (e) {
+            $reject.call(wrapper, e);
+          }
+        });
+      } else {
+        promise._v = value;
+        promise._s = 1;
+        notify(promise, false);
+      }
+    } catch (e) {
+      $reject.call({ _w: promise, _d: false }, e); // wrap
+    }
+  };
+  
+  // constructor polyfill
+  if (!USE_NATIVE) {
+    // 25.4.3.1 Promise(executor)
+    $Promise = function Promise(executor) {
+      anInstance(this, $Promise, PROMISE, '_h');
+      aFunction(executor);
+      Internal.call(this);
+      try {
+        executor(ctx($resolve, this, 1), ctx($reject, this, 1));
+      } catch (err) {
+        $reject.call(this, err);
+      }
+    };
+    Internal = function Promise(executor) {
+      this._c = []; // <- awaiting reactions
+      this._a = undefined; // <- checked in isUnhandled reactions
+      this._s = 0; // <- state
+      this._d = false; // <- done
+      this._v = undefined; // <- value
+      this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
+      this._n = false; // <- notify
+    };
+    Internal.prototype = __webpack_require__(71)($Promise.prototype, {
+      // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
+      then: function then(onFulfilled, onRejected) {
+        var reaction = newPromiseCapability(speciesConstructor(this, $Promise));
+        reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
+        reaction.fail = typeof onRejected == 'function' && onRejected;
+        reaction.domain = isNode ? process.domain : undefined;
+        this._c.push(reaction);
+        if (this._a) this._a.push(reaction);
+        if (this._s) notify(this, false);
+        return reaction.promise;
+      },
+      // 25.4.5.1 Promise.prototype.catch(onRejected)
+      'catch': function _catch(onRejected) {
+        return this.then(undefined, onRejected);
+      }
+    });
+    PromiseCapability = function PromiseCapability() {
+      var promise = new Internal();
+      this.promise = promise;
+      this.resolve = ctx($resolve, promise, 1);
+      this.reject = ctx($reject, promise, 1);
+    };
+  }
+  
+  $export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });
+  __webpack_require__(53)($Promise, PROMISE);
+  __webpack_require__(72)(PROMISE);
+  Wrapper = __webpack_require__(7)[PROMISE];
+  
+  // statics
+  $export($export.S + $export.F * !USE_NATIVE, PROMISE, {
+    // 25.4.4.5 Promise.reject(r)
+    reject: function reject(r) {
+      var capability = newPromiseCapability(this),
+          $$reject = capability.reject;
+      $$reject(r);
+      return capability.promise;
+    }
+  });
+  $export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {
+    // 25.4.4.6 Promise.resolve(x)
+    resolve: function resolve(x) {
+      // instanceof instead of internal slot check because we should fix it without replacement native Promise core
+      if (x instanceof $Promise && sameConstructor(x.constructor, this)) return x;
+      var capability = newPromiseCapability(this),
+          $$resolve = capability.resolve;
+      $$resolve(x);
+      return capability.promise;
+    }
+  });
+  $export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(73)(function (iter) {
+    $Promise.all(iter)['catch'](empty);
+  })), PROMISE, {
+    // 25.4.4.1 Promise.all(iterable)
+    all: function all(iterable) {
+      var C = this,
+          capability = newPromiseCapability(C),
+          resolve = capability.resolve,
+          reject = capability.reject;
+      var abrupt = perform(function () {
+        var values = [],
+            index = 0,
+            remaining = 1;
+        forOf(iterable, false, function (promise) {
+          var $index = index++,
+              alreadyCalled = false;
+          values.push(undefined);
+          remaining++;
+          C.resolve(promise).then(function (value) {
+            if (alreadyCalled) return;
+            alreadyCalled = true;
+            values[$index] = value;
+            --remaining || resolve(values);
+          }, reject);
+        });
+        --remaining || resolve(values);
+      });
+      if (abrupt) reject(abrupt.error);
+      return capability.promise;
+    },
+    // 25.4.4.4 Promise.race(iterable)
+    race: function race(iterable) {
+      var C = this,
+          capability = newPromiseCapability(C),
+          reject = capability.reject;
+      var abrupt = perform(function () {
+        forOf(iterable, false, function (promise) {
+          C.resolve(promise).then(capability.resolve, reject);
+        });
+      });
+      if (abrupt) reject(abrupt.error);
+      return capability.promise;
+    }
+  });
+
+/***/ },
+/* 60 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  module.exports = function (it, Constructor, name, forbiddenField) {
+    if (!(it instanceof Constructor) || forbiddenField !== undefined && forbiddenField in it) {
+      throw TypeError(name + ': incorrect invocation!');
+    }return it;
+  };
+
+/***/ },
+/* 61 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var ctx = __webpack_require__(21),
+      call = __webpack_require__(62),
+      isArrayIter = __webpack_require__(63),
+      anObject = __webpack_require__(10),
+      toLength = __webpack_require__(31),
+      getIterFn = __webpack_require__(64);
+  module.exports = function (iterable, entries, fn, that, ITERATOR) {
+    var iterFn = ITERATOR ? function () {
+      return iterable;
+    } : getIterFn(iterable),
+        f = ctx(fn, that, entries ? 2 : 1),
+        index = 0,
+        length,
+        step,
+        iterator;
+    if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');
+    // fast case for arrays with default iterator
+    if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {
+      entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
+    } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {
+      call(iterator, f, step.value, entries);
+    }
+  };
+
+/***/ },
+/* 62 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // call something on iterator step with safe closing on error
+  var anObject = __webpack_require__(10);
+  module.exports = function (iterator, fn, value, entries) {
+    try {
+      return entries ? fn(anObject(value)[0], value[1]) : fn(value);
+      // 7.4.6 IteratorClose(iterator, completion)
+    } catch (e) {
+      var ret = iterator['return'];
+      if (ret !== undefined) anObject(ret.call(iterator));
+      throw e;
+    }
+  };
+
+/***/ },
+/* 63 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // check on default Array iterator
+  var Iterators = __webpack_require__(48),
+      ITERATOR = __webpack_require__(43)('iterator'),
+      ArrayProto = Array.prototype;
+  
+  module.exports = function (it) {
+    return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
+  };
+
+/***/ },
+/* 64 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var classof = __webpack_require__(42),
+      ITERATOR = __webpack_require__(43)('iterator'),
+      Iterators = __webpack_require__(48);
+  module.exports = __webpack_require__(7).getIteratorMethod = function (it) {
+    if (it != undefined) return it[ITERATOR] || it['@@iterator'] || Iterators[classof(it)];
+  };
+
+/***/ },
+/* 65 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // Works with __proto__ only. Old v8 can't work with null proto objects.
+  /* eslint-disable no-proto */
+  var isObject = __webpack_require__(11),
+      anObject = __webpack_require__(10);
+  var check = function check(O, proto) {
+    anObject(O);
+    if (!isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
+  };
+  module.exports = {
+    set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
+    function (test, buggy, set) {
+      try {
+        set = __webpack_require__(21)(Function.call, __webpack_require__(66).f(Object.prototype, '__proto__').set, 2);
+        set(test, []);
+        buggy = !(test instanceof Array);
+      } catch (e) {
+        buggy = true;
+      }
+      return function setPrototypeOf(O, proto) {
+        check(O, proto);
+        if (buggy) O.__proto__ = proto;else set(O, proto);
+        return O;
+      };
+    }({}, false) : undefined),
+    check: check
+  };
+
+/***/ },
+/* 66 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var pIE = __webpack_require__(38),
+      createDesc = __webpack_require__(17),
+      toIObject = __webpack_require__(26),
+      toPrimitive = __webpack_require__(16),
+      has = __webpack_require__(19),
+      IE8_DOM_DEFINE = __webpack_require__(12),
+      gOPD = Object.getOwnPropertyDescriptor;
+  
+  exports.f = __webpack_require__(13) ? gOPD : function getOwnPropertyDescriptor(O, P) {
+    O = toIObject(O);
+    P = toPrimitive(P, true);
+    if (IE8_DOM_DEFINE) try {
+      return gOPD(O, P);
+    } catch (e) {/* empty */}
+    if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);
+  };
+
+/***/ },
+/* 67 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // 7.3.20 SpeciesConstructor(O, defaultConstructor)
+  var anObject = __webpack_require__(10),
+      aFunction = __webpack_require__(22),
+      SPECIES = __webpack_require__(43)('species');
+  module.exports = function (O, D) {
+    var C = anObject(O).constructor,
+        S;
+    return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
+  };
+
+/***/ },
+/* 68 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var ctx = __webpack_require__(21),
+      invoke = __webpack_require__(69),
+      html = __webpack_require__(52),
+      cel = __webpack_require__(15),
+      global = __webpack_require__(6),
+      process = global.process,
+      setTask = global.setImmediate,
+      clearTask = global.clearImmediate,
+      MessageChannel = global.MessageChannel,
+      counter = 0,
+      queue = {},
+      ONREADYSTATECHANGE = 'onreadystatechange',
+      defer,
+      channel,
+      port;
+  var run = function run() {
+    var id = +this;
+    if (queue.hasOwnProperty(id)) {
+      var fn = queue[id];
+      delete queue[id];
+      fn();
+    }
+  };
+  var listener = function listener(event) {
+    run.call(event.data);
+  };
+  // Node.js 0.9+ & IE10+ has setImmediate, otherwise:
+  if (!setTask || !clearTask) {
+    setTask = function setImmediate(fn) {
+      var args = [],
+          i = 1;
+      while (arguments.length > i) {
+        args.push(arguments[i++]);
+      }queue[++counter] = function () {
+        invoke(typeof fn == 'function' ? fn : Function(fn), args);
+      };
+      defer(counter);
+      return counter;
+    };
+    clearTask = function clearImmediate(id) {
+      delete queue[id];
+    };
+    // Node.js 0.8-
+    if (__webpack_require__(28)(process) == 'process') {
+      defer = function defer(id) {
+        process.nextTick(ctx(run, id, 1));
+      };
+      // Browsers with MessageChannel, includes WebWorkers
+    } else if (MessageChannel) {
+        channel = new MessageChannel();
+        port = channel.port2;
+        channel.port1.onmessage = listener;
+        defer = ctx(port.postMessage, port, 1);
+        // Browsers with postMessage, skip WebWorkers
+        // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
+      } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {
+          defer = function defer(id) {
+            global.postMessage(id + '', '*');
+          };
+          global.addEventListener('message', listener, false);
+          // IE8-
+        } else if (ONREADYSTATECHANGE in cel('script')) {
+            defer = function defer(id) {
+              html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {
+                html.removeChild(this);
+                run.call(id);
+              };
+            };
+            // Rest old browsers
+          } else {
+              defer = function defer(id) {
+                setTimeout(ctx(run, id, 1), 0);
+              };
+            }
+  }
+  module.exports = {
+    set: setTask,
+    clear: clearTask
+  };
+
+/***/ },
+/* 69 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  // fast apply, http://jsperf.lnkit.com/fast-apply/5
+  module.exports = function (fn, args, that) {
+                    var un = that === undefined;
+                    switch (args.length) {
+                                      case 0:
+                                                        return un ? fn() : fn.call(that);
+                                      case 1:
+                                                        return un ? fn(args[0]) : fn.call(that, args[0]);
+                                      case 2:
+                                                        return un ? fn(args[0], args[1]) : fn.call(that, args[0], args[1]);
+                                      case 3:
+                                                        return un ? fn(args[0], args[1], args[2]) : fn.call(that, args[0], args[1], args[2]);
+                                      case 4:
+                                                        return un ? fn(args[0], args[1], args[2], args[3]) : fn.call(that, args[0], args[1], args[2], args[3]);
+                    }return fn.apply(that, args);
+  };
+
+/***/ },
+/* 70 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var global = __webpack_require__(6),
+      macrotask = __webpack_require__(68).set,
+      Observer = global.MutationObserver || global.WebKitMutationObserver,
+      process = global.process,
+      Promise = global.Promise,
+      isNode = __webpack_require__(28)(process) == 'process',
+      head,
+      last,
+      notify;
+  
+  var flush = function flush() {
+    var parent, fn;
+    if (isNode && (parent = process.domain)) parent.exit();
+    while (head) {
+      fn = head.fn;
+      fn(); // <- currently we use it only for Promise - try / catch not required
+      head = head.next;
+    }last = undefined;
+    if (parent) parent.enter();
+  };
+  
+  // Node.js
+  if (isNode) {
+    notify = function notify() {
+      process.nextTick(flush);
+    };
+    // browsers with MutationObserver
+  } else if (Observer) {
+      var toggle = true,
+          node = document.createTextNode('');
+      new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new
+      notify = function notify() {
+        node.data = toggle = !toggle;
+      };
+      // environments with maybe non-completely correct, but existent Promise
+    } else if (Promise && Promise.resolve) {
+        notify = function notify() {
+          Promise.resolve().then(flush);
+        };
+        // for other environments - macrotask based on:
+        // - setImmediate
+        // - MessageChannel
+        // - window.postMessag
+        // - onreadystatechange
+        // - setTimeout
+      } else {
+          notify = function notify() {
+            // strange IE + webpack dev server bug - use .call(global)
+            macrotask.call(global, flush);
+          };
+        }
+  
+  module.exports = function (fn) {
+    var task = { fn: fn, next: undefined };
+    if (last) last.next = task;
+    if (!head) {
+      head = task;
+      notify();
+    }last = task;
+  };
+
+/***/ },
+/* 71 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var redefine = __webpack_require__(18);
+  module.exports = function (target, src, safe) {
+    for (var key in src) {
+      redefine(target, key, src[key], safe);
+    }return target;
+  };
+
+/***/ },
+/* 72 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var global = __webpack_require__(6),
+      dP = __webpack_require__(9),
+      DESCRIPTORS = __webpack_require__(13),
+      SPECIES = __webpack_require__(43)('species');
+  
+  module.exports = function (KEY) {
+    var C = global[KEY];
+    if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {
+      configurable: true,
+      get: function get() {
+        return this;
+      }
+    });
+  };
+
+/***/ },
+/* 73 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var ITERATOR = __webpack_require__(43)('iterator'),
+      SAFE_CLOSING = false;
+  
+  try {
+    var riter = [7][ITERATOR]();
+    riter['return'] = function () {
+      SAFE_CLOSING = true;
+    };
+    Array.from(riter, function () {
+      throw 2;
+    });
+  } catch (e) {/* empty */}
+  
+  module.exports = function (exec, skipClosing) {
+    if (!skipClosing && !SAFE_CLOSING) return false;
+    var safe = false;
+    try {
+      var arr = [7],
+          iter = arr[ITERATOR]();
+      iter.next = function () {
+        safe = true;
+      };
+      arr[ITERATOR] = function () {
+        return iter;
+      };
+      exec(arr);
+    } catch (e) {/* empty */}
+    return safe;
+  };
+
+/***/ },
+/* 74 */
+/***/ function(module, exports) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
+  
+  var _global = global;
+  var setTimeout = _global.setTimeout;
+  var setTimeoutNative = _global.setTimeoutNative;
+  
+  // fix no setTimeout on Android V8
+  
+  if (typeof setTimeout === 'undefined' && typeof setTimeoutNative === 'function') {
+    (function () {
+      var timeoutMap = {};
+      var timeoutId = 0;
+      global.setTimeout = function (cb, time) {
+        timeoutMap[++timeoutId] = cb;
+        setTimeoutNative(timeoutId.toString(), time);
+      };
+      global.setTimeoutCallback = function (id) {
+        if (typeof timeoutMap[id] === 'function') {
+          timeoutMap[id]();
+          delete timeoutMap[id];
+        }
+      };
+    })();
+  }
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 75 */
+/***/ function(module, exports) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
+  
+  var _global = global;
+  var console = _global.console;
+  
+  
+  if (typeof console === 'undefined') {
+    global.console = {
+      log: function log() {
+        if (typeof nativeLog === 'function') {
+          nativeLog.apply(undefined, arguments);
+        }
+      },
+      error: function error() {
+        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+          args[_key] = arguments[_key];
+        }
+  
+        throw new Error(args);
+      }
+    };
+  }
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 76 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  
+  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /**
+                                                                                                                                                                                                                                                     * @fileOverview Main entry, instance manager
+                                                                                                                                                                                                                                                     *
+                                                                                                                                                                                                                                                     * - createInstance(instanceId, code, options, data)
+                                                                                                                                                                                                                                                     * - refreshInstance(instanceId, data)
+                                                                                                                                                                                                                                                     * - destroyInstance(instanceId)
+                                                                                                                                                                                                                                                     * - registerComponents(components)
+                                                                                                                                                                                                                                                     * - registerModules(modules)
+                                                                                                                                                                                                                                                     * - getRoot(instanceId)
+                                                                                                                                                                                                                                                     * - instanceMap
+                                                                                                                                                                                                                                                     * - callJS(instanceId, tasks)
+                                                                                                                                                                                                                                                     *   - fireEvent(ref, type, data)
+                                                                                                                                                                                                                                                     *   - callback(funcId, data)
+                                                                                                                                                                                                                                                     */
+  
+  exports.createInstance = createInstance;
+  exports.refreshInstance = refreshInstance;
+  exports.destroyInstance = destroyInstance;
+  exports.registerComponents = registerComponents;
+  exports.registerModules = registerModules;
+  exports.registerMethods = registerMethods;
+  exports.getRoot = getRoot;
+  exports.callJS = callJS;
+  
+  var _perf = __webpack_require__(77);
+  
+  var perf = _interopRequireWildcard(_perf);
+  
+  var _config = __webpack_require__(79);
+  
+  var config = _interopRequireWildcard(_config);
+  
+  var _app = __webpack_require__(80);
+  
+  var _app2 = _interopRequireDefault(_app);
+  
+  var _vm = __webpack_require__(85);
+  
+  var _vm2 = _interopRequireDefault(_vm);
+  
+  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+  
+  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+  
+  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
+  
+  var nativeComponentMap = config.nativeComponentMap;
+  
+  var instanceMap = {};
+  
+  /**
+   * create a Weex instance
+   *
+   * @param  {string} instanceId
+   * @param  {string} code
+   * @param  {object} [options] option `HAS_LOG` enable print log
+   * @param  {object} [data]
+   */
+  function createInstance(instanceId, code, options, data) {
+    var instance = instanceMap[instanceId];
+    options = options || {};
+  
+    config.debug = options.debug;
+  
+    var result;
+    if (!instance) {
+      perf.start('createInstance', instanceId);
+      instance = new _app2.default(instanceId, options);
+      instanceMap[instanceId] = instance;
+      result = instance.init(code, data);
+      perf.end('createInstance', instanceId);
+    } else {
+      result = new Error('invalid instance id "' + instanceId + '"');
+    }
+  
+    return result;
+  }
+  
+  /**
+   * refresh a Weex instance
+   *
+   * @param  {string} instanceId
+   * @param  {object} data
+   */
+  function refreshInstance(instanceId, data) {
+    var instance = instanceMap[instanceId];
+    var result;
+    if (instance) {
+      perf.start('refreshData', instanceId);
+      result = instance.refreshData(data);
+      perf.end('refreshData', instanceId);
+    } else {
+      result = new Error('invalid instance id "' + instanceId + '"');
+    }
+    return result;
+  }
+  
+  /**
+   * destroy a Weex instance
+   * @param  {string} instanceId
+   */
+  function destroyInstance(instanceId) {
+    var instance = instanceMap[instanceId];
+    if (!instance) {
+      return new Error('invalid instance id "' + instanceId + '"');
+    }
+  
+    perf.start('destroyInstance', instanceId);
+    instance.destroy();
+    delete instanceMap[instanceId];
+    perf.end('destroyInstance', instanceId);
+  
+    return instanceMap;
+  }
+  
+  /**
+   * register the name of each native component
+   * @param  {array} components array of name
+   */
+  function registerComponents(components) {
+    if (Array.isArray(components)) {
+      components.forEach(function register(name) {
+        /* istanbul ignore if */
+        if (!name) {
+          return;
+        }
+        if (typeof name === 'string') {
+          nativeComponentMap[name] = true;
+        } else if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object' && typeof name.type === 'string') {
+          nativeComponentMap[name.type] = name;
+        }
+      });
+    }
+  }
+  
+  /**
+   * register the name and methods of each module
+   * @param  {object} modules a object of modules
+   */
+  function registerModules(modules) {
+    if ((typeof modules === 'undefined' ? 'undefined' : _typeof(modules)) === 'object') {
+      _vm2.default.registerModules(modules);
+    }
+  }
+  
+  /**
+   * register the name and methods of each api
+   * @param  {object} apis a object of apis
+   */
+  function registerMethods(apis) {
+    if ((typeof apis === 'undefined' ? 'undefined' : _typeof(apis)) === 'object') {
+      _vm2.default.registerMethods(apis);
+    }
+  }
+  
+  /**
+   * get a whole element tree of an instance
+   * for debugging
+   * @param  {string} instanceId
+   * @return {object} a virtual dom tree
+   */
+  function getRoot(instanceId) {
+    var instance = instanceMap[instanceId];
+    var result;
+    if (instance) {
+      result = instance.getRootElement();
+    } else {
+      result = new Error('invalid instance id "' + instanceId + '"');
+    }
+    return result;
+  }
+  
+  var jsHandlers = {
+    fireEvent: function fireEvent(instanceId, ref, type, data) {
+      var instance = instanceMap[instanceId];
+      var result;
+      perf.start('fireEvent', instanceId + '-' + ref + '-' + type);
+      result = instance.fireEvent(ref, type, data);
+      perf.end('fireEvent', instanceId + '-' + ref + '-' + type);
+      return result;
+    },
+  
+    callback: function callback(instanceId, funcId, data, ifLast) {
+      var instance = instanceMap[instanceId];
+      var result;
+      perf.start('callback', instanceId + '-' + funcId + '-' + data + '-' + ifLast);
+      result = instance.callback(funcId, data, ifLast);
+      perf.end('callback', instanceId + '-' + funcId + '-' + data + '-' + ifLast);
+      return result;
+    }
+  };
+  
+  /**
+   * accept calls from native (event or callback)
+   *
+   * @param  {string} instanceId
+   * @param  {array} tasks list with `method` and `args`
+   */
+  function callJS(instanceId, tasks) {
+    var instance = instanceMap[instanceId];
+    var results = [];
+    if (instance && Array.isArray(tasks)) {
+      tasks.forEach(function (task) {
+        var handler = jsHandlers[task.method];
+        var args = [].concat(_toConsumableArray(task.args));
+        if (typeof handler === 'function') {
+          log('javascript:', task.method, task.args);
+          args.unshift(instanceId);
+          results.push(handler.apply(undefined, _toConsumableArray(args)));
+        }
+      });
+    } else {
+      results.push(new Error('invalid instance id "' + instanceId + '" or tasks'));
+    }
+  
+    return results;
+  }
+
+/***/ },
+/* 77 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.start = start;
+  exports.end = end;
+  exports.reset = reset;
+  exports.toJSON = toJSON;
+  
+  var _log = __webpack_require__(78);
+  
+  var _log2 = _interopRequireDefault(_log);
+  
+  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+  
+  var data = { type: 'root', children: [] };
+  var current = data;
+  var stack = [current];
+  
+  function spaces(num) {
+    return Array(num).join(' ');
+  }
+  
+  function start(type, id) {
+    var task = { type: type, id: id, children: [], start: Date.now() };
+    current.children.push(task);
+    stack.push(task);
+    current = task;
+    (0, _log2.default)('perf:' + spaces(stack.length - 1), 'start', task.type, task.id);
+  }
+  
+  function end(type, id) {
+    var task = stack.pop();
+    task.end = Date.now();
+    current = stack[stack.length - 1];
+    (0, _log2.default)('perf:' + spaces(stack.length), 'end', task.end - task.start + 'ms', task.type, task.id);
+  }
+  
+  function reset() {
+    data.children = [];
+    current = data;
+    stack.length = 0;
+    stack.push(current);
+  }
+  
+  function toJSON() {
+    return JSON.parse(JSON.stringify(data));
+  }
+
+/***/ },
+/* 78 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.default = log;
+  
+  var _config = __webpack_require__(79);
+  
+  var config = _interopRequireWildcard(_config);
+  
+  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+  
+  function log() {
+    if (config.debug) {
+      var _global$console;
+  
+      (_global$console = global.console).log.apply(_global$console, arguments);
+    }
+  }
+  
+  global.log = log;
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 79 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  var nativeComponentMap = exports.nativeComponentMap = {
+    text: true,
+    image: true,
+    container: true,
+    slider: {
+      type: 'slider',
+      append: 'tree'
+    },
+    cell: {
+      type: 'cell',
+      append: 'tree'
+    }
+  };
+  
+  var customComponentMap = exports.customComponentMap = {};
+  
+  var debug = exports.debug = false;
+
+/***/ },
+/* 80 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.default = AppInstance;
+  
+  var _util = __webpack_require__(81);
+  
+  var _perf = __webpack_require__(77);
+  
+  var perf = _interopRequireWildcard(_perf);
+  
+  var _bundle = __webpack_require__(82);
+  
+  var bundle = _interopRequireWildcard(_bundle);
+  
+  var _ctrl = __webpack_require__(100);
+  
+  var ctrl = _interopRequireWildcard(_ctrl);
+  
+  var _differ = __webpack_require__(102);
+  
+  var _differ2 = _interopRequireDefault(_differ);
+  
+  var _event = __webpack_require__(103);
+  
+  var _event2 = _interopRequireDefault(_event);
+  
+  var _domListener = __webpack_require__(101);
+  
+  var _domListener2 = _interopRequireDefault(_domListener);
+  
+  var _dom = __webpack_require__(104);
+  
+  var _register = __webpack_require__(98);
+  
+  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+  
+  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+  
+  function AppInstance(instanceId, options) {
+    var _this = this;
+  
+    perf.start('initInstance', instanceId);
+    this.id = instanceId;
+    this.options = options || {};
+    this.vm = null;
+    this.doc = new _dom.Document(instanceId);
+    this.customComponentMap = {};
+    this.callbacks = {};
+    this.differ = new _differ2.default(instanceId);
+    this.uid = 0;
+    this.rendered = false;
+    this.eventManager = new _event2.default();
+    this.listener = new _domListener2.default(this.id, function (tasks) {
+      _this.callTasks(tasks);
+    });
+    this.doc.setEventManager(this.eventManager);
+    this.doc.setListener(this.listener);
+  
+    perf.end('initInstance', instanceId);
+  } /**
+     * @fileOverview
+     * Weex instance constructor & definition
+     */
+  
+  function normalize(app, v) {
+    var type = (0, _util.typof)(v);
+  
+    switch (type) {
+      case 'undefined':
+      case 'null':
+        return '';
+      case 'regexp':
+        return v.toString();
+      case 'date':
+        return v.toISOString();
+      case 'number':
+      case 'string':
+      case 'boolean':
+      case 'array':
+      case 'object':
+        if (v instanceof _dom.Node) {
+          return v.ref;
+        }
+        return v;
+      case 'function':
+        app.callbacks[++app.uid] = v;
+        return app.uid.toString();
+      default:
+        return JSON.stringify(v);
+    }
+  }
+  
+  AppInstance.prototype.callTasks = function (tasks) {
+    var _this2 = this;
+  
+    if ((0, _util.typof)(tasks) !== 'array') {
+      tasks = [tasks];
+    }
+  
+    tasks.forEach(function (task) {
+      task.args = task.args.map(function (arg) {
+        return normalize(_this2, arg);
+      });
+    });
+  
+    callNative(this.id, tasks, '-1');
+  };
+  
+  (0, _util.extend)(AppInstance.prototype, bundle, ctrl, {
+    registerComponent: _register.registerComponent,
+    requireComponent: _register.requireComponent,
+    requireModule: _register.requireModule
+  });
+
+/***/ },
+/* 81 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.warn = exports.log = exports.indexOf = exports.define = exports.normalize = exports.typof = exports.stringify = exports.isArray = exports.isPlainObject = exports.isObject = exports.extend = exports.toArray = exports.bind = exports.camelize = exports.isReserved = undefined;
+  
+  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /// lang.js
+  
+  
+  var _config2 = __webpack_require__(79);
+  
+  var _config3 = _interopRequireDefault(_config2);
+  
+  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+  
+  /**
+   * Check is a string starts with $ or _
+   *
+   * @param {String} str
+   * @return {Boolean}
+   */
+  
+  var isReserved = exports.isReserved = function isReserved(str) {
+    var c = (str + '').charCodeAt(0);
+    return c === 0x24 || c === 0x5F;
+  };
+  
+  /**
+   * Camelize a hyphen-delmited string.
+   *
+   * @param {String} str
+   * @return {String}
+   */
+  
+  var camelRE = /-(\w)/g;
+  function toUpper(_, c) {
+    return c ? c.toUpperCase() : '';
+  }
+  var camelize = exports.camelize = function camelize(str) {
+    return str.replace(camelRE, toUpper);
+  };
+  
+  /**
+   * Simple bind, faster than native
+   *
+   * @param {Function} fn
+   * @param {Object} ctx
+   * @return {Function}
+   */
+  
+  var bind = exports.bind = function bind(fn, ctx) {
+    return function (a) {
+      var l = arguments.length;
+      return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx);
+    };
+  };
+  
+  /**
+   * Convert an Array-like object to a real Array.
+   *
+   * @param {Array-like} list
+   * @param {Number} [start] - start index
+   * @return {Array}
+   */
+  
+  var toArray = exports.toArray = function toArray(list, start) {
+    start = start || 0;
+    var i = list.length - start;
+    var ret = new Array(i);
+    while (i--) {
+      ret[i] = list[i + start];
+    }
+    return ret;
+  };
+  
+  /**
+   * Mix properties into target object.
+   *
+   * @param {Object} to
+   * @param {Object} from
+   */
+  
+  var extend = exports.extend = function extend(target) {
+    for (var _len = arguments.length, src = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+      src[_key - 1] = arguments[_key];
+    }
+  
+    if (typeof Object.assign === 'function') {
+      Object.assign.apply(Object, [target].concat(src));
+    } else {
+      var first = src.shift();
+      for (var key in first) {
+        target[key] = first[key];
+      }
+      if (src.length) {
+        extend.apply(undefined, [target].concat(src));
+      }
+    }
+    return target;
+  };
+  
+  /**
+   * Quick object check - this is primarily used to tell
+   * Objects from primitive values when we know the value
+   * is a JSON-compliant type.
+   *
+   * @param {*} obj
+   * @return {Boolean}
+   */
+  
+  var isObject = exports.isObject = function isObject(obj) {
+    return !!(obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object');
+  };
+  
+  /**
+   * Strict object type check. Only returns true
+   * for plain JavaScript objects.
+   *
+   * @param {*} obj
+   * @return {Boolean}
+   */
+  
+  var toString = Object.prototype.toString;
+  var isPlainObject = exports.isPlainObject = function isPlainObject(obj) {
+    return toString.call(obj) === '[object Object]';
+  };
+  
+  /**
+   * Array type check.
+   *
+   * @param {*} obj
+   * @return {Boolean}
+   */
+  
+  var isArray = exports.isArray = function isArray(obj) {
+    return Array.isArray(obj);
+  };
+  
+  var stringify = exports.stringify = function stringify(x) {
+    return typeof x === 'undefined' || x === null || typeof x === 'function' ? '' : (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === 'object' ? x instanceof RegExp ? x.toString() : x instanceof Date ? JSON.parse(JSON.stringify(x)) : JSON.stringify(x) : x.toString();
+  };
+  
+  var typof = exports.typof = function typof(v) {
+    var s = Object.prototype.toString.call(v);
+    return s.substring(8, s.length - 1).toLowerCase();
+  };
+  
+  var normalize = exports.normalize = function normalize(v) {
+    var type = typof(v);
+  
+    switch (type) {
+      case 'undefined':
+      case 'null':
+        return '';
+      case 'regexp':
+        return v.toString();
+      case 'date':
+        return v.toISOString();
+      case 'number':
+      case 'string':
+      case 'boolean':
+      case 'array':
+      case 'object':
+      case 'function':
+        return v;
+      default:
+        return JSON.stringify(v);
+    }
+  };
+  
+  /**
+   * Define a non-enumerable property
+   *
+   * @param {Object} obj
+   * @param {String} key
+   * @param {*} val
+   * @param {Boolean} [enumerable]
+   */
+  
+  var define = exports.define = function define(obj, key, val, enumerable) {
+    Object.defineProperty(obj, key, {
+      value: val,
+      enumerable: !!enumerable,
+      writable: true,
+      configurable: true
+    });
+  };
+  
+  /**
+   * Manual indexOf because it's slightly faster than
+   * native.
+   *
+   * @param {Array} arr
+   * @param {*} obj
+   */
+  
+  var indexOf = exports.indexOf = function indexOf(arr, obj) {
+    for (var i = 0, l = arr.length; i < l; i++) {
+      if (arr[i] === obj) return i;
+    }
+    return -1;
+  };
+  
+  /// debug.js
+  
+  var hasConsole = typeof console !== 'undefined';
+  
+  /**
+   * Log a message.
+   *
+   * @param {String} msg
+   */
+  
+  var log = exports.log = function log(msg) {
+    var _config = _config3.default || {};
+    if (hasConsole && _config.debug) {
+      console.log.call(undefined, '[info]: ', msg);
+    }
+  };
+  
+  /**
+   * We've got a problem here.
+   *
+   * @param {String} msg
+   */
+  
+  var warn = exports.warn = function warn(msg) {
+    // if (hasConsole && (!config.silent || config.debug)) {
+    if (hasConsole) {
+      console.warn.call(undefined, '[warn]: ', msg);
+      /* istanbul ignore if */
+      // if (config.debug) {
+      //   /* jshint debug: true */
+      //   debugger
+      // }
+    }
+  };
+
+/***/ },
+/* 82 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.require = exports.define = undefined;
+  exports.clearCommonModules = clearCommonModules;
+  exports.bootstrap = bootstrap;
+  exports.register = register;
+  exports.render = render;
+  
+  var _semver = __webpack_require__(83);
+  
+  var _semver2 = _interopRequireDefault(_semver);
+  
+  var _util = __webpack_require__(81);
+  
+  var _ = _interopRequireWildcard(_util);
+  
+  var _config = __webpack_require__(79);
+  
+  var config = _interopRequireWildcard(_config);
+  
+  var _perf = __webpack_require__(77);
+  
+  var perf = _interopRequireWildcard(_perf);
+  
+  var _vm = __webpack_require__(85);
+  
+  var _vm2 = _interopRequireDefault(_vm);
+  
+  var _downgrade = __webpack_require__(99);
+  
+  var downgrade = _interopRequireWildcard(_downgrade);
+  
+  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+  
+  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+  
+  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /**
+                                                                                                                                                                                                                     * @fileOverview
+                                                                                                                                                                                                                     * api that invoked by js bundle code
+                                                                                                                                                                                                                     *
+                                                                                                                                                                                                                     * - define(name, factory): define a new composed component type
+                                                                                                                                                                                                                     * - bootstrap(type, config, data): require a certain type &
+                                                                                                                                                                                                                     *         render with (optional) data
+                                                                                                                                                                                                                     *
+                                                                                                                                                                                                                     * deprecated:
+                                                                                                                                                                                                                     * - register(type, options): register a new composed component type
+                                                                                                                                                                                                                     * - render(type, data): render by a certain type with (optional) data
+                                                                                                                                                                                                                     * - require(type)(data): require a type then render with data
+                                                                                                                                                                                                                     */
+  
+  var WEEX_COMPONENT_REG = /^\@weex-component\//;
+  var WEEX_MODULE_REG = /^\@weex-module\//;
+  var NORMAL_MODULE_REG = /^\.{1,2}\//;
+  var JS_SURFIX_REG = /\.js$/;
+  
+  var isWeexComponent = function isWeexComponent(name) {
+    return !!name.match(WEEX_COMPONENT_REG);
+  };
+  var isWeexModule = function isWeexModule(name) {
+    return !!name.match(WEEX_MODULE_REG);
+  };
+  var isNormalModule = function isNormalModule(name) {
+    return !!name.match(NORMAL_MODULE_REG);
+  };
+  var isNpmModule = function isNpmModule(name) {
+    return !isWeexComponent(name) && !isWeexModule(name) && !isNormalModule(name);
+  };
+  
+  function removeWeexPrefix(str) {
+    return str.replace(WEEX_COMPONENT_REG, '').replace(WEEX_MODULE_REG, '');
+  }
+  
+  function removeJSSurfix(str) {
+    return str.replace(JS_SURFIX_REG, '');
+  }
+  
+  var commonModules = {};
+  
+  function clearCommonModules() {
+    commonModules = {};
+  }
+  
+  // define(name, factory) for primary usage
+  // or
+  // define(name, deps, factory) for compatibility
+  // Notice: DO NOT use function define() {},
+  // it will cause error after builded by webpack
+  var define = exports.define = function define(name, deps, factory) {
+    var _this = this;
+  
+    perf.start('define', name);
+  
+    if (_.typof(deps) === 'function') {
+      factory = deps;
+      deps = [];
+    }
+  
+    var _require = function _require(name) {
+      var cleanName = void 0;
+  
+      if (isWeexComponent(name)) {
+        cleanName = removeWeexPrefix(name);
+        return _this.requireComponent(cleanName);
+      }
+      if (isWeexModule(name)) {
+        cleanName = removeWeexPrefix(name);
+        return _this.requireModule(cleanName);
+      }
+      if (isNormalModule(name)) {
+        cleanName = removeJSSurfix(name);
+        return commonModules[name];
+      }
+      if (isNpmModule(name)) {
+        cleanName = removeJSSurfix(name);
+        return commonModules[name];
+      }
+    };
+    var _module = { exports: {} };
+  
+    var cleanName = void 0;
+    if (isWeexComponent(name)) {
+      cleanName = removeWeexPrefix(name);
+  
+      factory(_require, _module.exports, _module);
+  
+      this.registerComponent(cleanName, _module.exports);
+    } else if (isWeexModule(name)) {
+      cleanName = removeWeexPrefix(name);
+  
+      factory(_require, _module.exports, _module);
+  
+      _vm2.default.registerModules(_defineProperty({}, cleanName, _module.exports));
+    } else if (isNormalModule(name)) {
+      cleanName = removeJSSurfix(name);
+  
+      factory(_require, _module.exports, _module);
+  
+      commonModules[cleanName] = _module.exports;
+    } else if (isNpmModule(name)) {
+      cleanName = removeJSSurfix(name);
+  
+      factory(_require, _module.exports, _module);
+  
+      var exports = _module.exports;
+      if (exports.template || exports.style || exports.methods) {
+        // downgrade to old define method (define('componentName', factory))
+        // the exports contain one key of template, style or methods
+        // but it has risk!!!
+        this.registerComponent(cleanName, exports);
+      } else {
+        commonModules[cleanName] = _module.exports;
+      }
+    }
+  
+    perf.end('define', name);
+  };
+  
+  function bootstrap(name, config, data) {
+    var cleanName = void 0;
+  
+    if (isWeexComponent(name)) {
+      cleanName = removeWeexPrefix(name);
+    } else if (isNpmModule(name)) {
+      cleanName = removeJSSurfix(name);
+      // check if define by old 'define' method
+      if (!this.customComponentMap[cleanName]) {
+        return new Error('It\'s not a component: ' + name);
+      }
+    } else {
+      return new Error('Wrong component name: ' + name);
+    }
+  
+    config = _.isPlainObject(config) ? config : {};
+  
+    if (typeof config.transformerVersion === 'string' && typeof global.needTransformerVersion === 'string' && !_semver2.default.satisfies(config.transformerVersion, global.needTransformerVersion)) {
+      return new Error('JS Bundle version: ' + config.transformerVersion + ' ' + ('not compatible with ' + global.needTransformerVersion));
+    }
+  
+    var _checkDowngrade = downgrade.check(config.downgrade);
+    if (_checkDowngrade.isDowngrade) {
+      this.callTasks([{
+        module: 'instanceWrap',
+        method: 'error',
+        args: [_checkDowngrade.errorType, _checkDowngrade.code, _checkDowngrade.errorMessage]
+      }]);
+      return new Error('Downgrade: ' + config.downgrade);
+    }
+  
+    perf.start('create vm', cleanName);
+  
+    this.vm = new _vm2.default(cleanName, { _app: this }, null, data, {
+      'hook:ready': function hookReady() {
+        perf.end('create vm', cleanName);
+      }
+    });
+  }
+  
+  /**
+   * @deprecated
+   */
+  function register(type, options) {
+    perf.start('register', type);
+    this.registerComponent(type, options);
+    perf.end('register', type);
+  }
+  
+  /**
+   * @deprecated
+   */
+  function render(type, data) {
+    return this.bootstrap(type, {}, data);
+  }
+  
+  /**
+   * @deprecated
+   */
+  function _require2(type) {
+    var _this2 = this;
+  
+    return function (data) {
+      return _this2.bootstrap(type, {}, data);
+    };
+  }
+  exports.require = _require2;
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 83 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /* WEBPACK VAR INJECTION */(function(process) {'use strict';
+  
+  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
+  
+  exports = module.exports = SemVer;
+  
+  // The debug function is excluded entirely from the minified version.
+  /* nomin */var debug;
+  /* nomin */if ((typeof process === 'undefined' ? 'undefined' : _typeof(process)) === 'object' &&
+  /* nomin */process.env &&
+  /* nomin */process.env.NODE_DEBUG &&
+  /* nomin *//\bsemver\b/i.test(process.env.NODE_DEBUG))
+    /* nomin */debug = function debug() {
+      /* nomin */var args = Array.prototype.slice.call(arguments, 0);
+      /* nomin */args.unshift('SEMVER');
+      /* nomin */console.log.apply(console, args);
+      /* nomin */
+    };
+    /* nomin */else
+    /* nomin */debug = function debug() {};
+  
+  // Note: this is the semver.org version of the spec that it implements
+  // Not necessarily the package version of this code.
+  exports.SEMVER_SPEC_VERSION = '2.0.0';
+  
+  var MAX_LENGTH = 256;
+  var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
+  
+  // The actual regexps go on exports.re
+  var re = exports.re = [];
+  var src = exports.src = [];
+  var R = 0;
+  
+  // The following Regular Expressions can be used for tokenizing,
+  // validating, and parsing SemVer version strings.
+  
+  // ## Numeric Identifier
+  // A single `0`, or a non-zero digit followed by zero or more digits.
+  
+  var NUMERICIDENTIFIER = R++;
+  src[NUMERICIDENTIFIER] = '0|[1-9]\\d*';
+  var NUMERICIDENTIFIERLOOSE = R++;
+  src[NUMERICIDENTIFIERLOOSE] = '[0-9]+';
+  
+  // ## Non-numeric Identifier
+  // Zero or more digits, followed by a letter or hyphen, and then zero or
+  // more letters, digits, or hyphens.
+  
+  var NONNUMERICIDENTIFIER = R++;
+  src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';
+  
+  // ## Main Version
+  // Three dot-separated numeric identifiers.
+  
+  var MAINVERSION = R++;
+  src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')';
+  
+  var MAINVERSIONLOOSE = R++;
+  src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')';
+  
+  // ## Pre-release Version Identifier
+  // A numeric identifier, or a non-numeric identifier.
+  
+  var PRERELEASEIDENTIFIER = R++;
+  src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + '|' + src[NONNUMERICIDENTIFIER] + ')';
+  
+  var PRERELEASEIDENTIFIERLOOSE = R++;
+  src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + '|' + src[NONNUMERICIDENTIFIER] + ')';
+  
+  // ## Pre-release Version
+  // Hyphen, followed by one or more dot-separated pre-release version
+  // identifiers.
+  
+  var PRERELEASE = R++;
+  src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))';
+  
+  var PRERELEASELOOSE = R++;
+  src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))';
+  
+  // ## Build Metadata Identifier
+  // Any combination of digits, letters, or hyphens.
+  
+  var BUILDIDENTIFIER = R++;
+  src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+';
+  
+  // ## Build Metadata
+  // Plus sign, followed by one or more period-separated build metadata
+  // identifiers.
+  
+  var BUILD = R++;
+  src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))';
+  
+  // ## Full Version String
+  // A main version, followed optionally by a pre-release version and
+  // build metadata.
+  
+  // Note that the only major, minor, patch, and pre-release sections of
+  // the version string are capturing groups.  The build metadata is not a
+  // capturing group, because it should not ever be used in version
+  // comparison.
+  
+  var FULL = R++;
+  var FULLPLAIN = 'v?' + src[MAINVERSION] + src[PRERELEASE] + '?' + src[BUILD] + '?';
+  
+  src[FULL] = '^' + FULLPLAIN + '$';
+  
+  // like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
+  // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
+  // common in the npm registry.
+  var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + src[PRERELEASELOOSE] + '?' + src[BUILD] + '?';
+  
+  var LOOSE = R++;
+  src[LOOSE] = '^' + LOOSEPLAIN + '$';
+  
+  var GTLT = R++;
+  src[GTLT] = '((?:<|>)?=?)';
+  
+  // Something like "2.*" or "1.2.x".
+  // Note that "x.x" is a valid xRange identifer, meaning "any version"
+  // Only the first item is strictly required.
+  var XRANGEIDENTIFIERLOOSE = R++;
+  src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*';
+  var XRANGEIDENTIFIER = R++;
+  src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*';
+  
+  var XRANGEPLAIN = R++;
+  src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:' + src[PRERELEASE] + ')?' + src[BUILD] + '?' + ')?)?';
+  
+  var XRANGEPLAINLOOSE = R++;
+  src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:' + src[PRERELEASELOOSE] + ')?' + src[BUILD] + '?' + ')?)?';
+  
+  var XRANGE = R++;
+  src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$';
+  var XRANGELOOSE = R++;
+  src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$';
+  
+  // Tilde ranges.
+  // Meaning is "reasonably at or greater than"
+  var LONETILDE = R++;
+  src[LONETILDE] = '(?:~>?)';
+  
+  var TILDETRIM = R++;
+  src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+';
+  re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g');
+  var tildeTrimReplace = '$1~';
+  
+  var TILDE = R++;
+  src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$';
+  var TILDELOOSE = R++;
+  src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$';
+  
+  // Caret ranges.
+  // Meaning is "at least and backwards compatible with"
+  var LONECARET = R++;
+  src[LONECARET] = '(?:\\^)';
+  
+  var CARETTRIM = R++;
+  src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+';
+  re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g');
+  var caretTrimReplace = '$1^';
+  
+  var CARET = R++;
+  src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$';
+  var CARETLOOSE = R++;
+  src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$';
+  
+  // A simple gt/lt/eq thing, or just "" to indicate "any version"
+  var COMPARATORLOOSE = R++;
+  src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$';
+  var COMPARATOR = R++;
+  src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$';
+  
+  // An expression to strip any whitespace between the gtlt and the thing
+  // it modifies, so that `> 1.2.3` ==> `>1.2.3`
+  var COMPARATORTRIM = R++;
+  src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')';
+  
+  // this one has to use the /g flag
+  re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g');
+  var comparatorTrimReplace = '$1$2$3';
+  
+  // Something like `1.2.3 - 1.2.4`
+  // Note that these all use the loose form, because they'll be
+  // checked against either the strict or loose comparator form
+  // later.
+  var HYPHENRANGE = R++;
+  src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAIN] + ')' + '\\s*$';
+  
+  var HYPHENRANGELOOSE = R++;
+  src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAINLOOSE] + ')' + '\\s*$';
+  
+  // Star ranges basically just allow anything at all.
+  var STAR = R++;
+  src[STAR] = '(<|>)?=?\\s*\\*';
+  
+  // Compile to actual regexp objects.
+  // All are flag-free, unless they were created above with a flag.
+  for (var i = 0; i < R; i++) {
+    debug(i, src[i]);
+    if (!re[i]) re[i] = new RegExp(src[i]);
+  }
+  
+  exports.parse = parse;
+  function parse(version, loose) {
+    if (version instanceof SemVer) return version;
+  
+    if (typeof version !== 'string') return null;
+  
+    if (version.length > MAX_LENGTH) return null;
+  
+    var r = loose ? re[LOOSE] : re[FULL];
+    if (!r.test(version)) return null;
+  
+    try {
+      return new SemVer(version, loose);
+    } catch (er) {
+      return null;
+    }
+  }
+  
+  exports.valid = valid;
+  function valid(version, loose) {
+    var v = parse(version, loose);
+    return v ? v.version : null;
+  }
+  
+  exports.clean = clean;
+  function clean(version, loose) {
+    var s = parse(version.trim().replace(/^[=v]+/, ''), loose);
+    return s ? s.version : null;
+  }
+  
+  exports.SemVer = SemVer;
+  
+  function SemVer(version, loose) {
+    if (version instanceof SemVer) {
+      if (version.loose === loose) return version;else version = version.version;
+    } else if (typeof version !== 'string') {
+      throw new TypeError('Invalid Version: ' + version);
+    }
+  
+    if (version.length > MAX_LENGTH) throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters');
+  
+    if (!(this instanceof SemVer)) return new SemVer(version, loose);
+  
+    debug('SemVer', version, loose);
+    this.loose = loose;
+    var m = version.trim().match(loose ? re[LOOSE] : re[FULL]);
+  
+    if (!m) throw new TypeError('Invalid Version: ' + version);
+  
+    this.raw = version;
+  
+    // these are actually numbers
+    this.major = +m[1];
+    this.minor = +m[2];
+    this.patch = +m[3];
+  
+    if (this.major > MAX_SAFE_INTEGER || this.major < 0) throw new TypeError('Invalid major version');
+  
+    if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) throw new TypeError('Invalid minor version');
+  
+    if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) throw new TypeError('Invalid patch version');
+  
+    // numberify any prerelease numeric ids
+    if (!m[4]) this.prerelease = [];else this.prerelease = m[4].split('.').map(function (id) {
+      if (/^[0-9]+$/.test(id)) {
+        var num = +id;
+        if (num >= 0 && num < MAX_SAFE_INTEGER) return num;
+      }
+      return id;
+    });
+  
+    this.build = m[5] ? m[5].split('.') : [];
+    this.format();
+  }
+  
+  SemVer.prototype.format = function () {
+    this.version = this.major + '.' + this.minor + '.' + this.patch;
+    if (this.prerelease.length) this.version += '-' + this.prerelease.join('.');
+    return this.version;
+  };
+  
+  SemVer.prototype.toString = function () {
+    return this.version;
+  };
+  
+  SemVer.prototype.compare = function (other) {
+    debug('SemVer.compare', this.version, this.loose, other);
+    if (!(other instanceof SemVer)) other = new SemVer(other, this.loose);
+  
+    return this.compareMain(other) || this.comparePre(other);
+  };
+  
+  SemVer.prototype.compareMain = function (other) {
+    if (!(other instanceof SemVer)) other = new SemVer(other, this.loose);
+  
+    return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch);
+  };
+  
+  SemVer.prototype.comparePre = function (other) {
+    if (!(other instanceof SemVer)) other = new SemVer(other, this.loose);
+  
+    // NOT having a prerelease is > having one
+    if (this.prerelease.length && !other.prerelease.length) return -1;else if (!this.prerelease.length && other.prerelease.length) return 1;else if (!this.prerelease.length && !other.prerelease.length) return 0;
+  
+    var i = 0;
+    do {
+      var a = this.prerelease[i];
+      var b = other.prerelease[i];
+      debug('prerelease compare', i, a, b);
+      if (a === undefined && b === undefined) return 0;else if (b === undefined) return 1;else if (a === undefined) return -1;else if (a === b) continue;else return compareIdentifiers(a, b);
+    } while (++i);
+  };
+  
+  // preminor will bump the version up to the next minor release, and immediately
+  // down to pre-release. premajor and prepatch work the same way.
+  SemVer.prototype.inc = function (release, identifier) {
+    switch (release) {
+      case 'premajor':
+        this.prerelease.length = 0;
+        this.patch = 0;
+        this.minor = 0;
+        this.major++;
+        this.inc('pre', identifier);
+        break;
+      case 'preminor':
+        this.prerelease.length = 0;
+        this.patch = 0;
+        this.minor++;
+        this.inc('pre', identifier);
+        break;
+      case 'prepatch':
+        // If this is already a prerelease, it will bump to the next version
+        // drop any prereleases that might already exist, since they are not
+        // relevant at this point.
+        this.prerelease.length = 0;
+        this.inc('patch', identifier);
+        this.inc('pre', identifier);
+        break;
+      // If the input is a non-prerelease version, this acts the same as
+      // prepatch.
+      case 'prerelease':
+        if (this.prerelease.length === 0) this.inc('patch', identifier);
+        this.inc('pre', identifier);
+        break;
+  
+      case 'major':
+        // If this is a pre-major version, bump up to the same major version.
+        // Otherwise increment major.
+        // 1.0.0-5 bumps to 1.0.0
+        // 1.1.0 bumps to 2.0.0
+        if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) this.major++;
+        this.minor = 0;
+        this.patch = 0;
+        this.prerelease = [];
+        break;
+      case 'minor':
+        // If this is a pre-minor version, bump up to the same minor version.
+        // Otherwise increment minor.
+        // 1.2.0-5 bumps to 1.2.0
+        // 1.2.1 bumps to 1.3.0
+        if (this.patch !== 0 || this.prerelease.length === 0) this.minor++;
+        this.patch = 0;
+        this.prerelease = [];
+        break;
+      case 'patch':
+        // If this is not a pre-release version, it will increment the patch.
+        // If it is a pre-release it will bump up to the same patch version.
+        // 1.2.0-5 patches to 1.2.0
+        // 1.2.0 patches to 1.2.1
+        if (this.prerelease.length === 0) this.patch++;
+        this.prerelease = [];
+        break;
+      // This probably shouldn't be used publicly.
+      // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
+      case 'pre':
+        if (this.prerelease.length === 0) this.prerelease = [0];else {
+          var i = this.prerelease.length;
+          while (--i >= 0) {
+            if (typeof this.prerelease[i] === 'number') {
+              this.prerelease[i]++;
+              i = -2;
+            }
+          }
+          if (i === -1) // didn't increment anything
+            this.prerelease.push(0);
+        }
+        if (identifier) {
+          // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
+          // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
+          if (this.prerelease[0] === identifier) {
+            if (isNaN(this.prerelease[1])) this.prerelease = [identifier, 0];
+          } else this.prerelease = [identifier, 0];
+        }
+        break;
+  
+      default:
+        throw new Error('invalid increment argument: ' + release);
+    }
+    this.format();
+    this.raw = this.version;
+    return this;
+  };
+  
+  exports.inc = inc;
+  function inc(version, release, loose, identifier) {
+    if (typeof loose === 'string') {
+      identifier = loose;
+      loose = undefined;
+    }
+  
+    try {
+      return new SemVer(version, loose).inc(release, identifier).version;
+    } catch (er) {
+      return null;
+    }
+  }
+  
+  exports.diff = diff;
+  function diff(version1, version2) {
+    if (eq(version1, version2)) {
+      return null;
+    } else {
+      var v1 = parse(version1);
+      var v2 = parse(version2);
+      if (v1.prerelease.length || v2.prerelease.length) {
+        for (var key in v1) {
+          if (key === 'major' || key === 'minor' || key === 'patch') {
+            if (v1[key] !== v2[key]) {
+              return 'pre' + key;
+            }
+          }
+        }
+        return 'prerelease';
+      }
+      for (var key in v1) {
+        if (key === 'major' || key === 'minor' || key === 'patch') {
+          if (v1[key] !== v2[key]) {
+            return key;
+          }
+        }
+      }
+    }
+  }
+  
+  exports.compareIdentifiers = compareIdentifiers;
+  
+  var numeric = /^[0-9]+$/;
+  function compareIdentifiers(a, b) {
+    var anum = numeric.test(a);
+    var bnum = numeric.test(b);
+  
+    if (anum && bnum) {
+      a = +a;
+      b = +b;
+    }
+  
+    return anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : a > b ? 1 : 0;
+  }
+  
+  exports.rcompareIdentifiers = rcompareIdentifiers;
+  function rcompareIdentifiers(a, b) {
+    return compareIdentifiers(b, a);
+  }
+  
+  exports.major = major;
+  function major(a, loose) {
+    return new SemVer(a, loose).major;
+  }
+  
+  exports.minor = minor;
+  function minor(a, loose) {
+    return new SemVer(a, loose).minor;
+  }
+  
+  exports.patch = patch;
+  function patch(a, loose) {
+    return new SemVer(a, loose).patch;
+  }
+  
+  exports.compare = compare;
+  function compare(a, b, loose) {
+    return new SemVer(a, loose).compare(b);
+  }
+  
+  exports.compareLoose = compareLoose;
+  function compareLoose(a, b) {
+    return compare(a, b, true);
+  }
+  
+  exports.rcompare = rcompare;
+  function rcompare(a, b, loose) {
+    return compare(b, a, loose);
+  }
+  
+  exports.sort = sort;
+  function sort(list, loose) {
+    return list.sort(function (a, b) {
+      return exports.compare(a, b, loose);
+    });
+  }
+  
+  exports.rsort = rsort;
+  function rsort(list, loose) {
+    return list.sort(function (a, b) {
+      return exports.rcompare(a, b, loose);
+    });
+  }
+  
+  exports.gt = gt;
+  function gt(a, b, loose) {
+    return compare(a, b, loose) > 0;
+  }
+  
+  exports.lt = lt;
+  function lt(a, b, loose) {
+    return compare(a, b, loose) < 0;
+  }
+  
+  exports.eq = eq;
+  function eq(a, b, loose) {
+    return compare(a, b, loose) === 0;
+  }
+  
+  exports.neq = neq;
+  function neq(a, b, loose) {
+    return compare(a, b, loose) !== 0;
+  }
+  
+  exports.gte = gte;
+  function gte(a, b, loose) {
+    return compare(a, b, loose) >= 0;
+  }
+  
+  exports.lte = lte;
+  function lte(a, b, loose) {
+    return compare(a, b, loose) <= 0;
+  }
+  
+  exports.cmp = cmp;
+  function cmp(a, op, b, loose) {
+    var ret;
+    switch (op) {
+      case '===':
+        if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) === 'object') a = a.version;
+        if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) === 'object') b = b.version;
+        ret = a === b;
+        break;
+      case '!==':
+        if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) === 'object') a = a.version;
+        if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) === 'object') b = b.version;
+        ret = a !== b;
+        break;
+      case '':case '=':case '==':
+        ret = eq(a, b, loose);break;
+      case '!=':
+        ret = neq(a, b, loose);break;
+      case '>':
+        ret = gt(a, b, loose);break;
+      case '>=':
+        ret = gte(a, b, loose);break;
+      case '<':
+        ret = lt(a, b, loose);break;
+      case '<=':
+        ret = lte(a, b, loose);break;
+      default:
+        throw new TypeError('Invalid operator: ' + op);
+    }
+    return ret;
+  }
+  
+  exports.Comparator = Comparator;
+  function Comparator(comp, loose) {
+    if (comp instanceof Comparator) {
+      if (comp.loose === loose) return comp;else comp = comp.value;
+    }
+  
+    if (!(this instanceof Comparator)) return new Comparator(comp, loose);
+  
+    debug('comparator', comp, loose);
+    this.loose = loose;
+    this.parse(comp);
+  
+    if (this.semver === ANY) this.value = '';else this.value = this.operator + this.semver.version;
+  
+    debug('comp', this);
+  }
+  
+  var ANY = {};
+  Comparator.prototype.parse = function (comp) {
+    var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
+    var m = comp.match(r);
+  
+    if (!m) throw new TypeError('Invalid comparator: ' + comp);
+  
+    this.operator = m[1];
+    if (this.operator === '=') this.operator = '';
+  
+    // if it literally is just '>' or '' then allow anything.
+    if (!m[2]) this.semver = ANY;else this.semver = new SemVer(m[2], this.loose);
+  };
+  
+  Comparator.prototype.toString = function () {
+    return this.value;
+  };
+  
+  Comparator.prototype.test = function (version) {
+    debug('Comparator.test', version, this.loose);
+  
+    if (this.semver === ANY) return true;
+  
+    if (typeof version === 'string') version = new SemVer(version, this.loose);
+  
+    return cmp(version, this.operator, this.semver, this.loose);
+  };
+  
+  exports.Range = Range;
+  function Range(range, loose) {
+    if (range instanceof Range && range.loose === loose) return range;
+  
+    if (!(this instanceof Range)) return new Range(range, loose);
+  
+    this.loose = loose;
+  
+    // First, split based on boolean or ||
+    this.raw = range;
+    this.set = range.split(/\s*\|\|\s*/).map(function (range) {
+      return this.parseRange(range.trim());
+    }, this).filter(function (c) {
+      // throw out any that are not relevant for whatever reason
+      return c.length;
+    });
+  
+    if (!this.set.length) {
+      throw new TypeError('Invalid SemVer Range: ' + range);
+    }
+  
+    this.format();
+  }
+  
+  Range.prototype.format = function () {
+    this.range = this.set.map(function (comps) {
+      return comps.join(' ').trim();
+    }).join('||').trim();
+    return this.range;
+  };
+  
+  Range.prototype.toString = function () {
+    return this.range;
+  };
+  
+  Range.prototype.parseRange = function (range) {
+    var loose = this.loose;
+    range = range.trim();
+    debug('range', range, loose);
+    // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
+    var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
+    range = range.replace(hr, hyphenReplace);
+    debug('hyphen replace', range);
+    // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
+    range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace);
+    debug('comparator trim', range, re[COMPARATORTRIM]);
+  
+    // `~ 1.2.3` => `~1.2.3`
+    range = range.replace(re[TILDETRIM], tildeTrimReplace);
+  
+    // `^ 1.2.3` => `^1.2.3`
+    range = range.replace(re[CARETTRIM], caretTrimReplace);
+  
+    // normalize spaces
+    range = range.split(/\s+/).join(' ');
+  
+    // At this point, the range is completely trimmed and
+    // ready to be split into comparators.
+  
+    var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
+    var set = range.split(' ').map(function (comp) {
+      return parseComparator(comp, loose);
+    }).join(' ').split(/\s+/);
+    if (this.loose) {
+      // in loose mode, throw out any that are not valid comparators
+      set = set.filter(function (comp) {
+        return !!comp.match(compRe);
+      });
+    }
+    set = set.map(function (comp) {
+      return new Comparator(comp, loose);
+    });
+  
+    return set;
+  };
+  
+  // Mostly just for testing and legacy API reasons
+  exports.toComparators = toComparators;
+  function toComparators(range, loose) {
+    return new Range(range, loose).set.map(function (comp) {
+      return comp.map(function (c) {
+        return c.value;
+      }).join(' ').trim().split(' ');
+    });
+  }
+  
+  // comprised of xranges, tildes, stars, and gtlt's at this point.
+  // already replaced the hyphen ranges
+  // turn into a set of JUST comparators.
+  function parseComparator(comp, loose) {
+    debug('comp', comp);
+    comp = replaceCarets(comp, loose);
+    debug('caret', comp);
+    comp = replaceTildes(comp, loose);
+    debug('tildes', comp);
+    comp = replaceXRanges(comp, loose);
+    debug('xrange', comp);
+    comp = replaceStars(comp, loose);
+    debug('stars', comp);
+    return comp;
+  }
+  
+  function isX(id) {
+    return !id || id.toLowerCase() === 'x' || id === '*';
+  }
+  
+  // ~, ~> --> * (any, kinda silly)
+  // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
+  // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
+  // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
+  // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
+  // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
+  function replaceTildes(comp, loose) {
+    return comp.trim().split(/\s+/).map(function (comp) {
+      return replaceTilde(comp, loose);
+    }).join(' ');
+  }
+  
+  function replaceTilde(comp, loose) {
+    var r = loose ? re[TILDELOOSE] : re[TILDE];
+    return comp.replace(r, function (_, M, m, p, pr) {
+      debug('tilde', comp, _, M, m, p, pr);
+      var ret;
+  
+      if (isX(M)) ret = '';else if (isX(m)) ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';else if (isX(p))
+        // ~1.2 == >=1.2.0- <1.3.0-
+        ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';else if (pr) {
+        debug('replaceTilde pr', pr);
+        if (pr.charAt(0) !== '-') pr = '-' + pr;
+        ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + M + '.' + (+m + 1) + '.0';
+      } else
+        // ~1.2.3 == >=1.2.3 <1.3.0
+        ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0';
+  
+      debug('tilde return', ret);
+      return ret;
+    });
+  }
+  
+  // ^ --> * (any, kinda silly)
+  // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
+  // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
+  // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
+  // ^1.2.3 --> >=1.2.3 <2.0.0
+  // ^1.2.0 --> >=1.2.0 <2.0.0
+  function replaceCarets(comp, loose) {
+    return comp.trim().split(/\s+/).map(function (comp) {
+      return replaceCaret(comp, loose);
+    }).join(' ');
+  }
+  
+  function replaceCaret(comp, loose) {
+    debug('caret', comp, loose);
+    var r = loose ? re[CARETLOOSE] : re[CARET];
+    return comp.replace(r, function (_, M, m, p, pr) {
+      debug('caret', comp, _, M, m, p, pr);
+      var ret;
+  
+      if (isX(M)) ret = '';else if (isX(m)) ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';else if (isX(p)) {
+        if (M === '0') ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';else ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0';
+      } else if (pr) {
+        debug('replaceCaret pr', pr);
+        if (pr.charAt(0) !== '-') pr = '-' + pr;
+        if (M === '0') {
+          if (m === '0') ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + M + '.' + m + '.' + (+p + 1);else ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + M + '.' + (+m + 1) + '.0';
+        } else ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + (+M + 1) + '.0.0';
+      } else {
+        debug('no pr');
+        if (M === '0') {
+          if (m === '0') ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + m + '.' + (+p + 1);else ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0';
+        } else ret = '>=' + M + '.' + m + '.' + p + ' <' + (+M + 1) + '.0.0';
+      }
+  
+      debug('caret return', ret);
+      return ret;
+    });
+  }
+  
+  function replaceXRanges(comp, loose) {
+    debug('replaceXRanges', comp, loose);
+    return comp.split(/\s+/).map(function (comp) {
+      return replaceXRange(comp, loose);
+    }).join(' ');
+  }
+  
+  function replaceXRange(comp, loose) {
+    comp = comp.trim();
+    var r = loose ? re[XRANGELOOSE] : re[XRANGE];
+    return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
+      debug('xRange', comp, ret, gtlt, M, m, p, pr);
+      var xM = isX(M);
+      var xm = xM || isX(m);
+      var xp = xm || isX(p);
+      var anyX = xp;
+  
+      if (gtlt === '=' && anyX) gtlt = '';
+  
+      if (xM) {
+        if (gtlt === '>' || gtlt === '<') {
+          // nothing is allowed
+          ret = '<0.0.0';
+        } else {
+          // nothing is forbidden
+          ret = '*';
+        }
+      } else if (gtlt && anyX) {
+        // replace X with 0
+        if (xm) m = 0;
+        if (xp) p = 0;
+  
+        if (gtlt === '>') {
+          // >1 => >=2.0.0
+          // >1.2 => >=1.3.0
+          // >1.2.3 => >= 1.2.4
+          gtlt = '>=';
+          if (xm) {
+            M = +M + 1;
+            m = 0;
+            p = 0;
+          } else if (xp) {
+            m = +m + 1;
+            p = 0;
+          }
+        } else if (gtlt === '<=') {
+          // <=0.7.x is actually <0.8.0, since any 0.7.x should
+          // pass.  Similarly, <=7.x is actually <8.0.0, etc.
+          gtlt = '<';
+          if (xm) M = +M + 1;else m = +m + 1;
+        }
+  
+        ret = gtlt + M + '.' + m + '.' + p;
+      } else if (xm) {
+        ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
+      } else if (xp) {
+        ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
+      }
+  
+      debug('xRange return', ret);
+  
+      return ret;
+    });
+  }
+  
+  // Because * is AND-ed with everything else in the comparator,
+  // and '' means "any version", just remove the *s entirely.
+  function replaceStars(comp, loose) {
+    debug('replaceStars', comp, loose);
+    // Looseness is ignored here.  star is always as loose as it gets!
+    return comp.trim().replace(re[STAR], '');
+  }
+  
+  // This function is passed to string.replace(re[HYPHENRANGE])
+  // M, m, patch, prerelease, build
+  // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
+  // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
+  // 1.2 - 3.4 => >=1.2.0 <3.5.0
+  function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) {
+  
+    if (isX(fM)) from = '';else if (isX(fm)) from = '>=' + fM + '.0.0';else if (isX(fp)) from = '>=' + fM + '.' + fm + '.0';else from = '>=' + from;
+  
+    if (isX(tM)) to = '';else if (isX(tm)) to = '<' + (+tM + 1) + '.0.0';else if (isX(tp)) to = '<' + tM + '.' + (+tm + 1) + '.0';else if (tpr) to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr;else to = '<=' + to;
+  
+    return (from + ' ' + to).trim();
+  }
+  
+  // if ANY of the sets match ALL of its comparators, then pass
+  Range.prototype.test = function (version) {
+    if (!version) return false;
+  
+    if (typeof version === 'string') version = new SemVer(version, this.loose);
+  
+    for (var i = 0; i < this.set.length; i++) {
+      if (testSet(this.set[i], version)) return true;
+    }
+    return false;
+  };
+  
+  function testSet(set, version) {
+    for (var i = 0; i < set.length; i++) {
+      if (!set[i].test(version)) return false;
+    }
+  
+    if (version.prerelease.length) {
+      // Find the set of versions that are allowed to have prereleases
+      // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
+      // That should allow `1.2.3-pr.2` to pass.
+      // However, `1.2.4-alpha.notready` should NOT be allowed,
+      // even though it's within the range set by the comparators.
+      for (var i = 0; i < set.length; i++) {
+        debug(set[i].semver);
+        if (set[i].semver === ANY) continue;
+  
+        if (set[i].semver.prerelease.length > 0) {
+          var allowed = set[i].semver;
+          if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) return true;
+        }
+      }
+  
+      // Version has a -pre, but it's not one of the ones we like.
+      return false;
+    }
+  
+    return true;
+  }
+  
+  exports.satisfies = satisfies;
+  function satisfies(version, range, loose) {
+    try {
+      range = new Range(range, loose);
+    } catch (er) {
+      return false;
+    }
+    return range.test(version);
+  }
+  
+  exports.maxSatisfying = maxSatisfying;
+  function maxSatisfying(versions, range, loose) {
+    return versions.filter(function (version) {
+      return satisfies(version, range, loose);
+    }).sort(function (a, b) {
+      return rcompare(a, b, loose);
+    })[0] || null;
+  }
+  
+  exports.validRange = validRange;
+  function validRange(range, loose) {
+    try {
+      // Return '*' instead of '' so that truthiness works.
+      // This will throw if it's invalid anyway
+      return new Range(range, loose).range || '*';
+    } catch (er) {
+      return null;
+    }
+  }
+  
+  // Determine if version is less than all the versions possible in the range
+  exports.ltr = ltr;
+  function ltr(version, range, loose) {
+    return outside(version, range, '<', loose);
+  }
+  
+  // Determine if version is greater than all the versions possible in the range.
+  exports.gtr = gtr;
+  function gtr(version, range, loose) {
+    return outside(version, range, '>', loose);
+  }
+  
+  exports.outside = outside;
+  function outside(version, range, hilo, loose) {
+    version = new SemVer(version, loose);
+    range = new Range(range, loose);
+  
+    var gtfn, ltefn, ltfn, comp, ecomp;
+    switch (hilo) {
+      case '>':
+        gtfn = gt;
+        ltefn = lte;
+        ltfn = lt;
+        comp = '>';
+        ecomp = '>=';
+        break;
+      case '<':
+        gtfn = lt;
+        ltefn = gte;
+        ltfn = gt;
+        comp = '<';
+        ecomp = '<=';
+        break;
+      default:
+        throw new TypeError('Must provide a hilo val of "<" or ">"');
+    }
+  
+    // If it satisifes the range it is not outside
+    if (satisfies(version, range, loose)) {
+      return false;
+    }
+  
+    // From now on, variable terms are as if we're in "gtr" mode.
+    // but note that everything is flipped for the "ltr" function.
+  
+    for (var i = 0; i < range.set.length; ++i) {
+      var comparators = range.set[i];
+  
+      var high = null;
+      var low = null;
+  
+      comparators.forEach(function (comparator) {
+        if (comparator.semver === ANY) {
+          comparator = new Comparator('>=0.0.0');
+        }
+        high = high || comparator;
+        low = low || comparator;
+        if (gtfn(comparator.semver, high.semver, loose)) {
+          high = comparator;
+        } else if (ltfn(comparator.semver, low.semver, loose)) {
+          low = comparator;
+        }
+      });
+  
+      // If the edge version comparator has a operator then our version
+      // isn't outside it
+      if (high.operator === comp || high.operator === ecomp) {
+        return false;
+      }
+  
+      // If the lowest version comparator has an operator and our version
+      // is less than it then it isn't higher than the range
+      if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) {
+        return false;
+      } else if (low.operator === ecomp && ltfn(version, low.semver)) {
+        return false;
+      }
+    }
+    return true;
+  }
+  /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(84)))
+
+/***/ },
+/* 84 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  // shim for using process in browser
+  
+  var process = module.exports = {};
+  var queue = [];
+  var draining = false;
+  var currentQueue;
+  var queueIndex = -1;
+  
+  function cleanUpNextTick() {
+      draining = false;
+      if (currentQueue.length) {
+          queue = currentQueue.concat(queue);
+      } else {
+          queueIndex = -1;
+      }
+      if (queue.length) {
+          drainQueue();
+      }
+  }
+  
+  function drainQueue() {
+      if (draining) {
+          return;
+      }
+      var timeout = setTimeout(cleanUpNextTick);
+      draining = true;
+  
+      var len = queue.length;
+      while (len) {
+          currentQueue = queue;
+          queue = [];
+          while (++queueIndex < len) {
+              if (currentQueue) {
+                  currentQueue[queueIndex].run();
+              }
+          }
+          queueIndex = -1;
+          len = queue.length;
+      }
+      currentQueue = null;
+      draining = false;
+      clearTimeout(timeout);
+  }
+  
+  process.nextTick = function (fun) {
+      var args = new Array(arguments.length - 1);
+      if (arguments.length > 1) {
+          for (var i = 1; i < arguments.length; i++) {
+              args[i - 1] = arguments[i];
+          }
+      }
+      queue.push(new Item(fun, args));
+      if (queue.length === 1 && !draining) {
+          setTimeout(drainQueue, 0);
+      }
+  };
+  
+  // v8 likes predictible objects
+  function Item(fun, array) {
+      this.fun = fun;
+      this.array = array;
+  }
+  Item.prototype.run = function () {
+      this.fun.apply(null, this.array);
+  };
+  process.title = 'browser';
+  process.browser = true;
+  process.env = {};
+  process.argv = [];
+  process.version = ''; // empty string to avoid regexp issues
+  process.versions = {};
+  
+  function noop() {}
+  
+  process.on = noop;
+  process.addListener = noop;
+  process.once = noop;
+  process.off = noop;
+  process.removeListener = noop;
+  process.removeAllListeners = noop;
+  process.emit = noop;
+  
+  process.binding = function (name) {
+      throw new Error('process.binding is not supported');
+  };
+  
+  process.cwd = function () {
+      return '/';
+  };
+  process.chdir = function (dir) {
+      throw new Error('process.chdir is not supported');
+  };
+  process.umask = function () {
+      return 0;
+  };
+
+/***/ },
+/* 85 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.default = Vm;
+  
+  var _util = __webpack_require__(81);
+  
+  var _scope = __webpack_require__(86);
+  
+  var scope = _interopRequireWildcard(_scope);
+  
+  var _compiler = __webpack_require__(93);
+  
+  var compiler = _interopRequireWildcard(_compiler);
+  
+  var _directive = __webpack_require__(94);
+  
+  var directive = _interopRequireWildcard(_directive);
+  
+  var _domHelper = __webpack_require__(96);
+  
+  var domHelper = _interopRequireWildcard(_domHelper);
+  
+  var _events = __webpack_require__(97);
+  
+  var events = _interopRequireWildcard(_events);
+  
+  var _register = __webpack_require__(98);
+  
+  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+  
+  function callOldReadyEntry(vm, component) {
+    if (component.methods && component.methods.ready) {
+      component.methods.ready.call(vm);
+    }
+  }
+  
+  /**
+   * ViewModel constructor
+   *
+   * @param {string} type
+   * @param {object} parentVm   which contains _app
+   * @param {object} parentEl   root element or frag block
+   * @param {object} mergedData external data
+   * @param {object} externalEvents external events
+   */
+  
+  // import * as modules from './../api/modules'
+  // import * as api from './../api/api'
+  
+  /**
+   * @fileOverview
+   * ViewModel Constructor & definition
+   */
+  
+  function Vm(type, parentVm, parentEl, mergedData, externalEvents) {
+    this._parent = parentVm._realParent ? parentVm._realParent : parentVm;
+    this._app = parentVm._app;
+    parentVm._childrenVms && parentVm._childrenVms.push(this);
+  
+    var component = this._app.customComponentMap[type] || {};
+    var data = component.data || {};
+  
+    this._options = component;
+    this._methods = component.methods || {};
+    this._computed = component.computed || {};
+    this._css = component.style || {};
+    this._ids = {};
+    this._watchers = [];
+    this._vmEvents = {};
+    this._childrenVms = [];
+    this._type = type;
+  
+    // bind events and lifecycles
+    this._initEvents(externalEvents);
+  
+    this.$emit('hook:init');
+    this._inited = true;
+    // proxy data and methods
+    // observe data and add this to vms
+    this._data = typeof data === 'function' ? data() : data;
+    if (mergedData) {
+      (0, _util.extend)(this._data, mergedData);
+    }
+    this._initScope();
+  
+    this.$emit('hook:created');
+    this._created = true;
+    // backward old ready entry
+    callOldReadyEntry(this, component);
+  
+    // if no parentElement then specify the documentElement
+    this._parentEl = parentEl || this._app.doc.documentElement;
+    this._build();
+  }
+  
+  (0, _util.extend)(Vm.prototype, scope, compiler, directive, domHelper, events);
+  (0, _util.extend)(Vm, {
+    registerModules: _register.registerModules,
+    registerMethods: _register.registerMethods
+  });
+  // Vm.registerModules(modules)
+
+/***/ },
+/* 86 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var _ = __webpack_require__(87);
+  var Observer = __webpack_require__(88);
+  var Dep = __webpack_require__(90);
+  
+  /**
+   * Setup the scope of an instance, which contains:
+   * - observed data
+   * - computed properties
+   * - user methods
+   * - meta properties
+   */
+  
+  exports._initScope = function () {
+    this._initData();
+    this._initComputed();
+    this._initMethods();
+    // this._initMeta()
+  };
+  
+  /**
+   * Initialize the data. 
+   */
+  
+  exports._initData = function () {
+    // proxy data on instance
+    var data = this._data;
+    var i, key;
+    // // make sure all props properties are observed
+    // var props = this.$options.props
+    // if (props) {
+    //   i = props.length
+    //   while (i--) {
+    //     key = _.camelize(props[i])
+    //     if (!(key in data)) {
+    //       data[key] = null
+    //     }
+    //   }
+    // }
+    var keys = Object.keys(data);
+    i = keys.length;
+    while (i--) {
+      key = keys[i];
+      if (!_.isReserved(key)) {
+        this._proxy(key);
+      }
+    }
+    // observe data
+    Observer.create(data).addVm(this);
+  };
+  
+  // /**
+  //  * Swap the isntance's $data. Called in $data's setter.
+  //  *
+  //  * @param {Object} newData
+  //  */
+  
+  // exports._setData = function (newData) {
+  //   newData = newData || {}
+  //   var oldData = this._data
+  //   this._data = newData
+  //   var keys, key, i
+  //   // unproxy keys not present in new data
+  //   keys = Object.keys(oldData)
+  //   i = keys.length
+  //   while (i--) {
+  //     key = keys[i]
+  //     if (!_.isReserved(key) && !(key in newData)) {
+  //       this._unproxy(key)
+  //     }
+  //   }
+  //   // proxy keys not already proxied,
+  //   // and trigger change for changed values
+  //   keys = Object.keys(newData)
+  //   i = keys.length
+  //   while (i--) {
+  //     key = keys[i]
+  //     if (!this.hasOwnProperty(key) && !_.isReserved(key)) {
+  //       // new property
+  //       this._proxy(key)
+  //     }
+  //   }
+  //   oldData.__ob__.removeVm(this)
+  //   Observer.create(newData).addVm(this)
+  //   this._digest()
+  // }
+  
+  /**
+   * Proxy a property, so that
+   * vm.prop === vm._data.prop
+   *
+   * @param {String} key
+   */
+  
+  exports._proxy = function (key) {
+    // need to store ref to self here
+    // because these getter/setters might
+    // be called by child instances!
+    var self = this;
+    Object.defineProperty(self, key, {
+      configurable: true,
+      enumerable: true,
+      get: function proxyGetter() {
+        return self._data[key];
+      },
+      set: function proxySetter(val) {
+        self._data[key] = val;
+      }
+    });
+  };
+  
+  /**
+   * Unproxy a property.
+   *
+   * @param {String} key
+   */
+  
+  exports._unproxy = function (key) {
+    delete this[key];
+  };
+  
+  // /**
+  //  * Force update on every watcher in scope.
+  //  */
+  
+  // exports._digest = function () {
+  //   var i = this._watchers.length
+  //   while (i--) {
+  //     this._watchers[i].update()
+  //   }
+  //   var children = this._children
+  //   i = children.length
+  //   while (i--) {
+  //     var child = children[i]
+  //     if (child.$options.inherit) {
+  //       child._digest()
+  //     }
+  //   }
+  // }
+  
+  /**
+   * Setup computed properties. They are essentially
+   * special getter/setters
+   */
+  
+  function noop() {}
+  exports._initComputed = function () {
+    // var computed = this.$options.computed
+    var computed = this._computed;
+    if (computed) {
+      for (var key in computed) {
+        var userDef = computed[key];
+        var def = {
+          enumerable: true,
+          configurable: true
+        };
+        if (typeof userDef === 'function') {
+          def.get = _.bind(userDef, this);
+          def.set = noop;
+        } else {
+          def.get = userDef.get ? _.bind(userDef.get, this) : noop;
+          def.set = userDef.set ? _.bind(userDef.set, this) : noop;
+        }
+        Object.defineProperty(this, key, def);
+      }
+    }
+  };
+  
+  /**
+   * Setup instance methods. Methods must be bound to the
+   * instance since they might be called by children
+   * inheriting them.
+   */
+  
+  exports._initMethods = function () {
+    // var methods = this.$options.methods
+    var methods = this._methods;
+    if (methods) {
+      for (var key in methods) {
+        this[key] = _.bind(methods[key], this);
+      }
+    }
+  };
+  
+  // /**
+  //  * Initialize meta information like $index, $key & $value.
+  //  */
+
+  // exports._initMeta = function () {
+  //   var metas = this.$options._meta
+  //   if (metas) {
+  //     for (var key in metas) {
+  //       this._defineMeta(key, metas[key])
+  //     }
+  //   }
+  // }
+
+  // /**
+  //  * Define a meta property, e.g $index, $key, $value
+  //  * which only exists on the vm instance but not in $data.
+  //  *
+  //  * @param {String} key
+  //  * @param {*} value
+  //  */
+
+  // exports._defineMeta = function (key, value) {
+  //   var dep = new Dep()
+  //   Object.defineProperty(this, key, {
+  //     enumerable: true,
+  //     configurable: true,
+  //     get: function metaGetter () {
+  //       if (Observer.target) {
+  //         Observer.target.addDep(dep)
+  //       }
+  //       return value
+  //     },
+  //     set: function metaSetter (val) {
+  //       if (val !== value) {
+  //         value = val
+  //         dep.notify()
+  //       }
+  //     }
+  //   })
+  // }
+
+/***/ },
+/* 87 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  // required for code in instance/observer
+  module.exports = __webpack_require__(81);
+
+/***/ },
+/* 88 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var _ = __webpack_require__(87);
+  var config = __webpack_require__(89);
+  var Dep = __webpack_require__(90);
+  var arrayMethods = __webpack_require__(91);
+  var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
+  __webpack_require__(92);
+  
+  var uid = 0;
+  
+  /**
+   * Type enums
+   */
+  
+  var ARRAY = 0;
+  var OBJECT = 1;
+  
+  /**
+   * Augment an target Object or Array by intercepting
+   * the prototype chain using __proto__
+   *
+   * @param {Object|Array} target
+   * @param {Object} proto
+   */
+  
+  function protoAugment(target, src) {
+    target.__proto__ = src;
+  }
+  
+  /**
+   * Augment an target Object or Array by defining
+   * hidden properties.
+   *
+   * @param {Object|Array} target
+   * @param {Object} proto
+   */
+  
+  function copyAugment(target, src, keys) {
+    var i = keys.length;
+    var key;
+    while (i--) {
+      key = keys[i];
+      _.define(target, key, src[key]);
+    }
+  }
+  
+  /**
+   * Observer class that are attached to each observed
+   * object. Once attached, the observer converts target
+   * object's property keys into getter/setters that
+   * collect dependencies and dispatches updates.
+   *
+   * @param {Array|Object} value
+   * @param {Number} type
+   * @constructor
+   */
+  
+  function Observer(value, type) {
+    this.id = ++uid;
+    this.value = value;
+    this.active = true;
+    this.deps = [];
+    _.define(value, '__ob__', this);
+    if (type === ARRAY) {
+      var augment = config.proto && _.hasProto ? protoAugment : copyAugment;
+      augment(value, arrayMethods, arrayKeys);
+      this.observeArray(value);
+    } else if (type === OBJECT) {
+      this.walk(value);
+    }
+  }
+  
+  Observer.target = null;
+  
+  var p = Observer.prototype;
+  
+  /**
+   * Attempt to create an observer instance for a value,
+   * returns the new observer if successfully observed,
+   * or the existing observer if the value already has one.
+   *
+   * @param {*} value
+   * @return {Observer|undefined}
+   * @static
+   */
+  
+  Observer.create = function (value) {
+    if (value && value.hasOwnProperty('__ob__') && value.__ob__ instanceof Observer) {
+      return value.__ob__;
+    } else if (_.isArray(value)) {
+      return new Observer(value, ARRAY);
+    } else if (_.isPlainObject(value) && !value._isVue // avoid Vue instance
+    ) {
+        return new Observer(value, OBJECT);
+      }
+  };
+  
+  /**
+   * Walk through each property and convert them into
+   * getter/setters. This method should only be called when
+   * value type is Object. Properties prefixed with `$` or `_`
+   * and accessor properties are ignored.
+   *
+   * @param {Object} obj
+   */
+  
+  p.walk = function (obj) {
+    var keys = Object.keys(obj);
+    var i = keys.length;
+    var key, prefix;
+    while (i--) {
+      key = keys[i];
+      prefix = key.charCodeAt(0);
+      if (prefix !== 0x24 && prefix !== 0x5F) {
+        // skip $ or _
+        this.convert(key, obj[key]);
+      }
+    }
+  };
+  
+  /**
+   * Try to carete an observer for a child value,
+   * and if value is array, link dep to the array.
+   *
+   * @param {*} val
+   * @return {Dep|undefined}
+   */
+  
+  p.observe = function (val) {
+    return Observer.create(val);
+  };
+  
+  /**
+   * Observe a list of Array items.
+   *
+   * @param {Array} items
+   */
+  
+  p.observeArray = function (items) {
+    var i = items.length;
+    while (i--) {
+      this.observe(items[i]);
+    }
+  };
+  
+  /**
+   * Convert a property into getter/setter so we can emit
+   * the events when the property is accessed/changed.
+   *
+   * @param {String} key
+   * @param {*} val
+   */
+  
+  p.convert = function (key, val) {
+    var ob = this;
+    var childOb = ob.observe(val);
+    var dep = new Dep();
+    if (childOb) {
+      childOb.deps.push(dep);
+    }
+    Object.defineProperty(ob.value, key, {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        // Observer.target is a watcher whose getter is
+        // currently being evaluated.
+        if (ob.active && Observer.target) {
+          Observer.target.addDep(dep);
+        }
+        return val;
+      },
+      set: function set(newVal) {
+        if (newVal === val) return;
+        // remove dep from old value
+        var oldChildOb = val && val.__ob__;
+        if (oldChildOb) {
+          oldChildOb.deps.$remove(dep);
+        }
+        val = newVal;
+        // add dep to new value
+        var newChildOb = ob.observe(newVal);
+        if (newChildOb) {
+          newChildOb.deps.push(dep);
+        }
+        dep.notify();
+      }
+    });
+  };
+  
+  /**
+   * Notify change on all self deps on an observer.
+   * This is called when a mutable value mutates. e.g.
+   * when an Array's mutating methods are called, or an
+   * Object's $add/$delete are called.
+   */
+  
+  p.notify = function () {
+    var deps = this.deps;
+    for (var i = 0, l = deps.length; i < l; i++) {
+      deps[i].notify();
+    }
+  };
+  
+  /**
+   * Add an owner vm, so that when $add/$delete mutations
+   * happen we can notify owner vms to proxy the keys and
+   * digest the watchers. This is only called when the object
+   * is observed as an instance's root $data.
+   *
+   * @param {Vue} vm
+   */
+  
+  p.addVm = function (vm) {
+    (this.vms = this.vms || []).push(vm);
+  };
+  
+  /**
+   * Remove an owner vm. This is called when the object is
+   * swapped out as an instance's $data object.
+   *
+   * @param {Vue} vm
+   */
+  
+  p.removeVm = function (vm) {
+    this.vms.$remove(vm);
+  };
+  
+  module.exports = Observer;
+
+/***/ },
+/* 89 */
+/***/ function(module, exports) {
+
+  "use strict";
+  
+  module.exports = { proto: true };
+
+/***/ },
+/* 90 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var _ = __webpack_require__(87);
+  
+  /**
+   * A dep is an observable that can have multiple
+   * directives subscribing to it.
+   *
+   * @constructor
+   */
+  
+  function Dep() {
+    this.subs = [];
+  }
+  
+  var p = Dep.prototype;
+  
+  /**
+   * Add a directive subscriber.
+   *
+   * @param {Directive} sub
+   */
+  
+  p.addSub = function (sub) {
+    this.subs.push(sub);
+  };
+  
+  /**
+   * Remove a directive subscriber.
+   *
+   * @param {Directive} sub
+   */
+  
+  p.removeSub = function (sub) {
+    this.subs.$remove(sub);
+  };
+  
+  /**
+   * Notify all subscribers of a new value.
+   */
+  
+  p.notify = function () {
+    // stablize the subscriber list first
+    var subs = _.toArray(this.subs);
+    for (var i = 0, l = subs.length; i < l; i++) {
+      subs[i].update();
+    }
+  };
+  
+  module.exports = Dep;
+
+/***/ },
+/* 91 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var _ = __webpack_require__(87);
+  var arrayProto = Array.prototype;
+  var arrayMethods = Object.create(arrayProto)
+  
+  /**
+   * Intercept mutating methods and emit events
+   */
+  
+  ;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
+    // cache original method
+    var original = arrayProto[method];
+    _.define(arrayMethods, method, function mutator() {
+      // avoid leaking arguments:
+      // http://jsperf.com/closure-with-arguments
+      var i = arguments.length;
+      var args = new Array(i);
+      while (i--) {
+        args[i] = arguments[i];
+      }
+      var result = original.apply(this, args);
+      var ob = this.__ob__;
+      var inserted;
+      switch (method) {
+        case 'push':
+          inserted = args;
+          break;
+        case 'unshift':
+          inserted = args;
+          break;
+        case 'splice':
+          inserted = args.slice(2);
+          break;
+      }
+      if (inserted) ob.observeArray(inserted);
+      // notify change
+      ob.notify();
+      return result;
+    });
+  });
+  
+  /**
+   * Swap the element at the given index with a new value
+   * and emits corresponding event.
+   *
+   * @param {Number} index
+   * @param {*} val
+   * @return {*} - replaced element
+   */
+  
+  _.define(arrayProto, '$set', function $set(index, val) {
+    if (index >= this.length) {
+      this.length = index + 1;
+    }
+    return this.splice(index, 1, val)[0];
+  });
+  
+  /**
+   * Convenience method to remove the element at given index.
+   *
+   * @param {Number} index
+   * @param {*} val
+   */
+  
+  _.define(arrayProto, '$remove', function $remove(index) {
+    /* istanbul ignore if */
+    if (!this.length) return;
+    if (typeof index !== 'number') {
+      index = _.indexOf(this, index);
+    }
+    if (index > -1) {
+      this.splice(index, 1);
+    }
+  });
+  
+  module.exports = arrayMethods;
+
+/***/ },
+/* 92 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  var _ = __webpack_require__(87);
+  var objProto = Object.prototype;
+  
+  /**
+   * Add a new property to an observed object
+   * and emits corresponding event
+   *
+   * @param {String} key
+   * @param {*} val
+   * @public
+   */
+  
+  _.define(objProto, '$add', function $add(key, val) {
+    if (this.hasOwnProperty(key)) return;
+    var ob = this.__ob__;
+    if (!ob || _.isReserved(key)) {
+      this[key] = val;
+      return;
+    }
+    ob.convert(key, val);
+    ob.notify();
+    if (ob.vms) {
+      var i = ob.vms.length;
+      while (i--) {
+        var vm = ob.vms[i];
+        vm._proxy(key);
+        // vm._digest() // todo
+      }
+    }
+  });
+  
+  /**
+   * Set a property on an observed object, calling add to
+   * ensure the property is observed.
+   *
+   * @param {String} key
+   * @param {*} val
+   * @public
+   */
+  
+  _.define(objProto, '$set', function $set(key, val) {
+    this.$add(key, val);
+    this[key] = val;
+  });
+  
+  /**
+   * Deletes a property from an observed object
+   * and emits corresponding event
+   *
+   * @param {String} key
+   * @public
+   */
+  
+  _.define(objProto, '$delete', function $delete(key) {
+    if (!this.hasOwnProperty(key)) return;
+    delete this[key];
+    var ob = this.__ob__;
+    if (!ob || _.isReserved(key)) {
+      return;
+    }
+    ob.notify();
+    if (ob.vms) {
+      var i = ob.vms.length;
+      while (i--) {
+        var vm = ob.vms[i];
+        vm._unproxy(key);
+        // vm._digest() // todo
+      }
+    }
+  });
+
+/***/ },
+/* 93 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  
+  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
+  
+  exports._build = _build;
+  exports._generate = _generate;
+  exports._generateElement = _generateElement;
+  exports._setChildren = _setChildren;
+  exports._checkRepeat = _checkRepeat;
+  exports._checkDisplay = _checkDisplay;
+  exports._watchBlock = _watchBlock;
+  exports._mergeContext = _mergeContext;
+  /**
+  * @fileOverview
+  * ViewModel template parser & data-binding process
+  *
+  * required:
+  * index.js: Vm
+  * dom-helper.js: _createElement, _createBlock
+  * dom-helper.js: _attachTarget, _moveTarget, _removeTarget
+  * directive.js: _bindElement, _bindSubVm, _watch
+  * events.js: $on
+  */
+  
+  /**
+   * build(externalDirs)
+   *   createVm()
+   *   merge(externalDirs, dirs)
+   *   generate(template, parentNode)
+   *     if (type is content) create contentNode
+   *     else if (dirs have v-for) foreach -> create context
+   *       -> generate(templateWithoutFor, parentNode): diff(list) onchange
+   *     else if (dirs have v-if) assert
+   *       -> generate(templateWithoutIf, parentNode): toggle(shown) onchange
+   *     else if (type is native)
+   *       set(dirs): update(id/attr/style/class) onchange
+   *       append(template, parentNode)
+   *       foreach childNodes -> generate(childNode, template)
+   *     else if (type is custom)
+   *       addChildVm(vm, parentVm)
+   *       build(externalDirs)
+   *       foreach childNodes -> generate(childNode, template)
+   */
+  function _build() {
+    var opt = this._options || {};
+    var template = opt.template || {};
+  
+    if (opt.replace) {
+      if (template.children && template.children.length === 1) {
+        this._generate(template.children[0], this._parentEl);
+      } else {
+        this._generate(template.children, this._parentEl);
+      }
+    } else {
+      this._generate(template, this._parentEl);
+    }
+  
+    this.$emit('hook:ready');
+    this._ready = true;
+  }
+  
+  /**
+   * Generate elements by child or children and append to parent elements.
+   * Root element info would be merged if has. The first argument may be an array
+   * if the root element with options.replace has not only one child.
+   *
+   * @param  {object|array} target
+   * @param  {object} parentEl
+   * @param  {object} context
+   */
+  function _generate(target, parentEl, context) {
+    var _this = this;
+  
+    if (Array.isArray(target)) {
+      var _ret = function () {
+        var fragBlock = _this._createBlock(parentEl);
+        target.forEach(function (child) {
+          _this._generate(child, fragBlock, context);
+        });
+        return {
+          v: void 0
+        };
+      }();
+  
+      if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
+    }
+  
+    context = context || {};
+  
+    if (target.type === 'content' || target.type === 'slot') {
+      this._content = this._createBlock(parentEl);
+      return;
+    }
+  
+    if (!context.hasOwnProperty('repeat') && target.repeat) {
+      var _ret2 = function () {
+        var list = target.repeat.call(_this);
+        var repeatId = latestRepeatId++;
+        var latestItemId = markList(list, repeatId);
+  
+        var fragBlock = _this._createBlock(parentEl);
+        fragBlock.children = [];
+        fragBlock.data = list.slice(0);
+  
+        _this._checkRepeat(target, fragBlock, repeatId, latestItemId);
+  
+        list.forEach(function (item, index) {
+          if ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object') {
+            item.INDEX = index;
+          }
+          _this._generate(target, fragBlock, { repeat: item });
+        });
+  
+        return {
+          v: void 0
+        };
+      }();
+  
+      if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v;
+    }
+  
+    var subContext = this;
+    if (context.repeat && !context.shown) {
+      subContext = this._mergeContext(context.repeat);
+    }
+  
+    if (!context.hasOwnProperty('shown') && target.shown) {
+      var display = target.shown.call(subContext);
+      var newContext = { shown: true };
+      var _fragBlock = subContext._createBlock(parentEl);
+  
+      if (parentEl.element && parentEl.children) {
+        parentEl.children.push(_fragBlock);
+      }
+  
+      if (context.repeat) {
+        newContext.repeat = context.repeat;
+      }
+  
+      _fragBlock.display = !!display;
+      subContext._checkDisplay(target, _fragBlock, newContext);
+  
+      if (display) {
+        subContext._generate(target, _fragBlock, newContext);
+      }
+  
+      return;
+    }
+  
+    var typeGetter = target.type;
+    var type = typeGetter;
+  
+    if (typeof typeGetter === 'function') {
+      type = typeGetter.call(subContext);
+  
+      if (!context.hasOwnProperty('type')) {
+        var _ret3 = function () {
+          var newContext = { type: type };
+          var fragBlock = subContext._createBlock(parentEl);
+  
+          if (parentEl.element && parentEl.children) {
+            parentEl.children.push(fragBlock);
+          }
+  
+          subContext._watch(typeGetter, function (value) {
+            subContext._removeBlock(fragBlock, true);
+            subContext._generate(target, fragBlock, { type: value });
+          });
+  
+          subContext._generate(target, fragBlock, newContext);
+  
+          return {
+            v: void 0
+          };
+        }();
+  
+        if ((typeof _ret3 === 'undefined' ? 'undefined' : _typeof(_ret3)) === "object") return _ret3.v;
+      }
+    }
+  
+    var isComponent = void 0;
+    if (this._app && this._app.customComponentMap && type) {
+      isComponent = this._app.customComponentMap[type];
+    } else {
+      isComponent = target.component;
+    }
+  
+    if (isComponent) {
+      var Vm = this.constructor;
+      var subVm = new Vm(type, subContext, parentEl, undefined, {
+        'hook:init': function hookInit() {
+          subContext._setId(target.id, null, this);
+        },
+        'hook:created': function hookCreated() {
+          subContext._bindSubVm(this, target, context.repeat);
+        },
+        'hook:ready': function hookReady() {
+          if (this._content) {
+            subContext._setChildren(target, this._content);
+          }
+        }
+      });
+      subContext._bindSubVmAfterInitialized(subVm, target);
+      return;
+    }
+  
+    var element = subContext._generateElement(type, target, parentEl);
+    var treeMode = target.append === 'tree';
+    if (!treeMode) {
+      subContext._attachTarget(element, parentEl);
+    }
+    subContext._setChildren(target, element);
+    if (treeMode) {
+      subContext._attachTarget(element, parentEl);
+    }
+  }
+  
+  /**
+   * Generate element from template and attach to the dest if needed.
+   * The time to attach depends on whether the mode status is node or tree.
+   *
+   * @param  {object} template
+   * @param  {object} dest
+   */
+  function _generateElement(type, template, dest) {
+  
+    this._applyNaitveComponentOptions(template);
+  
+    var element = void 0;
+    if (dest.ref === '_documentElement') {
+      // if its parent is documentElement then it's a body
+      element = this._createBody(type);
+    } else {
+      element = this._createElement(type);
+    }
+    // TODO it was a root element when not in a fragment
+    if (!this._rootEl) {
+      this._rootEl = element;
+    }
+  
+    this._bindElement(element, template);
+  
+    if (template.attr && template.attr.append) {
+      // backward, append prop in attr
+      element.append = template.attr.append;
+    }
+  
+    return element;
+  }
+  
+  /**
+   * Set all children to a certain parent element.
+   *
+   * @param {object} template
+   * @param {object} parentEl
+   */
+  function _setChildren(template, parentEl) {
+    var _this2 = this;
+  
+    var children = template.children;
+    if (children && children.length) {
+      children.forEach(function (child) {
+        _this2._generate(child, parentEl);
+      });
+    }
+  }
+  
+  /**
+   * Watch the list update and refresh the changes.
+   *
+   * @param  {object} target
+   * @param  {object} fragBlock
+   */
+  function _checkRepeat(target, fragBlock, repeatId, latestItemId) {
+    var _this3 = this;
+  
+    var children = fragBlock.children;
+  
+    this._watchBlock(fragBlock, target.repeat, 'repeat', function (value) {
+      if (!fragBlock) {
+        return;
+      }
+  
+      var oldChildren = children.slice();
+      var oldValue = fragBlock.data.slice();
+      // 1. collect all new refs track by
+      var trackMap = {};
+      var reusedMap = {};
+      value.forEach(function (item, index) {
+        var key = item['__wx_repeat_' + repeatId + '__'];
+        if (!key) {
+          key = latestItemId++;
+          setRepeatItemId(item, repeatId, key);
+        }
+        trackMap[key] = item;
+      });
+  
+      // 2. remove unused element foreach old item
+      var reusedList = [];
+      oldValue.forEach(function (item, index) {
+        var key = item['__wx_repeat_' + repeatId + '__'];
+        if (trackMap.hasOwnProperty(key)) {
+          reusedMap[key] = { item: item, index: index, target: oldChildren[index] };
+          reusedList.push(item);
+        } else {
+          _this3._removeTarget(oldChildren[index]);
+        }
+      });
+  
+      // 3. create new element foreach new item
+      children.length = 0;
+      fragBlock.data = value.slice();
+      fragBlock.updateMark = fragBlock.start;
+  
+      value.forEach(function (item, index) {
+        var key = item['__wx_repeat_' + repeatId + '__'];
+        var reused = reusedMap[key];
+        if ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object') {
+          item.INDEX = index;
+        }
+        if (reused) {
+          if (reused.item === reusedList[0]) {
+            reusedList.shift();
+          } else {
+            reusedList.$remove(reused.item);
+            _this3._moveTarget(reused.target, fragBlock.updateMark, true);
+          }
+          children.push(reused.target);
+          fragBlock.updateMark = reused.target;
+        } else {
+          _this3._generate(target, fragBlock, { repeat: item });
+        }
+      });
+  
+      delete fragBlock.updateMark;
+    });
+  }
+  
+  var latestRepeatId = 1;
+  
+  function markList(list, repeatId) {
+    var latestItemId = 1;
+    list.forEach(function (item) {
+      setRepeatItemId(item, repeatId, latestItemId++);
+    });
+    return latestItemId;
+  }
+  
+  function setRepeatItemId(item, repeatId, itemId) {
+    var key = '__wx_repeat_' + repeatId + '__';
+    if ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object') {
+      Object.defineProperty(item, key, {
+        value: itemId
+      });
+    }
+  }
+  
+  /**
+   * Watch the display update and add/remove the element.
+   *
+   * @param  {object} target
+   * @param  {object} fragBlock
+   * @param  {object} context
+   */
+  function _checkDisplay(target, fragBlock, context) {
+    var _this4 = this;
+  
+    this._watchBlock(fragBlock, target.shown, 'shown', function (value) {
+      if (!fragBlock || !!fragBlock.display === !!value) {
+        return;
+      }
+      fragBlock.display = value;
+      if (value) {
+        _this4._generate(target, fragBlock, context);
+      } else {
+        _this4._removeBlock(fragBlock, true);
+      }
+    });
+  }
+  
+  function _watchBlock(fragBlock, calc, type, handler) {
+    var differ = this && this._app && this._app.differ;
+    var config = {};
+    var depth = (fragBlock.element.depth || 0) + 1;
+  
+    this._watch(calc, function (value) {
+      config.latestValue = value;
+      if (differ && !config.recorded) {
+        differ.append(type, depth, fragBlock.blockId, function () {
+          var latestValue = config.latestValue;
+          handler(latestValue);
+          config.recorded = false;
+          config.latestValue = undefined;
+        });
+      }
+      config.recorded = true;
+    });
+  }
+  
+  /**
+   * Clone a context and merge certain data.
+   *
+   * @param  {object} mergedData
+   * @return {object}
+   */
+  function _mergeContext(mergedData) {
+    var context = Object.create(this);
+    context._data = mergedData;
+    context._initData();
+    context._realParent = this;
+    return context;
+  }
+
+/***/ },
+/* 94 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  
+  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /**
+                                                                                                                                                                                                                                                     * @fileOverview
+                                                                                                                                                                                                                                                     * Directive Parser
+                                                                                                                                                                                                                                                     */
+  
+  exports._applyNaitveComponentOptions = _applyNaitveComponentOptions;
+  exports._bindElement = _bindElement;
+  exports._bindSubVm = _bindSubVm;
+  exports._bindSubVmAfterInitialized = _bindSubVmAfterInitialized;
+  exports._setId = _setId;
+  exports._setAttr = _setAttr;
+  exports._setClass = _setClass;
+  exports._setStyle = _setStyle;
+  exports._setEvent = _setEvent;
+  exports._bindEvents = _bindEvents;
+  exports._bindDir = _bindDir;
+  exports._bindKey = _bindKey;
+  exports._watch = _watch;
+  
+  var _util = __webpack_require__(81);
+  
+  var _watcher = __webpack_require__(95);
+  
+  var _watcher2 = _interopRequireDefault(_watcher);
+  
+  var _config = __webpack_require__(79);
+  
+  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+  
+  var SETTERS = {
+    attr: 'setAttr',
+    style: 'setStyle',
+    event: 'addEvent'
+  };
+  
+  /**
+   * apply the native component's options(specified by template.type)
+   * to the template
+   */
+  function _applyNaitveComponentOptions(template) {
+    var type = template.type;
+  
+    var options = _config.nativeComponentMap[type];
+  
+    if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {
+      (0, _util.extend)(template, options);
+    }
+  }
+  
+  /**
+   * bind all id, attr, classnames, style, events to an element
+   */
+  function _bindElement(el, template) {
+    this._setId(template.id, el, this);
+    this._setAttr(el, template.attr);
+    this._setClass(el, template.classList);
+    this._setStyle(el, template.style);
+    this._bindEvents(el, template.events);
+  }
+  
+  /**
+   * bind all props to sub vm and bind all style, events to the root element
+   * of the sub vm if it doesn't have a replaced multi-node fragment
+   */
+  function _bindSubVm(subVm, template, repeatItem) {
+    subVm = subVm || {};
+    template = template || {};
+  
+    var options = subVm._options || {};
+  
+    // bind props
+    var props = options.props;
+  
+    if (Array.isArray(props)) {
+      props = props.reduce(function (result, value) {
+        result[value] = true;
+        return result;
+      }, {});
+    }
+  
+    mergeProps(repeatItem, props, this, subVm);
+    mergeProps(template.attr, props, this, subVm);
+  }
+  
+  function _bindSubVmAfterInitialized(subVm, template) {
+    mergeClassStyle(template.classList, this, subVm);
+    mergeStyle(template.style, this, subVm);
+    mergeEvent(template.events, this, subVm);
+  }
+  
+  function mergeProps(target, props, vm, subVm) {
+    if (!target) {
+      return;
+    }
+  
+    var _loop = function _loop(key) {
+      if (!props || props[key]) {
+        var value = target[key];
+        if (typeof value === 'function') {
+          var returnValue = vm._watch(value, function (v) {
+            subVm[key] = v;
+          });
+          subVm[key] = returnValue;
+        } else {
+          subVm[key] = value;
+        }
+      }
+    };
+  
+    for (var key in target) {
+      _loop(key);
+    }
+  }
+  
+  function mergeStyle(target, vm, subVm) {
+    var _loop2 = function _loop2(key) {
+      var value = target[key];
+      if (typeof value === 'function') {
+        var returnValue = vm._watch(value, function (v) {
+          if (subVm._rootEl) {
+            subVm._rootEl.setStyle(key, v);
+          }
+        });
+        subVm._rootEl.setStyle(key, returnValue);
+      } else {
+        if (subVm._rootEl) {
+          subVm._rootEl.setStyle(key, value);
+        }
+      }
+    };
+  
+    for (var key in target) {
+      _loop2(key);
+    }
+  }
+  
+  function mergeClassStyle(target, vm, subVm) {
+    var css = vm._options && vm._options.style || {};
+  
+    if (!subVm._rootEl) {
+      return;
+    }
+  
+    if (typeof target === 'function') {
+      var _value = vm._watch(target, function (v) {
+        setClassStyle(subVm._rootEl, css, v);
+      });
+      setClassStyle(subVm._rootEl, css, _value);
+    } else if (target) {
+      setClassStyle(subVm._rootEl, css, target);
+    }
+  }
+  
+  function mergeEvent(target, vm, subVm) {
+    if (target && subVm._rootEl) {
+      for (var type in target) {
+        var handler = vm[target[type]];
+        if (handler) {
+          subVm._rootEl.addEvent(type, (0, _util.bind)(handler, vm));
+        }
+      }
+    }
+  }
+  
+  /**
+   * bind id to an element
+   * each id is unique in a whole vm
+   */
+  function _setId(id, el, vm) {
+    var _this = this;
+  
+    var map = Object.create(null);
+  
+    Object.defineProperties(map, {
+      vm: {
+        value: vm,
+        writable: false,
+        configurable: false
+      },
+      el: {
+        get: function get() {
+          return el || vm._rootEl;
+        },
+        configurable: false
+      }
+    });
+  
+    if (typeof id === 'function') {
+      var handler = id;
+      id = handler.call(this);
+      if (id) {
+        this._ids[id] = map;
+      }
+      this._watch(handler, function (newId) {
+        if (newId) {
+          _this._ids[newId] = map;
+        }
+      });
+    } else if (id && typeof id === 'string') {
+      this._ids[id] = map;
+    }
+  }
+  
+  /**
+   * bind attr to an element
+   */
+  function _setAttr(el, attr) {
+    this._bindDir(el, 'attr', attr);
+  }
+  
+  function setClassStyle(el, css, classList) {
+    var classStyle = {};
+    var length = classList.length;
+  
+    for (var i = 0; i < length; i++) {
+      var style = css[classList[i]];
+      if (style) {
+        for (var key in style) {
+          classStyle[key] = style[key];
+        }
+      }
+    }
+    el.setClassStyle(classStyle);
+  }
+  
+  /**
+   * bind classnames to an element
+   */
+  function _setClass(el, classList) {
+  
+    if (typeof classList !== 'function' && !Array.isArray(classList)) {
+      return;
+    }
+    if (Array.isArray(classList) && !classList.length) {
+      el.setClassStyle({});
+      return;
+    }
+  
+    var style = this._options && this._options.style || {};
+    if (typeof classList === 'function') {
+      var _value2 = this._watch(classList, function (v) {
+        setClassStyle(el, style, v);
+      });
+      setClassStyle(el, style, _value2);
+    } else {
+      setClassStyle(el, style, classList);
+    }
+  }
+  
+  /**
+   * bind style to an element
+   */
+  function _setStyle(el, style) {
+    this._bindDir(el, 'style', style);
+  }
+  
+  /**
+   * add an event type and handler to an element and generate a dom update
+   */
+  function _setEvent(el, type, handler) {
+    el.addEvent(type, (0, _util.bind)(handler, this));
+  }
+  
+  /**
+   * add all events of an element
+   */
+  function _bindEvents(el, events) {
+    if (!events) {
+      return;
+    }
+    var keys = Object.keys(events);
+    var i = keys.length;
+    while (i--) {
+      var key = keys[i];
+      var handler = events[key];
+      if (typeof handler === 'string') {
+        handler = this[handler];
+      }
+      this._setEvent(el, key, handler);
+    }
+  }
+  
+  /**
+   * set a series of members as a kind of an element
+   * for example: style, attr, ...
+   * if the value is a function then bind the data changes
+   */
+  function _bindDir(el, name, data) {
+    if (!data) {
+      return;
+    }
+    var keys = Object.keys(data);
+    var i = keys.length;
+    while (i--) {
+      var key = keys[i];
+      var _value3 = data[key];
+      if (typeof _value3 === 'function') {
+        var update = _value3;
+        this._bindKey(el, name, key, update);
+      } else {
+        el[SETTERS[name]](key, _value3);
+      }
+    }
+  }
+  
+  /**
+   * bind data changes to a certain key to a name series in an element
+   */
+  function _bindKey(el, name, key, calc) {
+    var _this2 = this;
+  
+    var methodName = SETTERS[name];
+    var obj = el[name];
+    // watch the calc, and returns a value by calc.call()
+    var value = this._watch(calc, function (value) {
+      function handler() {
+        el[methodName](key, value);
+      }
+      var differ = _this2 && _this2._app && _this2._app.differ;
+      if (differ) {
+        differ.append('element', el.depth, el.ref, handler);
+      } else {
+        handler();
+      }
+    });
+  
+    el[methodName](key, value);
+  }
+  
+  /**
+   * watch a calc function and callback if the calc value changes
+   */
+  function _watch(calc, callback) {
+    var watcher = new _watcher2.default(this, calc, function (value, oldValue) {
+      /* istanbul ignore if */
+      if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) !== 'object' && value === oldValue) {
+        return;
+      }
+      callback(value);
+    });
+  
+    return watcher.value;
+  }
+
+/***/ },
+/* 95 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  /**
+   * The MIT License (MIT)
+   *
+   * Copyright (c) 2013-2015 Yuxi Evan You
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining a copy
+   * of this software and associated documentation files (the "Software"), to deal
+   * in the Software without restriction, including without limitation the rights
+   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+   * copies of the Software, and to permit persons to whom the Software is
+   * furnished to do so, subject to the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be included in
+   * all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+   * THE SOFTWARE.
+   */
+  
+  var _ = __webpack_require__(87);
+  // var config = require('./config')
+  var Observer = __webpack_require__(88);
+  // var expParser = require('./parsers/expression')
+  // var batcher = require('./batcher')
+  var uid = 0;
+  
+  /**
+   * A watcher parses an expression, collects dependencies,
+   * and fires callback when the expression value changes.
+   * This is used for both the $watch() api and directives.
+   *
+   * @param {Vue} vm
+   * @param {String} expression
+   * @param {Function} cb
+   * @param {Object} options
+   *                 - {Array} filters
+   *                 - {Boolean} twoWay
+   *                 - {Boolean} deep
+   *                 - {Boolean} user
+   *                 - {Function} [preProcess]
+   * @constructor
+   */
+  
+  // function Watcher (vm, expression, cb, options) {
+  function Watcher(vm, update, cb) {
+    this.vm = vm;
+    vm._watchers.push(this);
+    // this.expression = expression
+    this.cb = cb;
+    this.id = ++uid; // uid for batching
+    this.active = true;
+    // options = options || {}
+    // this.deep = !!options.deep
+    // this.user = !!options.user
+    // this.twoWay = !!options.twoWay
+    // this.filters = options.filters
+    // this.preProcess = options.preProcess
+    this.deps = [];
+    this.newDeps = [];
+    // parse expression for getter/setter
+    // var res = expParser.parse(expression, options.twoWay)
+    // this.getter = res.get
+    // this.setter = res.set
+    this.getter = update;
+    this.value = this.get();
+  }
+  
+  var p = Watcher.prototype;
+  
+  /**
+   * Add a dependency to this directive.
+   *
+   * @param {Dep} dep
+   */
+  
+  p.addDep = function (dep) {
+    var newDeps = this.newDeps;
+    var old = this.deps;
+    if (_.indexOf(newDeps, dep) < 0) {
+      newDeps.push(dep);
+      var i = _.indexOf(old, dep);
+      if (i < 0) {
+        dep.addSub(this);
+      } else {
+        old[i] = null;
+      }
+    }
+  };
+  
+  /**
+   * Evaluate the getter, and re-collect dependencies.
+   */
+  
+  p.get = function () {
+    this.beforeGet();
+    var vm = this.vm;
+    var value;
+    try {
+      value = this.getter.call(vm, vm);
+    } catch (e) {
+      // if (config.warnExpressionErrors) {
+      //   _.warn(
+      //     'Error when evaluating expression "' +
+      //     this.expression + '":\n   ' + e
+      //   )
+      // }
+      _.warn('Error when update"');
+    }
+    // "touch" every property so they are all tracked as
+    // dependencies for deep watching
+    if (this.deep) {
+      traverse(value);
+    }
+    if (this.preProcess) {
+      value = this.preProcess(value);
+    }
+    if (this.filters) {
+      value = vm._applyFilters(value, null, this.filters, false);
+    }
+    this.afterGet();
+    return value;
+  };
+  
+  // /**
+  //  * Set the corresponding value with the setter.
+  //  *
+  //  * @param {*} value
+  //  */
+  
+  // p.set = function (value) {
+  //   var vm = this.vm
+  //   if (this.filters) {
+  //     value = vm._applyFilters(
+  //       value, this.value, this.filters, true)
+  //   }
+  //   try {
+  //     this.setter.call(vm, vm, value)
+  //   } catch (e) {
+  //     // if (config.warnExpressionErrors) {
+  //       _.warn(
+  //         'Error when evaluating setter "' +
+  //         this.expression + '":\n   ' + e
+  //       )
+  //     // }
+  //   }
+  // }
+  
+  /**
+   * Prepare for dependency collection.
+   */
+  
+  p.beforeGet = function () {
+    Observer.target = this;
+  };
+  
+  /**
+   * Clean up for dependency collection.
+   */
+  
+  p.afterGet = function () {
+    Observer.target = null;
+    var i = this.deps.length;
+    while (i--) {
+      var dep = this.deps[i];
+      if (dep) {
+        dep.removeSub(this);
+      }
+    }
+    this.deps = this.newDeps;
+    this.newDeps = [];
+  };
+  
+  /**
+   * Subscriber interface.
+   * Will be called when a dependency changes.
+   */
+  
+  // p.update = function () {
+  //   if (!config.async || config.debug) {
+  //     this.run()
+  //   } else {
+  //     batcher.push(this)
+  //   }
+  // }
+  
+  // /**
+  //  * Batcher job interface.
+  //  * Will be called by the batcher.
+  //  */
+  
+  // p.run = function () {
+  p.update = function () {
+    if (this.active) {
+      var value = this.get();
+      if (value !== this.value || Array.isArray(value) || this.deep) {
+        var oldValue = this.value;
+        this.value = value;
+        this.cb(value, oldValue);
+      }
+    }
+  };
+  
+  /**
+   * Remove self from all dependencies' subcriber list.
+   */
+  
+  p.teardown = function () {
+    if (this.active) {
+      // remove self from vm's watcher list
+      // we can skip this if the vm if being destroyed
+      // which can improve teardown performance.
+      if (!this.vm._isBeingDestroyed) {
+        this.vm._watchers.$remove(this);
+      }
+      var i = this.deps.length;
+      while (i--) {
+        this.deps[i].removeSub(this);
+      }
+      this.active = false;
+      this.vm = this.cb = this.value = null;
+    }
+  };
+  
+  /**
+   * Recrusively traverse an object to evoke all converted
+   * getters, so that every nested property inside the object
+   * is collected as a "deep" dependency.
+   *
+   * @param {Object} obj
+   */
+  
+  function traverse(obj) {
+    var key, val, i;
+    for (key in obj) {
+      val = obj[key];
+      if (_.isArray(val)) {
+        i = val.length;
+        while (i--) {
+          traverse(val[i]);
+        }
+      } else if (_.isObject(val)) {
+        traverse(val);
+      }
+    }
+  }
+  
+  module.exports = Watcher;
+
+/***/ },
+/* 96 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports._createBody = _createBody;
+  exports._createElement = _createElement;
+  exports._createBlock = _createBlock;
+  exports._createBlockStart = _createBlockStart;
+  exports._createBlockEnd = _createBlockEnd;
+  exports._attachTarget = _attachTarget;
+  exports._moveTarget = _moveTarget;
+  exports._moveElement = _moveElement;
+  exports._moveBlock = _moveBlock;
+  exports._removeTarget = _removeTarget;
+  exports._removeElement = _removeElement;
+  exports._removeBlock = _removeBlock;
+  /**
+   * @fileOverview Document & Element Helpers.
+   *
+   * required:
+   * Document#: createElement, createComment, getRef
+   * Element#: appendChild, insertBefore, removeChild, nextSibling
+   */
+  
+  /**
+   * Create a body by type
+   * Using this._app.doc
+   *
+   * @param  {string} type
+   */
+  function _createBody(type) {
+    var doc = this._app.doc;
+    return doc.createBody(type);
+  }
+  
+  /**
+   * Create an element by type
+   * Using this._app.doc
+   *
+   * @param  {string} type
+   */
+  function _createElement(type) {
+    var doc = this._app.doc;
+    return doc.createElement(type);
+  }
+  
+  /**
+   * Create and return a frag block for an element.
+   * The frag block has a starter, ender and the element itself.
+   *
+   * @param  {object} element
+   */
+  function _createBlock(element) {
+    var start = this._createBlockStart();
+    var end = this._createBlockEnd();
+    var blockId = lastestBlockId++;
+    if (element.element) {
+      element.element.insertBefore(start, element.end);
+      element.element.insertBefore(end, element.end);
+      element = element.element;
+    } else {
+      element.appendChild(start);
+      element.appendChild(end);
+    }
+    return { start: start, end: end, element: element, blockId: blockId };
+  }
+  
+  var lastestBlockId = 1;
+  
+  /**
+   * Create and return a block starter.
+   * Using this._app.doc
+   */
+  function _createBlockStart() {
+    var doc = this._app.doc;
+    var anchor = doc.createComment('start');
+    return anchor;
+  }
+  
+  /**
+   * Create and return a block ender.
+   * Using this._app.doc
+   */
+  function _createBlockEnd() {
+    var doc = this._app.doc;
+    var anchor = doc.createComment('end');
+    return anchor;
+  }
+  
+  /**
+   * Attach target to a certain dest using appendChild by default.
+   * If the dest is a frag block then insert before the ender.
+   * If the target is a frag block then attach the starter and ender in order.
+   *
+   * @param  {object} target
+   * @param  {object} dest
+   */
+  function _attachTarget(target, dest) {
+  
+    if (dest.element) {
+      var before = dest.end;
+      var after = dest.updateMark;
+      // push new target for watch list update later
+      if (dest.children) {
+        dest.children.push(target);
+      }
+      // for check repeat case
+      if (after) {
+        this._moveTarget(target, after);
+        dest.updateMark = target.element ? target.end : target;
+      } else if (target.element) {
+        dest.element.insertBefore(target.start, before);
+        dest.element.insertBefore(target.end, before);
+      } else {
+        dest.element.insertBefore(target, before);
+      }
+    } else {
+      if (target.element) {
+        dest.appendChild(target.start);
+        dest.appendChild(target.end);
+      } else {
+        dest.appendChild(target);
+      }
+    }
+  }
+  
+  /**
+   * Move target before a certain element. The target maybe block or element.
+   *
+   * @param  {object} target
+   * @param  {object} before
+   */
+  function _moveTarget(target, after) {
+    if (target.element) {
+      this._moveBlock(target, after);
+    } else {
+      this._moveElement(target, after);
+    }
+  }
+  
+  /**
+   * Move element before a certain element.
+   *
+   * @param  {object} element
+   * @param  {object} before
+   */
+  function _moveElement(element, after) {
+    var doc = this._app.doc;
+    var parent = doc.getRef(after.parentRef);
+  
+    if (parent) {
+      parent.insertAfter(element, after);
+    }
+  }
+  
+  /**
+   * Move all elements of the block before a certain element.
+   *
+   * @param  {object} fragBlock
+   * @param  {object} before
+   */
+  function _moveBlock(fragBlock, after) {
+    var doc = this._app.doc;
+    var parent = doc.getRef(after.parentRef);
+  
+    if (parent) {
+      (function () {
+        var el = fragBlock.start;
+        var group = [el];
+  
+        while (el && el !== fragBlock.end) {
+          el = el.next();
+          group.push(el);
+        }
+  
+        var temp = after;
+        group.forEach(function (el) {
+          parent.insertAfter(el, temp);
+          temp = el;
+        });
+      })();
+    }
+  }
+  
+  /**
+   * Remove target from DOM tree.
+   * If the target is a frag block then call _removeBlock
+   *
+   * @param  {object} target
+   */
+  function _removeTarget(target) {
+  
+    if (target.element) {
+      this._removeBlock(target);
+    } else {
+      this._removeElement(target);
+    }
+  }
+  
+  /**
+   * Remove a certain element.
+   * Using this._app.doc
+   *
+   * @param  {object} target
+   */
+  function _removeElement(target) {
+    var doc = this._app.doc;
+    var parent = doc.getRef(target.parentRef);
+  
+    if (parent) {
+      parent.removeChild(target);
+    }
+  }
+  
+  /**
+   * Remove a frag block.
+   * The second param decides whether the block self should be removed too.
+   *
+   * @param  {object}  fragBlock
+   * @param  {Boolean} preserveBlock=false
+   */
+  function _removeBlock(fragBlock) {
+    var _this = this;
+  
+    var preserveBlock = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
+  
+    var result = [];
+    var el = fragBlock.start.next();
+  
+    while (el && el !== fragBlock.end) {
+      result.push(el);
+      el = el.next();
+    }
+  
+    if (!preserveBlock) {
+      this._removeElement(fragBlock.start);
+    }
+    result.forEach(function (el) {
+      _this._removeElement(el);
+    });
+    if (!preserveBlock) {
+      this._removeElement(fragBlock.end);
+    }
+  }
+
+/***/ },
+/* 97 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.$emit = $emit;
+  exports.$dispatch = $dispatch;
+  exports.$broadcast = $broadcast;
+  exports.$on = $on;
+  exports.$off = $off;
+  exports._initEvents = _initEvents;
+  function Evt(type, detail) {
+    if (detail instanceof Evt) {
+      return detail;
+    }
+  
+    this.timestamp = Date.now();
+    this.detail = detail;
+    this.type = type;
+  
+    var shouldStop = false;
+    this.stop = function () {
+      shouldStop = true;
+    };
+    this.hasStopped = function () {
+      return shouldStop;
+    };
+  }
+  
+  function $emit(type, detail) {
+    var _this = this;
+  
+    var events = this._vmEvents;
+    var handlerList = events[type];
+    if (handlerList) {
+      (function () {
+        var evt = new Evt(type, detail);
+        handlerList.forEach(function (handler) {
+          handler.call(_this, evt);
+        });
+      })();
+    }
+  }
+  
+  function $dispatch(type, detail) {
+    var evt = new Evt(type, detail);
+    this.$emit(type, evt);
+  
+    if (!evt.hasStopped() && this._parent && this._parent.$dispatch) {
+      this._parent.$dispatch(type, evt);
+    }
+  }
+  
+  function $broadcast(type, detail) {
+    var evt = new Evt(type, detail);
+    this.$emit(type, evt);
+  
+    if (!evt.hasStopped() && this._childrenVms) {
+      this._childrenVms.forEach(function (subVm) {
+        subVm.$broadcast(type, evt);
+      });
+    }
+  }
+  
+  function $on(type, handler) {
+    if (!type || typeof handler !== 'function') {
+      return;
+    }
+    var events = this._vmEvents;
+    var handlerList = events[type] || [];
+    handlerList.push(handler);
+    events[type] = handlerList;
+  
+    // fixed old version lifecycle design
+    if (type === 'hook:ready' && this._ready) {
+      this.$emit('hook:ready');
+    }
+  }
+  
+  function $off(type, handler) {
+    if (!type) {
+      return;
+    }
+    var events = this._vmEvents;
+    if (!handler) {
+      delete events[type];
+      return;
+    }
+    var handlerList = events[type];
+    if (!handlerList) {
+      return;
+    }
+    handlerList.$remove(handler);
+  }
+  
+  var LIFE_CYCLE_TYPES = ['init', 'created', 'ready'];
+  
+  function _initEvents(externalEvents) {
+    var _this2 = this;
+  
+    var options = this._options || {};
+    var events = options.events || {};
+    for (var type1 in events) {
+      this.$on(type1, events[type1]);
+    }
+    for (var type2 in externalEvents) {
+      this.$on(type2, externalEvents[type2]);
+    }
+    LIFE_CYCLE_TYPES.forEach(function (type) {
+      _this2.$on('hook:' + type, options[type]);
+    });
+  }
+
+/***/ },
+/* 98 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.clearModules = clearModules;
+  exports.getModule = getModule;
+  exports.requireModule = requireModule;
+  exports.registerModules = registerModules;
+  exports.registerMethods = registerMethods;
+  exports.requireComponent = requireComponent;
+  exports.registerComponent = registerComponent;
+  var nativeModules = {};
+  
+  function assignModules(modules, ifReplace) {
+    var _loop = function _loop(moduleName) {
+  
+      // init `modules[moduleName][]`
+      var methods = nativeModules[moduleName];
+      if (!methods) {
+        methods = {};
+        nativeModules[moduleName] = methods;
+      }
+  
+      // push each non-existed new method
+      modules[moduleName].forEach(function (method) {
+        if (typeof method === 'string') {
+          method = {
+            name: method
+          };
+        }
+  
+        if (!methods[method.name] || ifReplace) {
+          methods[method.name] = method;
+        }
+      });
+    };
+  
+    for (var moduleName in modules) {
+      _loop(moduleName);
+    }
+  }
+  
+  function assignApis(Ctor, apis) {
+    var p = Ctor.prototype;
+  
+    for (var apiName in apis) {
+      if (!p.hasOwnProperty(apiName)) {
+        p[apiName] = apis[apiName];
+      }
+    }
+  }
+  
+  function clearModules() {
+    nativeModules = {};
+  }
+  
+  function getModule(moduleName) {
+    return nativeModules[moduleName];
+  }
+  
+  /**
+   * @context a instance of AppInstance
+   */
+  function requireModule(moduleName) {
+    var _this = this;
+  
+    var methods = nativeModules[moduleName];
+    var target = {};
+  
+    var _loop2 = function _loop2(methodName) {
+      target[methodName] = function () {
+        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+          args[_key] = arguments[_key];
+        }
+  
+        return _this.callTasks({
+          module: moduleName,
+          method: methodName,
+          args: args
+        });
+      };
+    };
+  
+    for (var methodName in methods) {
+      _loop2(methodName);
+    }
+  
+    return target;
+  }
+  
+  /**
+   * @context Vm
+   */
+  function registerModules(modules, ifReplace) {
+    assignModules(modules, ifReplace);
+  }
+  
+  /**
+   * @context Vm
+   */
+  function registerMethods(apis) {
+    assignApis(this, apis);
+  }
+  
+  /**
+   * @context a instance of AppInstance
+   */
+  function requireComponent(name) {
+    var customComponentMap = this.customComponentMap;
+  
+    return customComponentMap[name];
+  }
+  
+  /**
+   * @context a instance of AppInstance
+   */
+  function registerComponent(name, exports) {
+    var customComponentMap = this.customComponentMap;
+  
+  
+    if (customComponentMap[name]) {
+      throw new Error('define a component(' + name + ') that already exists');
+    }
+  
+    customComponentMap[name] = exports;
+  }
+
+/***/ },
+/* 99 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.normalizeVersion = normalizeVersion;
+  exports.getError = getError;
+  exports.check = check;
+  
+  var _semver = __webpack_require__(83);
+  
+  var _semver2 = _interopRequireDefault(_semver);
+  
+  var _util = __webpack_require__(81);
+  
+  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+  
+  /**
+   * [normalizeVersion description]
+   * @param  {String} Version. ie: 1, 1.0, 1.0.0
+   * @return {String} Version
+   */
+  function normalizeVersion(v) {
+    var isValid = _semver2.default.valid(v) ? true : false;
+    if (isValid) {
+      return v;
+    }
+  
+    v = typeof v === 'string' ? v : '';
+    var split = v.split('.');
+    var i = 0;
+    var result = [];
+  
+    while (i < 3) {
+      var s = typeof split[i] === 'string' && split[i] ? split[i] : '0';
+      result.push(s);
+      i++;
+    }
+  
+    return result.join('.');
+  }
+  
+  function getError(key, val, criteria) {
+    var result = {
+      isDowngrade: true,
+      errorType: 1,
+      code: 1000
+    };
+    var getMsg = function getMsg(key, val, criteria) {
+      return 'Downgrade[' + key + '] :: deviceInfo ' + val + ' matched criteria ' + criteria;
+    };
+    var _key = key.toLowerCase();
+  
+    result.errorMessage = getMsg(key, val, criteria);
+  
+    if (_key.indexOf('osversion') >= 0) {
+      result.code = 1001;
+    } else if (_key.indexOf('appversion') >= 0) {
+      result.code = 1002;
+    } else if (_key.indexOf('weexversion') >= 0) {
+      result.code = 1003;
+    } else if (_key.indexOf('devicemodel') >= 0) {
+      result.code = 1004;
+    }
+  
+    return result;
+  }
+  
+  /**
+   * WEEX framework input(deviceInfo)
+   * {
+   *   platform: 'iOS' or 'android'
+   *   osVersion: '1.0.0' or '1.0' or '1'
+   *   appVersion: '1.0.0' or '1.0' or '1'
+   *   weexVersion: '1.0.0' or '1.0' or '1'
+   *   dDeviceModel: 'MODEL_NAME'
+   * }
+   *
+   * downgrade config(config)
+   * {
+   *   ios: {
+   *     osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+   *     appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+   *     weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+   *     deviceModel: ['modelA', 'modelB', ...]
+   *   },
+   *   android: {
+   *     osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+   *     appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+   *     weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+   *     deviceModel: ['modelA', 'modelB', ...]
+   *   }
+   * }
+   *
+   *
+   * @param  {object} deviceInfo Weex SDK framework input
+   * @param  {object} config     user input
+   * @return {Object}            { isDowngrade: true/false, errorMessage... }
+   */
+  function check(config, deviceInfo) {
+    deviceInfo = deviceInfo || global.WXEnvironment;
+    deviceInfo = (0, _util.isPlainObject)(deviceInfo) ? deviceInfo : {};
+    config = (0, _util.isPlainObject)(config) ? config : {};
+    var platform = deviceInfo.platform || 'unknow';
+    var dPlatform = platform.toLowerCase();
+    var cObj = config[dPlatform] || {};
+  
+    var result = {
+      isDowngrade: false // defautl is pass
+    };
+  
+    for (var i in deviceInfo) {
+      var key = i;
+      var keyLower = key.toLowerCase();
+      var val = deviceInfo[i];
+      var isVersion = keyLower.indexOf('version') >= 0 ? true : false;
+      var isDeviceModel = keyLower.indexOf('devicemodel') >= 0 ? true : false;
+      var criteria = cObj[i];
+  
+      if (criteria && isVersion) {
+        var c = this.normalizeVersion(criteria);
+        var d = this.normalizeVersion(deviceInfo[i]);
+  
+        if (_semver2.default.satisfies(d, c)) {
+          result = (0, _util.extend)(this.getError(key, val, criteria));
+          break;
+        }
+      } else if (isDeviceModel) {
+        var _criteria = (0, _util.typof)(criteria) === 'array' ? criteria : [criteria];
+        if (_criteria.indexOf(val) >= 0) {
+          result = (0, _util.extend)(this.getError(key, val, criteria));
+          break;
+        }
+      }
+    }
+  
+    return result;
+  }
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ },
+/* 100 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.init = init;
+  exports.destroy = destroy;
+  exports.getRootElement = getRootElement;
+  exports.updateActions = updateActions;
+  exports.fireEvent = fireEvent;
+  exports.callback = callback;
+  exports.refreshData = refreshData;
+  
+  var _util = __webpack_require__(81);
+  
+  var _perf = __webpack_require__(77);
+  
+  var perf = _interopRequireWildcard(_perf);
+  
+  var _domListener = __webpack_require__(101);
+  
+  var _domListener2 = _interopRequireDefault(_domListener);
+  
+  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+  
+  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+  
+  function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } /**
+                                                                                                                                                                                                       * @fileOverview
+                                                                                                                                                                                                       * instance controls from native
+                                                                                                                                                                                                       *
+                                                                                                                                                                                                       * - init bundle
+                                                                                                                                                                                                       * - fire event
+                                                                                                                                                                                                       * - callback
+                                                                                                                                                                                                       * - destroy
+                                                                                                                                                                                                       *
+                                                                                                                                                                                                       * corresponded with the API of instance manager (framework.js)
+                                                                                                                                                                                                       */
+  
+  function init(code, data) {
+    var _this = this;
+  
+    var result;
+    // @see: lib/app/bundle.js
+    var define = (0, _util.bind)(this.define, this);
+    var bootstrap = function bootstrap(name, config, _data) {
+      result = _this.bootstrap(name, config, _data || data);
+      _this.doc.listener.createFinish();
+      _this.doc.close();
+    };
+  
+    // backward(register/render)
+    var register = (0, _util.bind)(this.register, this);
+    var render = function render(name, _data) {
+      result = _this.bootstrap(name, {}, _data);
+    };
+  
+    var require = function require(name) {
+      return function (_data) {
+        result = _this.bootstrap(name, {}, _data);
+      };
+    };
+  
+    var document = this.doc;
+  
+    perf.start('run bundle', this.id);
+  
+    var functionBody = void 0;
+    /* istanbul ignore if */
+    if (typeof code === 'function') {
+      // `function () {...}` -> `{...}`
+      // not very strict
+      functionBody = code.toString().substr(12);
+    } else if (code) {
+      functionBody = code.toString();
+    }
+  
+    var fn = new Function('define', 'require', 'document', 'bootstrap', 'register', 'render', functionBody);
+  
+    fn(define, require, document, bootstrap, register, render);
+  
+    perf.end('run bundle', this.id);
+    return result;
+  }
+  
+  function destroy() {
+    this.id = '';
+    this.eventManager = null;
+    this.options = null;
+    this.blocks = null;
+    this.vm = null;
+    this.doc = null;
+    this.customComponentMap = null;
+    this.callbacks = null;
+  }
+  
+  function getRootElement() {
+    var doc = this.doc || {};
+    var body = doc.body || {};
+    return body.toJSON ? body.toJSON() : {};
+  }
+  
+  function updateActions(addonTasks) {
+    this.differ.flush();
+    var tasks = [];
+    if (this.listener && this.listener.updates.length) {
+      tasks.push.apply(tasks, _toConsumableArray(this.listener.updates));
+      this.listener.updates = [];
+    }
+    if (addonTasks && addonTasks.length) {
+      tasks.push.apply(tasks, _toConsumableArray(addonTasks));
+    }
+    if (tasks.length) {
+      this.callTasks(tasks);
+    }
+  }
+  
+  function fireEvent(ref, type, e, domChanges) {
+    var _this2 = this;
+  
+    if (Array.isArray(ref)) {
+      ref.some(function (ref) {
+        return _this2.fireEvent(ref, type, e) !== false;
+      });
+      return;
+    }
+  
+    var el = this.doc.getRef(ref);
+  
+    if (el) {
+      perf.start('manage event', ref + '-' + type);
+      e = e || {};
+      e.type = type;
+      e.target = el;
+      e.timestamp = Date.now();
+      if (domChanges) {
+        updateElement(el, domChanges);
+      }
+      var result = this.eventManager.fire(el, type, e);
+      perf.end('manage event', ref + '-' + type);
+      this.updateActions();
+      return result;
+    }
+  
+    return new Error('invalid element reference "' + ref + '"');
+  }
+  
+  function callback(callbackId, data, ifKeepAlive) {
+    var callback = this.callbacks[callbackId];
+  
+    if (typeof callback === 'function') {
+      callback(data); // data is already a object, @see: lib/framework.js
+  
+      if (typeof ifKeepAlive === 'undefined' || ifKeepAlive === false) {
+        this.callbacks[callbackId] = undefined;
+      }
+  
+      this.updateActions();
+      return;
+    }
+  
+    return new Error('invalid callback id "' + callbackId + '"');
+  }
+  
+  function refreshData(data) {
+    var vm = this.vm;
+  
+    if (vm && data) {
+      if (typeof vm.refreshData === 'function') {
+        vm.refreshData(data);
+      } else {
+        (0, _util.extend)(vm, data);
+      }
+      this.updateActions([(0, _domListener.createAction)('refreshFinish', [])]);
+      return;
+    }
+  
+    return new Error('invalid data "' + data + '"');
+  }
+  
+  function updateElement(el, changes) {
+    var attrs = changes.attrs || {};
+    for (var name in attrs) {
+      el.setAttr(name, attrs);
+    }
+    var style = changes.style || {};
+    for (var _name in style) {
+      el.setStyle(_name, style[_name]);
+    }
+  }
+
+/***/ },
+/* 101 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.default = Listener;
+  exports.createAction = createAction;
+  function Listener(id, handler) {
+    this.id = id;
+    this.batched = false;
+    this.updates = [];
+    if (typeof handler === 'function') {
+      this.handler = handler;
+    }
+  }
+  
+  Listener.prototype.createFinish = function (callback) {
+    var handler = this.handler;
+    handler([createAction('createFinish', [])], callback);
+  };
+  
+  Listener.prototype.createBody = function (element, ref) {
+    var actions = [createAction('createBody', [element.toJSON()])];
+    this.addActions(actions);
+  };
+  
+  Listener.prototype.addElement = function (element, ref, index) {
+    if (!(index >= 0)) {
+      index = -1;
+    }
+    this.addActions(createAction('addElement', [ref, element.toJSON(), index]));
+  };
+  
+  Listener.prototype.removeElement = function (ref) {
+    if (Array.isArray(ref)) {
+      var actions = ref.map(function (r) {
+        return createAction('removeElement', [r]);
+      });
+      this.addActions(actions);
+    } else {
+      this.addActions(createAction('removeElement', [ref]));
+    }
+  };
+  
+  Listener.prototype.moveElement = function (targetRef, parentRef, index) {
+    this.addActions(createAction('moveElement', [targetRef, parentRef, index]));
+  };
+  
+  Listener.prototype.setAttr = function (ref, key, value) {
+    var result = {};
+    result[key] = value;
+    this.addActions(createAction('updateAttrs', [ref, result]));
+  };
+  
+  Listener.prototype.setStyle = function (ref, key, value) {
+    var result = {};
+    result[key] = value;
+    this.addActions(createAction('updateStyle', [ref, result]));
+  };
+  
+  Listener.prototype.setStyles = function (ref, style) {
+    this.addActions(createAction('updateStyle', [ref, style]));
+  };
+  
+  Listener.prototype.addEvent = function (ref, type) {
+    this.addActions(createAction('addEvent', [ref, type]));
+  };
+  
+  Listener.prototype.removeEvent = function (ref, type) {
+    this.addActions(createAction('removeEvent', [ref, type]));
+  };
+  
+  Listener.prototype.handler = function (actions, cb) {
+    cb && cb();
+  };
+  
+  Listener.prototype.addActions = function (actions) {
+    var updates = this.updates;
+    var handler = this.handler;
+  
+    if (!Array.isArray(actions)) {
+      actions = [actions];
+    }
+  
+    if (this.batched) {
+      updates.push.apply(updates, actions);
+    } else {
+      handler(actions);
+    }
+  };
+  
+  function createAction(name, args) {
+    return { module: 'dom', method: name, args: args };
+  }
+
+/***/ },
+/* 102 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  
+  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+  
+  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+  
+  var Differ = function () {
+    function Differ(id) {
+      _classCallCheck(this, Differ);
+  
+      this.id = id;
+      this.map = [];
+      this.hooks = [];
+    }
+  
+    _createClass(Differ, [{
+      key: 'isEmpty',
+      value: function isEmpty() {
+        return this.map.length === 0;
+      }
+    }, {
+      key: 'append',
+      value: function append(type, depth, ref, handler) {
+        var map = this.map;
+        if (!map[depth]) {
+          map[depth] = {};
+        }
+        var group = map[depth];
+        if (!group[type]) {
+          group[type] = {};
+        }
+        if (type === 'element') {
+          if (!group[type][ref]) {
+            group[type][ref] = [];
+          }
+          group[type][ref].push(handler);
+        } else {
+          group[type][ref] = handler;
+        }
+      }
+    }, {
+      key: 'flush',
+      value: function flush() {
+        var map = this.map.slice();
+        this.map.length = 0;
+        map.forEach(function (group) {
+          callTypeMap(group, 'repeat');
+          callTypeMap(group, 'shown');
+          callTypeList(group, 'element');
+        });
+  
+        var hooks = this.hooks.slice();
+        this.hooks.length = 0;
+        hooks.forEach(function (fn) {
+          fn();
+        });
+  
+        if (!this.isEmpty()) {
+          this.flush();
+        }
+      }
+    }, {
+      key: 'then',
+      value: function then(fn) {
+        this.hooks.push(fn);
+      }
+    }]);
+  
+    return Differ;
+  }();
+  
+  exports.default = Differ;
+  
+  
+  function callTypeMap(group, type) {
+    var map = group[type];
+    for (var ref in map) {
+      map[ref]();
+    }
+  }
+  
+  function callTypeList(group, type) {
+    var map = group[type];
+    for (var ref in map) {
+      var list = map[ref];
+      list.forEach(function (handler) {
+        handler();
+      });
+    }
+  }
+
+/***/ },
+/* 103 */
+/***/ function(module, exports, __webpack_require__) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  
+  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /**
+                                                                                                                                                                                                                                                     * @fileOverview event manager
+                                                                                                                                                                                                                                                     */
+  
+  exports.default = EventManager;
+  
+  var _util = __webpack_require__(81);
+  
+  var _ = _interopRequireWildcard(_util);
+  
+  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+  
+  function EventManager() {
+    this.els = [];
+    this.targets = [];
+  }
+  
+  EventManager.prototype._get = function (el, force) {
+    var index = _.indexOf(this.els, el);
+    var target;
+    if (index >= 0) {
+      target = this.targets[index];
+    } else if (force) {
+      target = { el: el, events: {} };
+      this.els.push(el);
+      this.targets.push(target);
+    }
+    return target;
+  };
+  
+  EventManager.prototype.add = function (el, type, handler) {
+    if ((typeof el === 'undefined' ? 'undefined' : _typeof(el)) !== 'object' || !el || typeof type !== 'string' || !type || typeof handler !== 'function') {
+      return;
+    }
+    var target = this._get(el, true);
+    target.events[type] = handler;
+  };
+  
+  EventManager.prototype.remove = function (el, type) {
+    if ((typeof el === 'undefined' ? 'undefined' : _typeof(el)) !== 'object' || !el || typeof type !== 'string' || !type) {
+      return;
+    }
+    var target = this._get(el);
+    if (target) {
+      delete target.events[type];
+    }
+  };
+  
+  EventManager.prototype.fire = function (el, type, e) {
+    var target = this._get(el);
+    var handler, el;
+    if (target) {
+      el = target.el;
+      handler = target.events[type];
+      if (typeof handler === 'function') {
+        return handler.call(el, e);
+      }
+    }
+  };
+
+/***/ },
+/* 104 */
+/***/ function(module, exports) {
+
+  'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.Document = Document;
+  exports.destroyDocument = destroyDocument;
+  exports.Node = Node;
+  exports.Element = Element;
+  exports.Comment = Comment;
+  /**
+   * @fileOverview
+   * A simple virtual dom implementation
+   */
+  
+  var DEFAULT_TAG_NAME = 'div';
+  
+  var instanceMap = exports.instanceMap = {};
+  
+  function Document(id) {
+    id = id ? id.toString() : '';
+    this.id = id;
+    this.nextRef = 1;
+    this.nodeMap = {};
+    this.listener = null;
+    this.eventManager = null;
+    this.closed = false;
+    instanceMap[id] = this;
+  
+    this.createDocumentElement();
+  }
+  
+  function destroyDocument(id) {
+    delete instanceMap[id];
+  }
+  
+  Document.prototype.open = function () {
+    this.closed = false;
+    if (this.listener) {
+      this.listener.batched = false;
+    }
+  };
+  Document.prototype.close = function () {
+    this.closed = true;
+    if (this.listener) {
+      this.listener.batched = true;
+    }
+  };
+  
+  Document.prototype.setEventManager = function (eventManager) {
+    this.eventManager = eventManager;
+  };
+  
+  Document.prototype.setListener = function (listener) {
+    this.listener = listener;
+    listener.batched = !!this.closed;
+  };
+  
+  Document.prototype.addRef = function (el) {
+    el.ref = this.nextRef.toString();
+    this.nodeMap[el.ref] = el;
+    this.nextRef++;
+  };
+  
+  Document.prototype.getRef = function (ref) {
+    return this.nodeMap[ref];
+  };
+  
+  Document.prototype.removeRef = function (ref) {
+    delete this.nodeMap[ref];
+  };
+  
+  Document.prototype.createDocumentElement = function (type, props) {
+    if (!this.documentElement) {
+      this.documentElement = new Element(type, props, this);
+      this.nodeMap._documentElement = this.documentElement;
+      this.documentElement.ref = '_documentElement';
+      this.documentElement.attached = true;
+    }
+  
+    return this.documentElement;
+  };
+  
+  Document.prototype.createBody = function (type, props) {
+    if (!this.body) {
+      this.body = new Element(type, props, this);
+      this.nodeMap._root = this.body;
+      this.body.ref = '_root';
+      this.body.depth = 1;
+    }
+  
+    return this.body;
+  };
+  
+  Document.prototype.createElement = function (tagName, props) {
+    return new Element(tagName, props, this);
+  };
+  
+  Document.prototype.createComment = function (text) {
+    return new Comment(text, this);
+  };
+  
+  function Node() {}
+  
+  Node.prototype.create = function (instanceId) {
+    this.parentRef = null;
+    this.attached = false;
+    if (instanceId) {
+      this.instanceId = instanceId;
+      var doc = instanceMap[instanceId];
+      doc.addRef(this);
+    }
+  };
+  
+  Node.prototype.destroy = function () {
+    var ref = this.ref;
+    var instanceId = this.instanceId;
+    if (instanceId) {
+      var doc = instanceMap[instanceId];
+      doc.removeRef(ref);
+    }
+  
+    var children = this.children || [];
+    var length = children.length;
+    for (var i = 0; i < length; i++) {
+      children[i].destroy();
+    }
+  };
+  
+  Node.prototype.getRenderer = function () {
+    var doc = instanceMap[this.instanceId];
+    return doc.listener;
+  };
+  
+  Node.prototype.next = function () {
+    var instanceId = this.instanceId;
+    var doc = instanceMap[instanceId];
+    var parent = doc.getRef(this.parentRef);
+    if (parent) {
+      return parent.children[parent.children.indexOf(this) + 1];
+    }
+  };
+  
+  Node.prototype.prev = function () {
+    var instanceId = this.instanceId;
+    var doc = instanceMap[instanceId];
+    var parent = doc.getRef(this.parentRef);
+    if (parent) {
+      return parent.children[parent.children.indexOf(this) - 1];
+    }
+  };
+  
+  function Element() {
+    var type = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_TAG_NAME : arguments[0];
+    var props = arguments[1];
+    var ownerDocument = arguments[2];
+  
+    props = props || {};
+    this.create(ownerDocument.id);
+    this.ownerDocument = ownerDocument;
+    this.type = type;
+    this.attr = props.attr || {};
+    this.classStyle = props.classStyle || {};
+    this.style = props.style || {};
+    this.event = [];
+    this.children = [];
+    this.pureChildren = [];
+  }
+  
+  Element.prototype = new Node();
+  
+  Element.prototype.appendChild = function (node) {
+  
+    removeIfExisted(node);
+    node.parentRef = this.ref;
+    this.children.push(node);
+  
+    if (this.attached) {
+      setAttached(node, this.depth);
+    } else {
+      setDetached(node);
+    }
+  
+    if (node instanceof Element) {
+      this.pureChildren.push(node);
+  
+      if (this.attached) {
+        var renderer = this.getRenderer();
+        if (renderer) {
+          if (this.ref === '_documentElement') {
+            // if its parent is documentElement then it's a body
+            renderer.createBody(node, this.ref);
+          } else {
+            renderer.addElement(node, this.ref);
+          }
+        }
+      }
+    }
+  };
+  
+  Element.prototype.insertBefore = function (node, before) {
+  
+    if (node.parentRef === this.ref) {
+      moveBefore(node, before, this.children);
+      if (node instanceof Element) {
+        var pureBeforeIndex = movePureBefore(node, before, this.pureChildren);
+        if (pureBeforeIndex >= 0 && this.attached) {
+          var renderer = this.getRenderer();
+          if (renderer) {
+            renderer.moveElement(node.ref, this.ref, pureBeforeIndex);
+          }
+        }
+      }
+      return;
+    }
+  
+    removeIfExisted(node);
+  
+    var children = this.children;
+    var index = children.indexOf(before);
+  
+    node.parentRef = this.ref;
+    if (this.attached) {
+      setAttached(node, this.depth);
+    } else {
+      setDetached(node);
+    }
+    children.splice(index, 0, node);
+  
+    if (node instanceof Element) {
+      var pureChildren = this.pureChildren;
+      var pureIndex = getPureAfter(before, pureChildren);
+  
+      pureChildren.splice(pureIndex, 0, node);
+  
+      if (this.attached) {
+        var _renderer = this.getRenderer();
+        if (_renderer) {
+          _renderer.addElement(node, this.ref, pureIndex);
+        }
+      }
+    }
+  };
+  
+  Element.prototype.insertAfter = function (node, after) {
+  
+    if (node.parentRef === this.ref) {
+      moveAfter(node, after, this.children);
+      if (node instanceof Element) {
+        var pureAfterIndex = movePureAfter(node, after, this.pureChildren);
+        if (pureAfterIndex >= 0 && this.attached) {
+          var renderer = this.getRenderer();
+          if (renderer) {
+            renderer.moveElement(node.ref, this.ref, pureAfterIndex);
+          }
+        }
+      }
+      return;
+    }
+  
+    removeIfExisted(node);
+  
+    var children = this.children;
+    var index = children.indexOf(after);
+  
+    node.parentRef = this.ref;
+    if (this.attached) {
+      setAttached(node, this.depth);
+    } else {
+      setDetached(node);
+    }
+    children.splice(index + 1, 0, node);
+  
+    if (node instanceof Element) {
+      var pureChildren = this.pureChildren;
+      var pureIndex = getPureBefore(after, pureChildren);
+  
+      pureChildren.splice(pureIndex + 1, 0, node);
+  
+      if (this.attached) {
+        var _renderer2 = this.getRenderer();
+        if (_renderer2) {
+          _renderer2.addElement(node, this.ref, pureIndex + 1);
+        }
+      }
+    }
+  };
+  
+  Element.prototype.removeChild = function (node, preserved) {
+    var children = this.children;
+    var index = children.indexOf(node);
+  
+    setDetached(node);
+  
+    if (index >= 0) {
+      node.parentRef = null;
+      children.splice(index, 1);
+      if (!preserved) {
+        node.destroy();
+      }
+    }
+  
+    if (node instanceof Element) {
+      this.pureChildren.$remove(node);
+      if (this.attached) {
+        var renderer = this.getRenderer();
+        if (renderer) {
+          renderer.removeElement(node.ref);
+        }
+      }
+    }
+  };
+  
+  Element.prototype.clear = function () {
+    var children = this.children;
+    var length = children.length;
+    for (var i = 0; i < length; i++) {
+      var child = children[i];
+      child.parentRef = null;
+      setDetached(child);
+      child.destroy();
+    }
+    children.length = 0;
+  
+    if (this.attached) {
+      var refs = this.pureChildren.map(function (child) {
+        return child.ref;
+      });
+      this.pureChildren.length = 0;
+      var renderer = this.getRenderer();
+      if (renderer) {
+        renderer.removeElement(refs);
+      }
+    }
+  };
+  
+  function moveBefore(node, before, children) {
+    var targetIndex = children.indexOf(node);
+    var beforeIndex = children.indexOf(before);
+  
+    /* istanbul ignore next */
+    if (targetIndex === beforeIndex || targetIndex + 1 === beforeIndex) {
+      return -1;
+    }
+  
+    var newIndex = targetIndex < beforeIndex ? beforeIndex - 1 : beforeIndex;
+    children.splice(targetIndex, 1);
+    children.splice(newIndex, 0, node);
+  
+    return beforeIndex;
+  }
+  
+  function movePureBefore(node, before, pureChildren) {
+    var pureTargetIndex = pureChildren.indexOf(node);
+    var pureBeforeIndex = getPureAfter(before, pureChildren);
+  
+    /* istanbul ignore next */
+    if (pureTargetIndex === pureBeforeIndex || pureTargetIndex + 1 === pureBeforeIndex) {
+      return -1;
+    }
+  
+    var pureNewIndex = pureTargetIndex < pureBeforeIndex ? pureBeforeIndex - 1 : pureBeforeIndex;
+  
+    pureChildren.splice(pureTargetIndex, 1);
+    pureChildren.splice(pureNewIndex, 0, node);
+  
+    return pureBeforeIndex;
+  }
+  
+  function getPureAfter(node, pureChildren) {
+    var pureIndex = pureChildren.indexOf(node);
+    while (node && pureIndex < 0) {
+      node = node.next();
+      pureIndex = pureChildren.indexOf(node);
+    }
+    if (pureIndex < 0) {
+      pureIndex = pureChildren.length;
+    }
+    return pureIndex;
+  }
+  
+  function moveAfter(node, after, children) {
+    var targetIndex = children.indexOf(node);
+    var afterIndex = children.indexOf(after);
+  
+    /* istanbul ignore next */
+    if (targetIndex === afterIndex || targetIndex === afterIndex + 1) {
+      return -1;
+    }
+  
+    var newIndex = targetIndex < afterIndex ? afterIndex : afterIndex + 1;
+    children.splice(targetIndex, 1);
+    children.splice(newIndex, 0, node);
+  
+    return afterIndex;
+  }
+  
+  function movePureAfter(node, after, pureChildren) {
+    var pureTargetIndex = pureChildren.indexOf(node);
+    var pureAfterIndex = getPureBefore(after, pureChildren);
+  
+    /* istanbul ignore next */
+    if (pureTargetIndex === pureAfterIndex || pureTargetIndex === pureAfterIndex + 1) {
+      return -1;
+    }
+  
+    var pureNewIndex = pureTargetIndex < pureAfterIndex ? pureAfterIndex : pureAfterIndex + 1;
+  
+    pureChildren.splice(pureTargetIndex, 1);
+    pureChildren.splice(pureNewIndex, 0, node);
+  
+    return pureAfterIndex + 1;
+  }
+  
+  function getPureBefore(node, pureChildren) {
+    var pureIndex = pureChildren.indexOf(node);
+    while (node && pureIndex < 0) {
+      node = node.prev();
+      pureIndex = pureChildren.indexOf(node);
+    }
+    /* istanbul ignore next */
+    if (pureIndex < 0) {
+      pureIndex = -1;
+    }
+    return pureIndex;
+  }
+  
+  function setAttached(node, depth) {
+    if (node.ref === '_root') {
+      depth = 1;
+    } else {
+      depth = depth > 0 ? depth + 1 : 0;
+    }
+    node.attached = true;
+    node.depth = depth;
+    if (node.children) {
+      node.children.forEach(function (sub) {
+        setAttached(sub, depth);
+      });
+    }
+  }
+  
+  function setDetached(node) {
+    node.attached = false;
+    node.depth = 0;
+    if (node.children) {
+      node.children.forEach(function (sub) {
+        setDetached(sub);
+      });
+    }
+  }
+  
+  function removeIfExisted(node) {
+    var doc = instanceMap[node.instanceId];
+    if (doc) {
+      var existedNode = doc.getRef(node.ref);
+      if (existedNode) {
+        var existedParent = doc.getRef(existedNode.parentRef);
+        if (existedParent && existedParent.removeChild) {
+          existedParent.removeChild(existedNode, true);
+        }
+      }
+    }
+  }
+  
+  Element.prototype.setAttr = function (key, value) {
+    if (this.attr[key] === value) {
+      return;
+    }
+    this.attr[key] = value;
+    if (this.attached) {
+      var renderer = this.getRenderer();
+      if (renderer) {
+        renderer.setAttr(this.ref, key, value);
+      }
+    }
+  };
+  
+  Element.prototype.setStyle = function (key, value) {
+    if (this.style[key] === value) {
+      return;
+    }
+    this.style[key] = value;
+    if (this.attached) {
+      var renderer = this.getRenderer();
+      if (renderer) {
+        renderer.setStyle(this.ref, key, value);
+      }
+    }
+  };
+  
+  Element.prototype.setClassStyle = function (classStyle) {
+    this.classStyle = classStyle;
+    if (this.attached) {
+      var renderer = this.getRenderer();
+      if (renderer) {
+        renderer.setStyles(this.ref, this.toStyle());
+      }
+    }
+  };
+  
+  Element.prototype.addEvent = function (type, handler) {
+    var index = this.event.indexOf(type);
+  
+    if (index < 0) {
+      this.event.push(type);
+      var eventManager = this.ownerDocument.eventManager;
+      eventManager.add(this, type, handler);
+  
+      if (this.attached) {
+        var renderer = this.getRenderer();
+        if (renderer) {
+          renderer.addEvent(this.ref, type);
+        }
+      }
+    }
+  };
+  
+  Element.prototype.removeEvent = function (type) {
+    var index = this.event.indexOf(type);
+  
+    if (index >= 0) {
+      this.event.splice(index, 1);
+      var eventManager = this.ownerDocument.eventManager;
+      eventManager.remove(this, type);
+  
+      if (this.attached) {
+        var renderer = this.getRenderer();
+        if (renderer) {
+          renderer.removeEvent(this.ref, type);
+        }
+      }
+    }
+  };
+  
+  Element.prototype.toStyle = function () {
+    var result = {};
+    var classStyle = this.classStyle;
+    var style = this.style;
+    for (var name in classStyle) {
+      result[name] = classStyle[name];
+    }
+    for (var _name in style) {
+      result[_name] = style[_name];
+    }
+    return result;
+  };
+  
+  Element.prototype.toJSON = function () {
+    var result = {
+      ref: this.ref.toString(),
+      type: this.type,
+      attr: this.attr,
+      style: this.toStyle()
+    };
+  
+    if (this.event && this.event.length) {
+      result.event = this.event;
+    }
+    if (this.pureChildren && this.pureChildren.length) {
+      result.children = this.pureChildren.map(function (child) {
+        return child.toJSON();
+      });
+    }
+  
+    return result;
+  };
+  
+  Element.prototype.toString = function () {
+    return '<' + this.type + ' attr=' + JSON.stringify(this.attr) + ' style=' + JSON.stringify(this.toStyle()) + '>' + this.pureChildren.map(function (child) {
+      return child.toString();
+    }).join('') + '</' + this.type + '>';
+  };
+  
+  function Comment(value, ownerDocument) {
+    this.create(ownerDocument.id);
+    this.type = 'comment';
+    this.value = value;
+  }
+  
+  Comment.prototype = new Node();
+  
+  Comment.prototype.toString = function () {
+    return '<!-- ' + this.value + ' -->';
+  };
+
+/***/ },
+/* 105 */
+/***/ function(module, exports) {
+
+  module.exports = {
+    "name": "weex-jsframework",
+    "version": "0.13.7",
+    "description": "JS Framework for Weex solution which is a extendable cross-platform solution for dynamic programming and publishing projects",
+    "main": "index.js",
+    "scripts": {
+      "dev": "webpack --watch --config ./webpack.config.js",
+      "build": "webpack --config ./webpack.config.js",
+      "compress": "uglifyjs dist/index.js -o dist/index.min.js",
+      "lint": "jscs --config .jscsrc polyfill/*.js polyfill/__test__/*.js lib/*.js lib/__test__/*.js lib/app/*.js lib/app/__test__/*.js lib/vm/*.js lib/vm/__test__/*.js",
+      "test": "mocha --compilers js:babel-core/register polyfill/__test__/*.js lib/__test__/*.js lib/**/__test__/*.js",
+      "cover": "babel-node node_modules/isparta/bin/isparta cover --report text node_modules/mocha/bin/_mocha -- --reporter dot lib/__test__/*.js lib/**/__test__/*.js",
+      "ci": "npm run lint && npm run cover"
+    },
+    "repository": {
+      "type": "git",
+      "url": "git@github.com:alibaba/weex.git"
+    },
+    "author": [
+      {
+        "name": "jinjiang",
+        "email": "zhaojinjiang@me.com"
+      },
+      {
+        "name": "Terry King",
+        "email": "terrykingcha@gmail.com"
+      }
+    ],
+    "contributors": [
+      {
+        "name": "pushiming",
+        "email": "pushiming@gmail.com"
+      },
+      {
+        "name": "iskenhuang",
+        "email": "iskenhuang@gmail.com"
+      },
+      {
+        "name": "yuanyan",
+        "email": "yuanyan.cao@gmail.com"
+      }
+    ],
+    "keywords": [
+      "weex",
+      "mvvm",
+      "browser",
+      "hybrid",
+      "framework"
+    ],
+    "license": "Apache-2.0",
+    "dependencies": {
+      "semver": "~5.1.0",
+      "core-js": "~2.1.1"
+    },
+    "devDependencies": {
+      "babel-cli": "~6.4.5",
+      "babel-core": "~6.4.5",
+      "babel-loader": "~6.2.1",
+      "babel-preset-es2015": "~6.3.13",
+      "chai": "~3.2.0",
+      "isparta": "~4.0.0",
+      "istanbul": "~0.4.2",
+      "jscs": "~2.9.0",
+      "json-loader": "^0.5.4",
+      "mocha": "~2.3.4",
+      "sinon": "~1.17.2",
+      "sinon-chai": "~2.8.0",
+      "uglify-js": "^2.6.2",
+      "watch-cli": "~0.2.1",
+      "webpack": "~1.12.12"
+    },
+    "optionalDependencies": {
+      "weex-transformer": "~0.3"
+    }
+  };
+
+/***/ },
+/* 106 */
+/***/ function(module, exports, __webpack_require__) {
+
+  /* WEBPACK VAR INJECTION */(function(global) {'use strict';
+  
+  Object.defineProperty(exports, "__esModule", {
+    value: true
+  });
+  exports.$ = $;
+  exports.$el = $el;
+  exports.$vm = $vm;
+  exports.$renderThen = $renderThen;
+  exports.$scrollTo = $scrollTo;
+  exports.$transition = $transition;
+  exports.$getConfig = $getConfig;
+  exports.$sendHttp = $sendHttp;
+  exports.$openURL = $openURL;
+  exports.$setTitle = $setTitle;
+  exports.$call = $call;
+  
+  var _util = __webpack_require__(81);
+  
+  /**
+   * ==========================================================
+   * common
+   * ==========================================================
+   */
+  
+  /**
+   * @deprecated use $vm instead
+   * find the vm by id
+   * Note: there is only one id in whole component
+   * @param  {string} id
+   * @return {Vm}
+   */
+  function $(id) {
+    nativeLog('[WARNING] the Vm#$ api is deprecated, please use Vm#$vm instead');
+    var info = this._ids[id];
+    if (info) {
+      return info.vm;
+    }
+  }
+  
+  /**
+   * find the element by id
+   * Note: there is only one id in whole component
+   * @param  {string} id
+   * @return {Element}
+   */
+  /**
+   * @fileOverview The api for invoking with "$" prefix
+   */
+  function $el(id) {
+    var info = this._ids[id];
+    if (info) {
+      return info.el;
+    }
+  }
+  
+  /**
+   * find the vm of the custom component by id
+   * Note: there is only one id in whole component
+   * @param  {string} id
+   * @return {Vm}
+   */
+  function $vm(id) {
+    var info = this._ids[id];
+    if (info) {
+      return info.vm;
+    }
+  }
+  
+  /**
+   * Fire when differ rendering finished
+   *
+   * @param  {Function} fn
+   */
+  function $renderThen(fn) {
+    var app = this._app;
+    var differ = app.differ;
+    return differ.then(function () {
+      fn();
+    });
+  }
+  
+  /**
+   * scroll an element specified by id into view, 
+   * moreover specify a number of offset optionally
+   * @param  {string} id
+   * @param  {number} offset
+   */
+  function $scrollTo(id, offset) {
+    var el = this.$el(id);
+    if (el) {
+      var dom = this._app.requireModule('dom');
+      dom.scrollToElement(el.ref, { offset: offset });
+    }
+  }
+  
+  /**
+   * perform transition animation on an element specified by id
+   * @param  {string}   id
+   * @param  {object}   options
+   * @param  {object}   options.styles
+   * @param  {object}   options.duration(ms)
+   * @param  {object}   [options.timingFunction]
+   * @param  {object}   [options.delay=0(ms)]
+   * @param  {Function} callback
+   */
+  function $transition(id, options, callback) {
+    var _this = this;
+  
+    var el = this.$el(id);
+    if (el && options && options.styles) {
+      var animation = this._app.requireModule('animation');
+      animation.transition(el.ref, options, function () {
+        _this._setStyle(el, options.styles);
+        callback && callback.apply(undefined, arguments);
+      });
+    }
+  }
+  
+  /**
+   * get some config
+   * @return {object} some config for app instance
+   * @property {string} bundleUrl
+   * @property {boolean} debug
+   * @property {object} env
+   * @property {string} env.weexVersion(ex. 1.0.0)
+   * @property {string} env.appName(ex. TB/TM)
+   * @property {string} env.appVersion(ex. 5.0.0)
+   * @property {string} env.platform(ex. iOS/Android)
+   * @property {string} env.osVersion(ex. 7.0.0)
+   * @property {string} env.deviceModel **native only**
+   * @property {number} env.[deviceWidth=750]
+   * @property {number} env.deviceHeight
+   */
+  function $getConfig(callback) {
+    var config = (0, _util.extend)({
+      env: global.WXEnvironment || {}
+    }, this._app.options);
+    if ((0, _util.typof)(callback) === 'function') {
+      nativeLog('[WARNING] the callback of Vm#$getConfig(callback) is deprecated, ' + 'this api now can directly RETURN config info.');
+      callback(config);
+    }
+    return config;
+  }
+  
+  /**
+   * request network via http protocol
+   * @param  {object}   params
+   * @param  {Function} callback
+   */
+  function $sendHttp(params, callback) {
+    var stream = this._app.requireModule('stream');
+    stream.sendHttp(params, callback);
+  }
+  
+  /**
+   * open a url
+   * @param  {string} url
+   */
+  function $openURL(url) {
+    var event = this._app.requireModule('event');
+    event.openURL(url);
+  }
+  
+  /**
+   * set a title for page
+   * @param  {string} title
+   */
+  function $setTitle(title) {
+    var pageInfo = this._app.requireModule('pageInfo');
+    pageInfo.setTitle(title);
+  }
+  
+  /**
+   * invoke a native method by specifing the name of module and method
+   * @param  {string} moduleName
+   * @param  {string} methodName
+   * @param  {...*} the rest arguments
+   */
+  function $call(moduleName, methodName) {
+    var module = this._app.requireModule(moduleName);
+    if (module && module[methodName]) {
+      for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+        args[_key - 2] = arguments[_key];
+      }
+  
+      module[methodName].apply(module, args);
+    }
+  }
+  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
+
+/***/ }
+/******/ ]);
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgNGE5MjBlZjkyNzA3MDg5NWViMDIiLCJ3ZWJwYWNrOi8vLy4vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcG9seWZpbGwvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vcG9seWZpbGwvb2JqZWN0QXNzaWduLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9mbi9vYmplY3QvYXNzaWduLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuYXNzaWduLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fY29yZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faGlkZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19mYWlscy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19wcm9wZXJ0eS1kZXNjLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faGFzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL191aWQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2N0eC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fYS1mdW5jdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWFzc2lnbi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19pb2JqZWN0LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19jb2YuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3RvLWludGVnZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3RvLWluZGV4LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19zaGFyZWQta2V5LmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19zaGFyZWQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2VudW0tYnVnLWtleXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtcGllLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vLy4vcG9seWZpbGwvcHJvbWlzZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fY2xhc3NvZi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1hdC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faXRlci1kZWZpbmUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2xpYnJhcnkuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXJhdG9ycy5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faXRlci1jcmVhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1jcmVhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcHMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2h0bWwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3NldC10by1zdHJpbmctdGFnLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19hZGQtdG8tdW5zY29wYWJsZXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9lczYucHJvbWlzZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fYW4taW5zdGFuY2UuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2Zvci1vZi5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faXRlci1jYWxsLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fc3BlY2llcy1jb25zdHJ1Y3Rvci5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fdGFzay5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9faW52b2tlLmpzIiwid2VicGFjazovLy8uL34vY29yZS1qcy9tb2R1bGVzL19taWNyb3Rhc2suanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLWFsbC5qcyIsIndlYnBhY2s6Ly8vLi9+L2NvcmUtanMvbW9kdWxlcy9fc2V0LXNwZWNpZXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGV0ZWN0LmpzIiwid2VicGFjazovLy8uL3BvbHlmaWxsL3NldFRpbWVvdXQuanMiLCJ3ZWJwYWNrOi8vLy4vcG9seWZpbGwvY29uc29sZWxvZy5qcyIsIndlYnBhY2s6Ly8vLi9saWIvZnJhbWV3b3JrLmpzIiwid2VicGFjazovLy8uL2xpYi9wZXJmLmpzIiwid2VicGFjazovLy8uL2xpYi9sb2cuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2NvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL2luZGV4LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsL2luZGV4LmpzIiwid2VicGFjazovLy8uL2xpYi9hcHAvYnVuZGxlLmpzIiwid2VicGFjazovLy8uL34vc2VtdmVyL3NlbXZlci5qcyIsIndlYnBhY2s6Ly8vLi9+L3Byb2Nlc3MvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdm0vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL2luc3RhbmNlL3Njb3BlLmpzIiwid2VicGFjazovLy8uL2xpYi92bS91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi92bS9vYnNlcnZlci9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdm0vY29uZmlnLmpzIiwid2VicGFjazovLy8uL2xpYi92bS9vYnNlcnZlci9kZXAuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL29ic2VydmVyL2FycmF5LmpzIiwid2VicGFjazovLy8uL2xpYi92bS9vYnNlcnZlci9vYmplY3QuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL2NvbXBpbGVyLmpzIiwid2VicGFjazovLy8uL2xpYi92bS9kaXJlY3RpdmUuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL3dhdGNoZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL2RvbS1oZWxwZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3ZtL2V2ZW50cy5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL3JlZ2lzdGVyLmpzIiwid2VicGFjazovLy8uL2xpYi9hcHAvZG93bmdyYWRlLmpzIiwid2VicGFjazovLy8uL2xpYi9hcHAvY3RybC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL2RvbS1saXN0ZW5lci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL2RpZmZlci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXBwL2V2ZW50LmpzIiwid2VicGFjazovLy8uL2xpYi9hcHAvZG9tLmpzIiwid2VicGFjazovLy8uL3BhY2thZ2UuanNvbiIsIndlYnBhY2s6Ly8vLi9saWIvYXBpL21ldGhvZHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7QUN0Q0E7O0FBQ0E7O0tBQVksUzs7QUFDWjs7Ozs0QkFFUyxVO0FBQ0wsWUFBTyxVQUFQLElBQXFCLFlBQW1CO0FBQ3BDLGFBQU0sTUFBTSxVQUFVLFVBQVYsNkJBQVo7QUFDQSxhQUFJLGVBQWUsS0FBbkIsRUFBMEI7QUFDdEIscUJBQVEsS0FBUixDQUFjLElBQUksUUFBSixFQUFkO0FBQ0gsVUFGRCxNQUVPLElBQUksZUFBZSxLQUFuQixFQUEwQjtBQUM3QixpQkFBSSxPQUFKLENBQVksYUFBSztBQUNiLHFCQUFJLGFBQWEsS0FBakIsRUFBd0I7QUFDcEIsNkJBQVEsS0FBUixDQUFjLEVBQUUsUUFBRixFQUFkO0FBQ0g7QUFDSixjQUpEO0FBS0g7QUFDRCxnQkFBTyxHQUFQO0FBQ0gsTUFaRDs7O0FBREosTUFBSyxJQUFJLFVBQVQsSUFBdUIsU0FBdkIsRUFBa0M7QUFBQSxXQUF6QixVQUF5QjtBQWNqQzs7QUFFRCxRQUFPLE1BQVAsQ0FBYyxNQUFkLEVBQXNCO0FBQ2xCLHVDQURrQjtBQUVsQiw2QkFBd0IsOEJBQXFCLGtCQUFyQjtBQUZOLEVBQXRCOzs7OztBQVFBLEtBQU0sVUFBVSxvQkFBUSxHQUFSLENBQWhCO2VB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Q0Q7Ozs7Ozs7QUFPTSxVQUFTLFNBQVQsQ0FBbUIsTUFBbkIsRUFBMkIsUUFBM0IsRUFBcUM7QUFDMUMsT0FBTSxTQUFTLEtBQUssSUFBTCxDQUFVLGFBQVYsQ0FBd0IsUUFBeEIsQ0FBZjtBQUNBLFVBQU8sUUFBUCxDQUFnQixNQUFoQixFQUF3QixRQUF4QjtBQUNEOzs7Ozs7QUFNTSxVQUFTLFFBQVQsQ0FBa0IsR0FBbEIsRUFBdUI7QUFDNUIsT0FBTSxRQUFRLEtBQUssSUFBTCxDQUFVLGFBQVYsQ0FBd0IsT0FBeEIsQ0FBZDtBQUNBLFNBQU0sT0FBTixDQUFjLEdBQWQ7QUFDRDs7Ozs7O0FBTU0sVUFBUyxTQUFULENBQW1CLEtBQW5CLEVBQTBCO0FBQy9CLE9BQU0sV0FBVyxLQUFLLElBQUwsQ0FBVSxhQUFWLENBQXdCLFVBQXhCLENBQWpCO0FBQ0EsWUFBUyxRQUFULENBQWtCLEtBQWxCO0FBQ0Q7Ozs7Ozs7O0FBUU0sVUFBUyxLQUFULENBQWUsVUFBZixFQUEyQixVQUEzQixFQUFnRDtBQUNyRCxPQUFNLFNBQVMsS0FBSyxJQUFMLENBQVUsYUFBVixDQUF3QixVQUF4QixDQUFmO0FBQ0EsT0FBSSxVQUFVLE9BQU8sVUFBUCxDQUFkLEVBQWtDO0FBQUEsdUNBRmEsSUFFYjtBQUZhLFdBRWI7QUFBQTs7QUFDaEMsWUFBTyxVQUFQLGdCQUFzQixJQUF0QjtBQUNEO0FBQ0YsRSIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKVxuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuXG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRleHBvcnRzOiB7fSxcbiBcdFx0XHRpZDogbW9kdWxlSWQsXG4gXHRcdFx0bG9hZGVkOiBmYWxzZVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogd2VicGFjay9ib290c3RyYXAgNGE5MjBlZjkyNzA3MDg5NWViMDJcbiAqKi8iLCJpbXBvcnQgJy4vcG9seWZpbGwnXG5pbXBvcnQgKiBhcyBmcmFtZXdvcmsgZnJvbSAnLi9saWIvZnJhbWV3b3JrJ1xuaW1wb3J0IHt2ZXJzaW9uLCBvcHRpb25hbERlcGVuZGVuY2llc30gZnJvbSAnLi9wYWNrYWdlLmpzb24nXG5cbmZvciAobGV0IG1ldGhvZE5hbWUgaW4gZnJhbWV3b3JrKSB7XG4gICAgZ2xvYmFsW21ldGhvZE5hbWVdID0gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgY29uc3QgcmV0ID0gZnJhbWV3b3JrW21ldGhvZE5hbWVdKC4uLmFyZ3MpXG4gICAgICAgIGlmIChyZXQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihyZXQudG9TdHJpbmcoKSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgcmV0LmZvckVhY2gociA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHIudG9TdHJpbmcoKSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXRcbiAgICB9XG59XG5cbk9iamVjdC5hc3NpZ24oZ2xvYmFsLCB7XG4gICAgZnJhbWV3b3JrVmVyc2lvbjogdmVyc2lvbixcbiAgICBuZWVkVHJhbnNmb3JtZXJWZXJzaW9uOiBvcHRpb25hbERlcGVuZGVuY2llc1snd2VleC10cmFuc2Zvcm1lciddXG59KVxuXG4vKipcbiAqIHJlZ2lzdGVyIG1ldGhvZHNcbiAqL1xuY29uc3QgbWV0aG9kcyA9IHJlcXVpcmUoJy4vbGliL2FwaS9tZXRob2RzJylcbmNvbnN0IHtyZWdpc3Rlck1ldGhvZHN9ID0gZ2xvYmFsXG5yZWdpc3Rlck1ldGhvZHMobWV0aG9kcylcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vaW5kZXguanNcbiAqKi8iLCJpbXBvcnQgJy4vb2JqZWN0QXNzaWduJ1xuaW1wb3J0ICcuL3Byb21pc2UnXG5pbXBvcnQgJy4vc2V0VGltZW91dCdcbmltcG9ydCAnLi9jb25zb2xlbG9nJ1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9wb2x5ZmlsbC9pbmRleC5qc1xuICoqLyIsImltcG9ydCAnY29yZS1qcy9mbi9vYmplY3QvYXNzaWduJ1xuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9wb2x5ZmlsbC9vYmplY3RBc3NpZ24uanNcbiAqKi8iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5vYmplY3QuYXNzaWduJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5PYmplY3QuYXNzaWduO1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL2ZuL29iamVjdC9hc3NpZ24uanNcbiAqKi8iLCIvLyAxOS4xLjMuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYsICdPYmplY3QnLCB7YXNzaWduOiByZXF1aXJlKCcuL19vYmplY3QtYXNzaWduJyl9KTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuYXNzaWduLmpzXG4gKiovIiwidmFyIGdsb2JhbCAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgY29yZSAgICAgID0gcmVxdWlyZSgnLi9fY29yZScpXG4gICwgaGlkZSAgICAgID0gcmVxdWlyZSgnLi9faGlkZScpXG4gICwgcmVkZWZpbmUgID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKVxuICAsIGN0eCAgICAgICA9IHJlcXVpcmUoJy4vX2N0eCcpXG4gICwgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XG5cbnZhciAkZXhwb3J0ID0gZnVuY3Rpb24odHlwZSwgbmFtZSwgc291cmNlKXtcbiAgdmFyIElTX0ZPUkNFRCA9IHR5cGUgJiAkZXhwb3J0LkZcbiAgICAsIElTX0dMT0JBTCA9IHR5cGUgJiAkZXhwb3J0LkdcbiAgICAsIElTX1NUQVRJQyA9IHR5cGUgJiAkZXhwb3J0LlNcbiAgICAsIElTX1BST1RPICA9IHR5cGUgJiAkZXhwb3J0LlBcbiAgICAsIElTX0JJTkQgICA9IHR5cGUgJiAkZXhwb3J0LkJcbiAgICAsIHRhcmdldCAgICA9IElTX0dMT0JBTCA/IGdsb2JhbCA6IElTX1NUQVRJQyA/IGdsb2JhbFtuYW1lXSB8fCAoZ2xvYmFsW25hbWVdID0ge30pIDogKGdsb2JhbFtuYW1lXSB8fCB7fSlbUFJPVE9UWVBFXVxuICAgICwgZXhwb3J0cyAgID0gSVNfR0xPQkFMID8gY29yZSA6IGNvcmVbbmFtZV0gfHwgKGNvcmVbbmFtZV0gPSB7fSlcbiAgICAsIGV4cFByb3RvICA9IGV4cG9ydHNbUFJPVE9UWVBFXSB8fCAoZXhwb3J0c1tQUk9UT1RZUEVdID0ge30pXG4gICAgLCBrZXksIG93biwgb3V0LCBleHA7XG4gIGlmKElTX0dMT0JBTClzb3VyY2UgPSBuYW1lO1xuICBmb3Ioa2V5IGluIHNvdXJjZSl7XG4gICAgLy8gY29udGFpbnMgaW4gbmF0aXZlXG4gICAgb3duID0gIUlTX0ZPUkNFRCAmJiB0YXJnZXQgJiYgdGFyZ2V0W2tleV0gIT09IHVuZGVmaW5lZDtcbiAgICAvLyBleHBvcnQgbmF0aXZlIG9yIHBhc3NlZFxuICAgIG91dCA9IChvd24gPyB0YXJnZXQgOiBzb3VyY2UpW2tleV07XG4gICAgLy8gYmluZCB0aW1lcnMgdG8gZ2xvYmFsIGZvciBjYWxsIGZyb20gZXhwb3J0IGNvbnRleHRcbiAgICBleHAgPSBJU19CSU5EICYmIG93biA/IGN0eChvdXQsIGdsb2JhbCkgOiBJU19QUk9UTyAmJiB0eXBlb2Ygb3V0ID09ICdmdW5jdGlvbicgPyBjdHgoRnVuY3Rpb24uY2FsbCwgb3V0KSA6IG91dDtcbiAgICAvLyBleHRlbmQgZ2xvYmFsXG4gICAgaWYodGFyZ2V0KXJlZGVmaW5lKHRhcmdldCwga2V5LCBvdXQsIHR5cGUgJiAkZXhwb3J0LlUpO1xuICAgIC8vIGV4cG9ydFxuICAgIGlmKGV4cG9ydHNba2V5XSAhPSBvdXQpaGlkZShleHBvcnRzLCBrZXksIGV4cCk7XG4gICAgaWYoSVNfUFJPVE8gJiYgZXhwUHJvdG9ba2V5XSAhPSBvdXQpZXhwUHJvdG9ba2V5XSA9IG91dDtcbiAgfVxufTtcbmdsb2JhbC5jb3JlID0gY29yZTtcbi8vIHR5cGUgYml0bWFwXG4kZXhwb3J0LkYgPSAxOyAgIC8vIGZvcmNlZFxuJGV4cG9ydC5HID0gMjsgICAvLyBnbG9iYWxcbiRleHBvcnQuUyA9IDQ7ICAgLy8gc3RhdGljXG4kZXhwb3J0LlAgPSA4OyAgIC8vIHByb3RvXG4kZXhwb3J0LkIgPSAxNjsgIC8vIGJpbmRcbiRleHBvcnQuVyA9IDMyOyAgLy8gd3JhcFxuJGV4cG9ydC5VID0gNjQ7ICAvLyBzYWZlXG4kZXhwb3J0LlIgPSAxMjg7IC8vIHJlYWwgcHJvdG8gbWV0aG9kIGZvciBgbGlicmFyeWAgXG5tb2R1bGUuZXhwb3J0cyA9ICRleHBvcnQ7XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXG4gKiovIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzg2I2lzc3VlY29tbWVudC0xMTU3NTkwMjhcbnZhciBnbG9iYWwgPSBtb2R1bGUuZXhwb3J0cyA9IHR5cGVvZiB3aW5kb3cgIT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Lk1hdGggPT0gTWF0aFxuICA/IHdpbmRvdyA6IHR5cGVvZiBzZWxmICE9ICd1bmRlZmluZWQnICYmIHNlbGYuTWF0aCA9PSBNYXRoID8gc2VsZiA6IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5pZih0eXBlb2YgX19nID09ICdudW1iZXInKV9fZyA9IGdsb2JhbDsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZlxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1xuICoqLyIsInZhciBjb3JlID0gbW9kdWxlLmV4cG9ydHMgPSB7dmVyc2lvbjogJzIuMS41J307XG5pZih0eXBlb2YgX19lID09ICdudW1iZXInKV9fZSA9IGNvcmU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzXG4gKiovIiwidmFyIGRQICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKVxuICAsIGNyZWF0ZURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBmdW5jdGlvbihvYmplY3QsIGtleSwgdmFsdWUpe1xuICByZXR1cm4gZFAuZihvYmplY3QsIGtleSwgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xufSA6IGZ1bmN0aW9uKG9iamVjdCwga2V5LCB2YWx1ZSl7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIHJldHVybiBvYmplY3Q7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2hpZGUuanNcbiAqKi8iLCJ2YXIgYW5PYmplY3QgICAgICAgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxuICAsIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi9faWU4LWRvbS1kZWZpbmUnKVxuICAsIHRvUHJpbWl0aXZlICAgID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJylcbiAgLCBkUCAgICAgICAgICAgICA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpe1xuICBhbk9iamVjdChPKTtcbiAgUCA9IHRvUHJpbWl0aXZlKFAsIHRydWUpO1xuICBhbk9iamVjdChBdHRyaWJ1dGVzKTtcbiAgaWYoSUU4X0RPTV9ERUZJTkUpdHJ5IHtcbiAgICByZXR1cm4gZFAoTywgUCwgQXR0cmlidXRlcyk7XG4gIH0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cbiAgaWYoJ2dldCcgaW4gQXR0cmlidXRlcyB8fCAnc2V0JyBpbiBBdHRyaWJ1dGVzKXRocm93IFR5cGVFcnJvcignQWNjZXNzb3JzIG5vdCBzdXBwb3J0ZWQhJyk7XG4gIGlmKCd2YWx1ZScgaW4gQXR0cmlidXRlcylPW1BdID0gQXR0cmlidXRlcy52YWx1ZTtcbiAgcmV0dXJuIE87XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qc1xuICoqLyIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIGlmKCFpc09iamVjdChpdCkpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYW4gb2JqZWN0IScpO1xuICByZXR1cm4gaXQ7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gdHlwZW9mIGl0ID09PSAnb2JqZWN0JyA/IGl0ICE9PSBudWxsIDogdHlwZW9mIGl0ID09PSAnZnVuY3Rpb24nO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9ICFyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XHJcbiAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2RpdicpLCAnYScsIHtnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiA3OyB9fSkuYSAhPSA3O1xyXG59KTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19pZTgtZG9tLWRlZmluZS5qc1xuICoqLyIsIi8vIFRoYW5rJ3MgSUU4IGZvciBoaXMgZnVubnkgZGVmaW5lUHJvcGVydHlcbm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24oKXtcbiAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7Z2V0OiBmdW5jdGlvbigpeyByZXR1cm4gNzsgfX0pLmEgIT0gNztcbn0pO1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXG4gKiovIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihleGVjKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gISFleGVjKCk7XG4gIH0gY2F0Y2goZSl7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcbiAqKi8iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGRvY3VtZW50ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuZG9jdW1lbnRcbiAgLy8gaW4gb2xkIElFIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50IGlzICdvYmplY3QnXG4gICwgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGlzID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChpdCkgOiB7fTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qc1xuICoqLyIsIi8vIDcuMS4xIFRvUHJpbWl0aXZlKGlucHV0IFssIFByZWZlcnJlZFR5cGVdKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG4vLyBpbnN0ZWFkIG9mIHRoZSBFUzYgc3BlYyB2ZXJzaW9uLCB3ZSBkaWRuJ3QgaW1wbGVtZW50IEBAdG9QcmltaXRpdmUgY2FzZVxuLy8gYW5kIHRoZSBzZWNvbmQgYXJndW1lbnQgLSBmbGFnIC0gcHJlZmVycmVkIHR5cGUgaXMgYSBzdHJpbmdcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIFMpe1xuICBpZighaXNPYmplY3QoaXQpKXJldHVybiBpdDtcbiAgdmFyIGZuLCB2YWw7XG4gIGlmKFMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpcmV0dXJuIHZhbDtcbiAgaWYodHlwZW9mIChmbiA9IGl0LnZhbHVlT2YpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSlyZXR1cm4gdmFsO1xuICBpZighUyAmJiB0eXBlb2YgKGZuID0gaXQudG9TdHJpbmcpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSlyZXR1cm4gdmFsO1xuICB0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYml0bWFwLCB2YWx1ZSl7XG4gIHJldHVybiB7XG4gICAgZW51bWVyYWJsZSAgOiAhKGJpdG1hcCAmIDEpLFxuICAgIGNvbmZpZ3VyYWJsZTogIShiaXRtYXAgJiAyKSxcbiAgICB3cml0YWJsZSAgICA6ICEoYml0bWFwICYgNCksXG4gICAgdmFsdWUgICAgICAgOiB2YWx1ZVxuICB9O1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19wcm9wZXJ0eS1kZXNjLmpzXG4gKiovIiwidmFyIGdsb2JhbCAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgaGlkZSAgICAgID0gcmVxdWlyZSgnLi9faGlkZScpXG4gICwgaGFzICAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcbiAgLCBTUkMgICAgICAgPSByZXF1aXJlKCcuL191aWQnKSgnc3JjJylcbiAgLCBUT19TVFJJTkcgPSAndG9TdHJpbmcnXG4gICwgJHRvU3RyaW5nID0gRnVuY3Rpb25bVE9fU1RSSU5HXVxuICAsIFRQTCAgICAgICA9ICgnJyArICR0b1N0cmluZykuc3BsaXQoVE9fU1RSSU5HKTtcblxucmVxdWlyZSgnLi9fY29yZScpLmluc3BlY3RTb3VyY2UgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiAkdG9TdHJpbmcuY2FsbChpdCk7XG59O1xuXG4obW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihPLCBrZXksIHZhbCwgc2FmZSl7XG4gIHZhciBpc0Z1bmN0aW9uID0gdHlwZW9mIHZhbCA9PSAnZnVuY3Rpb24nO1xuICBpZihpc0Z1bmN0aW9uKWhhcyh2YWwsICduYW1lJykgfHwgaGlkZSh2YWwsICduYW1lJywga2V5KTtcbiAgaWYoT1trZXldID09PSB2YWwpcmV0dXJuO1xuICBpZihpc0Z1bmN0aW9uKWhhcyh2YWwsIFNSQykgfHwgaGlkZSh2YWwsIFNSQywgT1trZXldID8gJycgKyBPW2tleV0gOiBUUEwuam9pbihTdHJpbmcoa2V5KSkpO1xuICBpZihPID09PSBnbG9iYWwpe1xuICAgIE9ba2V5XSA9IHZhbDtcbiAgfSBlbHNlIHtcbiAgICBpZighc2FmZSl7XG4gICAgICBkZWxldGUgT1trZXldO1xuICAgICAgaGlkZShPLCBrZXksIHZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmKE9ba2V5XSlPW2tleV0gPSB2YWw7XG4gICAgICBlbHNlIGhpZGUoTywga2V5LCB2YWwpO1xuICAgIH1cbiAgfVxuLy8gYWRkIGZha2UgRnVuY3Rpb24jdG9TdHJpbmcgZm9yIGNvcnJlY3Qgd29yayB3cmFwcGVkIG1ldGhvZHMgLyBjb25zdHJ1Y3RvcnMgd2l0aCBtZXRob2RzIGxpa2UgTG9EYXNoIGlzTmF0aXZlXG59KShGdW5jdGlvbi5wcm90b3R5cGUsIFRPX1NUUklORywgZnVuY3Rpb24gdG9TdHJpbmcoKXtcbiAgcmV0dXJuIHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgJiYgdGhpc1tTUkNdIHx8ICR0b1N0cmluZy5jYWxsKHRoaXMpO1xufSk7XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUuanNcbiAqKi8iLCJ2YXIgaGFzT3duUHJvcGVydHkgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIGtleSl7XG4gIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGl0LCBrZXkpO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19oYXMuanNcbiAqKi8iLCJ2YXIgaWQgPSAwXG4gICwgcHggPSBNYXRoLnJhbmRvbSgpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihrZXkpe1xuICByZXR1cm4gJ1N5bWJvbCgnLmNvbmNhdChrZXkgPT09IHVuZGVmaW5lZCA/ICcnIDoga2V5LCAnKV8nLCAoKytpZCArIHB4KS50b1N0cmluZygzNikpO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL191aWQuanNcbiAqKi8iLCIvLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZuLCB0aGF0LCBsZW5ndGgpe1xuICBhRnVuY3Rpb24oZm4pO1xuICBpZih0aGF0ID09PSB1bmRlZmluZWQpcmV0dXJuIGZuO1xuICBzd2l0Y2gobGVuZ3RoKXtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbihhKXtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEpO1xuICAgIH07XG4gICAgY2FzZSAyOiByZXR1cm4gZnVuY3Rpb24oYSwgYil7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKGEsIGIsIGMpe1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24oLyogLi4uYXJncyAqLyl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoYXQsIGFyZ3VtZW50cyk7XG4gIH07XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2N0eC5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICBpZih0eXBlb2YgaXQgIT0gJ2Z1bmN0aW9uJyl0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBhIGZ1bmN0aW9uIScpO1xuICByZXR1cm4gaXQ7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2EtZnVuY3Rpb24uanNcbiAqKi8iLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjIuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlLCAuLi4pXG52YXIgZ2V0S2V5cyAgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpXG4gICwgZ09QUyAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wcycpXG4gICwgcElFICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJylcbiAgLCB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpXG4gICwgSU9iamVjdCAgPSByZXF1aXJlKCcuL19pb2JqZWN0JylcbiAgLCAkYXNzaWduICA9IE9iamVjdC5hc3NpZ247XG5cbi8vIHNob3VsZCB3b3JrIHdpdGggc3ltYm9scyBhbmQgc2hvdWxkIGhhdmUgZGV0ZXJtaW5pc3RpYyBwcm9wZXJ0eSBvcmRlciAoVjggYnVnKVxubW9kdWxlLmV4cG9ydHMgPSAhJGFzc2lnbiB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XG4gIHZhciBBID0ge31cbiAgICAsIEIgPSB7fVxuICAgICwgUyA9IFN5bWJvbCgpXG4gICAgLCBLID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0JztcbiAgQVtTXSA9IDc7XG4gIEsuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24oayl7IEJba10gPSBrOyB9KTtcbiAgcmV0dXJuICRhc3NpZ24oe30sIEEpW1NdICE9IDcgfHwgT2JqZWN0LmtleXMoJGFzc2lnbih7fSwgQikpLmpvaW4oJycpICE9IEs7XG59KSA/IGZ1bmN0aW9uIGFzc2lnbih0YXJnZXQsIHNvdXJjZSl7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgdmFyIFQgICAgID0gdG9PYmplY3QodGFyZ2V0KVxuICAgICwgYUxlbiAgPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgLCBpbmRleCA9IDFcbiAgICAsIGdldFN5bWJvbHMgPSBnT1BTLmZcbiAgICAsIGlzRW51bSAgICAgPSBwSUUuZjtcbiAgd2hpbGUoYUxlbiA+IGluZGV4KXtcbiAgICB2YXIgUyAgICAgID0gSU9iamVjdChhcmd1bWVudHNbaW5kZXgrK10pXG4gICAgICAsIGtleXMgICA9IGdldFN5bWJvbHMgPyBnZXRLZXlzKFMpLmNvbmNhdChnZXRTeW1ib2xzKFMpKSA6IGdldEtleXMoUylcbiAgICAgICwgbGVuZ3RoID0ga2V5cy5sZW5ndGhcbiAgICAgICwgaiAgICAgID0gMFxuICAgICAgLCBrZXk7XG4gICAgd2hpbGUobGVuZ3RoID4gailpZihpc0VudW0uY2FsbChTLCBrZXkgPSBrZXlzW2orK10pKVRba2V5XSA9IFNba2V5XTtcbiAgfSByZXR1cm4gVDtcbn0gOiAkYXNzaWduO1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1hc3NpZ24uanNcbiAqKi8iLCIvLyAxOS4xLjIuMTQgLyAxNS4yLjMuMTQgT2JqZWN0LmtleXMoTylcclxudmFyICRrZXlzICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMtaW50ZXJuYWwnKVxyXG4gICwgZW51bUJ1Z0tleXMgPSByZXF1aXJlKCcuL19lbnVtLWJ1Zy1rZXlzJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIGtleXMoTyl7XHJcbiAgcmV0dXJuICRrZXlzKE8sIGVudW1CdWdLZXlzKTtcclxufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy5qc1xuICoqLyIsInZhciBoYXMgICAgICAgICAgPSByZXF1aXJlKCcuL19oYXMnKVxyXG4gICwgdG9JT2JqZWN0ICAgID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpXHJcbiAgLCBhcnJheUluZGV4T2YgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKGZhbHNlKVxyXG4gICwgSUVfUFJPVE8gICAgID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvYmplY3QsIG5hbWVzKXtcclxuICB2YXIgTyAgICAgID0gdG9JT2JqZWN0KG9iamVjdClcclxuICAgICwgaSAgICAgID0gMFxyXG4gICAgLCByZXN1bHQgPSBbXVxyXG4gICAgLCBrZXk7XHJcbiAgZm9yKGtleSBpbiBPKWlmKGtleSAhPSBJRV9QUk9UTyloYXMoTywga2V5KSAmJiByZXN1bHQucHVzaChrZXkpO1xyXG4gIC8vIERvbid0IGVudW0gYnVnICYgaGlkZGVuIGtleXNcclxuICB3aGlsZShuYW1lcy5sZW5ndGggPiBpKWlmKGhhcyhPLCBrZXkgPSBuYW1lc1tpKytdKSl7XHJcbiAgICB+YXJyYXlJbmRleE9mKHJlc3VsdCwga2V5KSB8fCByZXN1bHQucHVzaChrZXkpO1xyXG4gIH1cclxuICByZXR1cm4gcmVzdWx0O1xyXG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzXG4gKiovIiwiLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKVxuICAsIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzXG4gKiovIiwiLy8gZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBhbmQgbm9uLWVudW1lcmFibGUgb2xkIFY4IHN0cmluZ3NcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0KCd6JykucHJvcGVydHlJc0VudW1lcmFibGUoMCkgPyBPYmplY3QgOiBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBjb2YoaXQpID09ICdTdHJpbmcnID8gaXQuc3BsaXQoJycpIDogT2JqZWN0KGl0KTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faW9iamVjdC5qc1xuICoqLyIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoaXQpLnNsaWNlKDgsIC0xKTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fY29mLmpzXG4gKiovIiwiLy8gNy4yLjEgUmVxdWlyZU9iamVjdENvZXJjaWJsZShhcmd1bWVudClcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICBpZihpdCA9PSB1bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanNcbiAqKi8iLCIvLyBmYWxzZSAtPiBBcnJheSNpbmRleE9mXG4vLyB0cnVlICAtPiBBcnJheSNpbmNsdWRlc1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKVxuICAsIHRvTGVuZ3RoICA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpXG4gICwgdG9JbmRleCAgID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oSVNfSU5DTFVERVMpe1xuICByZXR1cm4gZnVuY3Rpb24oJHRoaXMsIGVsLCBmcm9tSW5kZXgpe1xuICAgIHZhciBPICAgICAgPSB0b0lPYmplY3QoJHRoaXMpXG4gICAgICAsIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKVxuICAgICAgLCBpbmRleCAgPSB0b0luZGV4KGZyb21JbmRleCwgbGVuZ3RoKVxuICAgICAgLCB2YWx1ZTtcbiAgICAvLyBBcnJheSNpbmNsdWRlcyB1c2VzIFNhbWVWYWx1ZVplcm8gZXF1YWxpdHkgYWxnb3JpdGhtXG4gICAgaWYoSVNfSU5DTFVERVMgJiYgZWwgIT0gZWwpd2hpbGUobGVuZ3RoID4gaW5kZXgpe1xuICAgICAgdmFsdWUgPSBPW2luZGV4KytdO1xuICAgICAgaWYodmFsdWUgIT0gdmFsdWUpcmV0dXJuIHRydWU7XG4gICAgLy8gQXJyYXkjdG9JbmRleCBpZ25vcmVzIGhvbGVzLCBBcnJheSNpbmNsdWRlcyAtIG5vdFxuICAgIH0gZWxzZSBmb3IoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKWlmKElTX0lOQ0xVREVTIHx8IGluZGV4IGluIE8pe1xuICAgICAgaWYoT1tpbmRleF0gPT09IGVsKXJldHVybiBJU19JTkNMVURFUyB8fCBpbmRleDtcbiAgICB9IHJldHVybiAhSVNfSU5DTFVERVMgJiYgLTE7XG4gIH07XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzXG4gKiovIiwiLy8gNy4xLjE1IFRvTGVuZ3RoXG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpXG4gICwgbWluICAgICAgID0gTWF0aC5taW47XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGl0ID4gMCA/IG1pbih0b0ludGVnZXIoaXQpLCAweDFmZmZmZmZmZmZmZmZmKSA6IDA7IC8vIHBvdygyLCA1MykgLSAxID09IDkwMDcxOTkyNTQ3NDA5OTFcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzXG4gKiovIiwiLy8gNy4xLjQgVG9JbnRlZ2VyXG52YXIgY2VpbCAgPSBNYXRoLmNlaWxcbiAgLCBmbG9vciA9IE1hdGguZmxvb3I7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGlzTmFOKGl0ID0gK2l0KSA/IDAgOiAoaXQgPiAwID8gZmxvb3IgOiBjZWlsKShpdCk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3RvLWludGVnZXIuanNcbiAqKi8iLCJ2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpXG4gICwgbWF4ICAgICAgID0gTWF0aC5tYXhcbiAgLCBtaW4gICAgICAgPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5kZXgsIGxlbmd0aCl7XG4gIGluZGV4ID0gdG9JbnRlZ2VyKGluZGV4KTtcbiAgcmV0dXJuIGluZGV4IDwgMCA/IG1heChpbmRleCArIGxlbmd0aCwgMCkgOiBtaW4oaW5kZXgsIGxlbmd0aCk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3RvLWluZGV4LmpzXG4gKiovIiwidmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCdrZXlzJylcclxuICAsIHVpZCAgICA9IHJlcXVpcmUoJy4vX3VpZCcpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGtleSl7XHJcbiAgcmV0dXJuIHNoYXJlZFtrZXldIHx8IChzaGFyZWRba2V5XSA9IHVpZChrZXkpKTtcclxufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19zaGFyZWQta2V5LmpzXG4gKiovIiwidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgU0hBUkVEID0gJ19fY29yZS1qc19zaGFyZWRfXydcbiAgLCBzdG9yZSAgPSBnbG9iYWxbU0hBUkVEXSB8fCAoZ2xvYmFsW1NIQVJFRF0gPSB7fSk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGtleSl7XG4gIHJldHVybiBzdG9yZVtrZXldIHx8IChzdG9yZVtrZXldID0ge30pO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19zaGFyZWQuanNcbiAqKi8iLCIvLyBJRSA4LSBkb24ndCBlbnVtIGJ1ZyBrZXlzXHJcbm1vZHVsZS5leHBvcnRzID0gKFxyXG4gICdjb25zdHJ1Y3RvcixoYXNPd25Qcm9wZXJ0eSxpc1Byb3RvdHlwZU9mLHByb3BlcnR5SXNFbnVtZXJhYmxlLHRvTG9jYWxlU3RyaW5nLHRvU3RyaW5nLHZhbHVlT2YnXHJcbikuc3BsaXQoJywnKTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19lbnVtLWJ1Zy1rZXlzLmpzXG4gKiovIiwiZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wcy5qc1xuICoqLyIsImV4cG9ydHMuZiA9IHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1waWUuanNcbiAqKi8iLCIvLyA3LjEuMTMgVG9PYmplY3QoYXJndW1lbnQpXG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fdG8tb2JqZWN0LmpzXG4gKiovIiwiLy8gZml4IFByb21pc2UgUHJvYmxlbSBvbiBKU0NvbnRleHQgb2YgaU9TN344XG4vLyBAc2VlIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzU4NjZcbmdsb2JhbC5Qcm9taXNlID0gbnVsbFxucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nJylcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJylcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlJylcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lczYucHJvbWlzZScpXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9wb2x5ZmlsbC9wcm9taXNlLmpzXG4gKiovIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKVxuICAsIHRlc3QgICAgPSB7fTtcbnRlc3RbcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyldID0gJ3onO1xuaWYodGVzdCArICcnICE9ICdbb2JqZWN0IHpdJyl7XG4gIHJlcXVpcmUoJy4vX3JlZGVmaW5lJykoT2JqZWN0LnByb3RvdHlwZSwgJ3RvU3RyaW5nJywgZnVuY3Rpb24gdG9TdHJpbmcoKXtcbiAgICByZXR1cm4gJ1tvYmplY3QgJyArIGNsYXNzb2YodGhpcykgKyAnXSc7XG4gIH0sIHRydWUpO1xufVxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcuanNcbiAqKi8iLCIvLyBnZXR0aW5nIHRhZyBmcm9tIDE5LjEuMy42IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcoKVxudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpXG4gICwgVEFHID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJylcbiAgLy8gRVMzIHdyb25nIGhlcmVcbiAgLCBBUkcgPSBjb2YoZnVuY3Rpb24oKXsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKSA9PSAnQXJndW1lbnRzJztcblxuLy8gZmFsbGJhY2sgZm9yIElFMTEgU2NyaXB0IEFjY2VzcyBEZW5pZWQgZXJyb3JcbnZhciB0cnlHZXQgPSBmdW5jdGlvbihpdCwga2V5KXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gaXRba2V5XTtcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHZhciBPLCBULCBCO1xuICByZXR1cm4gaXQgPT09IHVuZGVmaW5lZCA/ICdVbmRlZmluZWQnIDogaXQgPT09IG51bGwgPyAnTnVsbCdcbiAgICAvLyBAQHRvU3RyaW5nVGFnIGNhc2VcbiAgICA6IHR5cGVvZiAoVCA9IHRyeUdldChPID0gT2JqZWN0KGl0KSwgVEFHKSkgPT0gJ3N0cmluZycgPyBUXG4gICAgLy8gYnVpbHRpblRhZyBjYXNlXG4gICAgOiBBUkcgPyBjb2YoTylcbiAgICAvLyBFUzMgYXJndW1lbnRzIGZhbGxiYWNrXG4gICAgOiAoQiA9IGNvZihPKSkgPT0gJ09iamVjdCcgJiYgdHlwZW9mIE8uY2FsbGVlID09ICdmdW5jdGlvbicgPyAnQXJndW1lbnRzJyA6IEI7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2NsYXNzb2YuanNcbiAqKi8iLCJ2YXIgc3RvcmUgICAgICA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCd3a3MnKVxuICAsIHVpZCAgICAgICAgPSByZXF1aXJlKCcuL191aWQnKVxuICAsIFN5bWJvbCAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5TeW1ib2xcbiAgLCBVU0VfU1lNQk9MID0gdHlwZW9mIFN5bWJvbCA9PSAnZnVuY3Rpb24nO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihuYW1lKXtcbiAgcmV0dXJuIHN0b3JlW25hbWVdIHx8IChzdG9yZVtuYW1lXSA9XG4gICAgVVNFX1NZTUJPTCAmJiBTeW1ib2xbbmFtZV0gfHwgKFVTRV9TWU1CT0wgPyBTeW1ib2wgOiB1aWQpKCdTeW1ib2wuJyArIG5hbWUpKTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXG4gKiovIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRhdCAgPSByZXF1aXJlKCcuL19zdHJpbmctYXQnKSh0cnVlKTtcblxuLy8gMjEuMS4zLjI3IFN0cmluZy5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxucmVxdWlyZSgnLi9faXRlci1kZWZpbmUnKShTdHJpbmcsICdTdHJpbmcnLCBmdW5jdGlvbihpdGVyYXRlZCl7XG4gIHRoaXMuX3QgPSBTdHJpbmcoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbi8vIDIxLjEuNS4yLjEgJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uKCl7XG4gIHZhciBPICAgICA9IHRoaXMuX3RcbiAgICAsIGluZGV4ID0gdGhpcy5faVxuICAgICwgcG9pbnQ7XG4gIGlmKGluZGV4ID49IE8ubGVuZ3RoKXJldHVybiB7dmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZX07XG4gIHBvaW50ID0gJGF0KE8sIGluZGV4KTtcbiAgdGhpcy5faSArPSBwb2ludC5sZW5ndGg7XG4gIHJldHVybiB7dmFsdWU6IHBvaW50LCBkb25lOiBmYWxzZX07XG59KTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanNcbiAqKi8iLCJ2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpXG4gICwgZGVmaW5lZCAgID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuLy8gdHJ1ZSAgLT4gU3RyaW5nI2F0XG4vLyBmYWxzZSAtPiBTdHJpbmcjY29kZVBvaW50QXRcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oVE9fU1RSSU5HKXtcbiAgcmV0dXJuIGZ1bmN0aW9uKHRoYXQsIHBvcyl7XG4gICAgdmFyIHMgPSBTdHJpbmcoZGVmaW5lZCh0aGF0KSlcbiAgICAgICwgaSA9IHRvSW50ZWdlcihwb3MpXG4gICAgICAsIGwgPSBzLmxlbmd0aFxuICAgICAgLCBhLCBiO1xuICAgIGlmKGkgPCAwIHx8IGkgPj0gbClyZXR1cm4gVE9fU1RSSU5HID8gJycgOiB1bmRlZmluZWQ7XG4gICAgYSA9IHMuY2hhckNvZGVBdChpKTtcbiAgICByZXR1cm4gYSA8IDB4ZDgwMCB8fCBhID4gMHhkYmZmIHx8IGkgKyAxID09PSBsIHx8IChiID0gcy5jaGFyQ29kZUF0KGkgKyAxKSkgPCAweGRjMDAgfHwgYiA+IDB4ZGZmZlxuICAgICAgPyBUT19TVFJJTkcgPyBzLmNoYXJBdChpKSA6IGFcbiAgICAgIDogVE9fU1RSSU5HID8gcy5zbGljZShpLCBpICsgMikgOiAoYSAtIDB4ZDgwMCA8PCAxMCkgKyAoYiAtIDB4ZGMwMCkgKyAweDEwMDAwO1xuICB9O1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19zdHJpbmctYXQuanNcbiAqKi8iLCIndXNlIHN0cmljdCc7XG52YXIgTElCUkFSWSAgICAgICAgPSByZXF1aXJlKCcuL19saWJyYXJ5JylcbiAgLCAkZXhwb3J0ICAgICAgICA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpXG4gICwgcmVkZWZpbmUgICAgICAgPSByZXF1aXJlKCcuL19yZWRlZmluZScpXG4gICwgaGlkZSAgICAgICAgICAgPSByZXF1aXJlKCcuL19oaWRlJylcbiAgLCBoYXMgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2hhcycpXG4gICwgSXRlcmF0b3JzICAgICAgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKVxuICAsICRpdGVyQ3JlYXRlICAgID0gcmVxdWlyZSgnLi9faXRlci1jcmVhdGUnKVxuICAsIHNldFRvU3RyaW5nVGFnID0gcmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKVxuICAsIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpXG4gICwgSVRFUkFUT1IgICAgICAgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKVxuICAsIEJVR0dZICAgICAgICAgID0gIShbXS5rZXlzICYmICduZXh0JyBpbiBbXS5rZXlzKCkpIC8vIFNhZmFyaSBoYXMgYnVnZ3kgaXRlcmF0b3JzIHcvbyBgbmV4dGBcbiAgLCBGRl9JVEVSQVRPUiAgICA9ICdAQGl0ZXJhdG9yJ1xuICAsIEtFWVMgICAgICAgICAgID0gJ2tleXMnXG4gICwgVkFMVUVTICAgICAgICAgPSAndmFsdWVzJztcblxudmFyIHJldHVyblRoaXMgPSBmdW5jdGlvbigpeyByZXR1cm4gdGhpczsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihCYXNlLCBOQU1FLCBDb25zdHJ1Y3RvciwgbmV4dCwgREVGQVVMVCwgSVNfU0VULCBGT1JDRUQpe1xuICAkaXRlckNyZWF0ZShDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCk7XG4gIHZhciBnZXRNZXRob2QgPSBmdW5jdGlvbihraW5kKXtcbiAgICBpZighQlVHR1kgJiYga2luZCBpbiBwcm90bylyZXR1cm4gcHJvdG9ba2luZF07XG4gICAgc3dpdGNoKGtpbmQpe1xuICAgICAgY2FzZSBLRVlTOiByZXR1cm4gZnVuY3Rpb24ga2V5cygpeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgICAgY2FzZSBWQUxVRVM6IHJldHVybiBmdW5jdGlvbiB2YWx1ZXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICB9IHJldHVybiBmdW5jdGlvbiBlbnRyaWVzKCl7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gIH07XG4gIHZhciBUQUcgICAgICAgID0gTkFNRSArICcgSXRlcmF0b3InXG4gICAgLCBERUZfVkFMVUVTID0gREVGQVVMVCA9PSBWQUxVRVNcbiAgICAsIFZBTFVFU19CVUcgPSBmYWxzZVxuICAgICwgcHJvdG8gICAgICA9IEJhc2UucHJvdG90eXBlXG4gICAgLCAkbmF0aXZlICAgID0gcHJvdG9bSVRFUkFUT1JdIHx8IHByb3RvW0ZGX0lURVJBVE9SXSB8fCBERUZBVUxUICYmIHByb3RvW0RFRkFVTFRdXG4gICAgLCAkZGVmYXVsdCAgID0gJG5hdGl2ZSB8fCBnZXRNZXRob2QoREVGQVVMVClcbiAgICAsICRlbnRyaWVzICAgPSBERUZBVUxUID8gIURFRl9WQUxVRVMgPyAkZGVmYXVsdCA6IGdldE1ldGhvZCgnZW50cmllcycpIDogdW5kZWZpbmVkXG4gICAgLCAkYW55TmF0aXZlID0gTkFNRSA9PSAnQXJyYXknID8gcHJvdG8uZW50cmllcyB8fCAkbmF0aXZlIDogJG5hdGl2ZVxuICAgICwgbWV0aG9kcywga2V5LCBJdGVyYXRvclByb3RvdHlwZTtcbiAgLy8gRml4IG5hdGl2ZVxuICBpZigkYW55TmF0aXZlKXtcbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvdHlwZU9mKCRhbnlOYXRpdmUuY2FsbChuZXcgQmFzZSkpO1xuICAgIGlmKEl0ZXJhdG9yUHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlKXtcbiAgICAgIC8vIFNldCBAQHRvU3RyaW5nVGFnIHRvIG5hdGl2ZSBpdGVyYXRvcnNcbiAgICAgIHNldFRvU3RyaW5nVGFnKEl0ZXJhdG9yUHJvdG90eXBlLCBUQUcsIHRydWUpO1xuICAgICAgLy8gZml4IGZvciBzb21lIG9sZCBlbmdpbmVzXG4gICAgICBpZighTElCUkFSWSAmJiAhaGFzKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUikpaGlkZShJdGVyYXRvclByb3RvdHlwZSwgSVRFUkFUT1IsIHJldHVyblRoaXMpO1xuICAgIH1cbiAgfVxuICAvLyBmaXggQXJyYXkje3ZhbHVlcywgQEBpdGVyYXRvcn0ubmFtZSBpbiBWOCAvIEZGXG4gIGlmKERFRl9WQUxVRVMgJiYgJG5hdGl2ZSAmJiAkbmF0aXZlLm5hbWUgIT09IFZBTFVFUyl7XG4gICAgVkFMVUVTX0JVRyA9IHRydWU7XG4gICAgJGRlZmF1bHQgPSBmdW5jdGlvbiB2YWx1ZXMoKXsgcmV0dXJuICRuYXRpdmUuY2FsbCh0aGlzKTsgfTtcbiAgfVxuICAvLyBEZWZpbmUgaXRlcmF0b3JcbiAgaWYoKCFMSUJSQVJZIHx8IEZPUkNFRCkgJiYgKEJVR0dZIHx8IFZBTFVFU19CVUcgfHwgIXByb3RvW0lURVJBVE9SXSkpe1xuICAgIGhpZGUocHJvdG8sIElURVJBVE9SLCAkZGVmYXVsdCk7XG4gIH1cbiAgLy8gUGx1ZyBmb3IgbGlicmFyeVxuICBJdGVyYXRvcnNbTkFNRV0gPSAkZGVmYXVsdDtcbiAgSXRlcmF0b3JzW1RBR10gID0gcmV0dXJuVGhpcztcbiAgaWYoREVGQVVMVCl7XG4gICAgbWV0aG9kcyA9IHtcbiAgICAgIHZhbHVlczogIERFRl9WQUxVRVMgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChWQUxVRVMpLFxuICAgICAga2V5czogICAgSVNfU0VUICAgICA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKEtFWVMpLFxuICAgICAgZW50cmllczogJGVudHJpZXNcbiAgICB9O1xuICAgIGlmKEZPUkNFRClmb3Ioa2V5IGluIG1ldGhvZHMpe1xuICAgICAgaWYoIShrZXkgaW4gcHJvdG8pKXJlZGVmaW5lKHByb3RvLCBrZXksIG1ldGhvZHNba2V5XSk7XG4gICAgfSBlbHNlICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKEJVR0dZIHx8IFZBTFVFU19CVUcpLCBOQU1FLCBtZXRob2RzKTtcbiAgfVxuICByZXR1cm4gbWV0aG9kcztcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faXRlci1kZWZpbmUuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IGZhbHNlO1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2xpYnJhcnkuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXJhdG9ycy5qc1xuICoqLyIsIid1c2Ugc3RyaWN0JztcbnZhciBjcmVhdGUgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKVxuICAsIGRlc2NyaXB0b3IgICAgID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpXG4gICwgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpXG4gICwgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcblxuLy8gMjUuMS4yLjEuMSAlSXRlcmF0b3JQcm90b3R5cGUlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2hpZGUnKShJdGVyYXRvclByb3RvdHlwZSwgcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyksIGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzOyB9KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCl7XG4gIENvbnN0cnVjdG9yLnByb3RvdHlwZSA9IGNyZWF0ZShJdGVyYXRvclByb3RvdHlwZSwge25leHQ6IGRlc2NyaXB0b3IoMSwgbmV4dCl9KTtcbiAgc2V0VG9TdHJpbmdUYWcoQ29uc3RydWN0b3IsIE5BTUUgKyAnIEl0ZXJhdG9yJyk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY3JlYXRlLmpzXG4gKiovIiwiLy8gMTkuMS4yLjIgLyAxNS4yLjMuNSBPYmplY3QuY3JlYXRlKE8gWywgUHJvcGVydGllc10pXHJcbnZhciBhbk9iamVjdCAgICA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpXHJcbiAgLCBkUHMgICAgICAgICA9IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKVxyXG4gICwgZW51bUJ1Z0tleXMgPSByZXF1aXJlKCcuL19lbnVtLWJ1Zy1rZXlzJylcclxuICAsIElFX1BST1RPICAgID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpXHJcbiAgLCBFbXB0eSAgICAgICA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH1cclxuICAsIFBST1RPVFlQRSAgID0gJ3Byb3RvdHlwZSc7XHJcblxyXG4vLyBDcmVhdGUgb2JqZWN0IHdpdGggZmFrZSBgbnVsbGAgcHJvdG90eXBlOiB1c2UgaWZyYW1lIE9iamVjdCB3aXRoIGNsZWFyZWQgcHJvdG90eXBlXHJcbnZhciBjcmVhdGVEaWN0ID0gZnVuY3Rpb24oKXtcclxuICAvLyBUaHJhc2gsIHdhc3RlIGFuZCBzb2RvbXk6IElFIEdDIGJ1Z1xyXG4gIHZhciBpZnJhbWUgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2lmcmFtZScpXHJcbiAgICAsIGkgICAgICA9IGVudW1CdWdLZXlzLmxlbmd0aFxyXG4gICAgLCBndCAgICAgPSAnPidcclxuICAgICwgaWZyYW1lRG9jdW1lbnQ7XHJcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgcmVxdWlyZSgnLi9faHRtbCcpLmFwcGVuZENoaWxkKGlmcmFtZSk7XHJcbiAgaWZyYW1lLnNyYyA9ICdqYXZhc2NyaXB0Oic7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2NyaXB0LXVybFxyXG4gIC8vIGNyZWF0ZURpY3QgPSBpZnJhbWUuY29udGVudFdpbmRvdy5PYmplY3Q7XHJcbiAgLy8gaHRtbC5yZW1vdmVDaGlsZChpZnJhbWUpO1xyXG4gIGlmcmFtZURvY3VtZW50ID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQ7XHJcbiAgaWZyYW1lRG9jdW1lbnQub3BlbigpO1xyXG4gIGlmcmFtZURvY3VtZW50LndyaXRlKCc8c2NyaXB0PmRvY3VtZW50LkY9T2JqZWN0PC9zY3JpcHQnICsgZ3QpO1xyXG4gIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XHJcbiAgY3JlYXRlRGljdCA9IGlmcmFtZURvY3VtZW50LkY7XHJcbiAgd2hpbGUoaS0tKWRlbGV0ZSBjcmVhdGVEaWN0W1BST1RPVFlQRV1bZW51bUJ1Z0tleXNbaV1dO1xyXG4gIHJldHVybiBjcmVhdGVEaWN0KCk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gY3JlYXRlKE8sIFByb3BlcnRpZXMpe1xyXG4gIHZhciByZXN1bHQ7XHJcbiAgaWYoTyAhPT0gbnVsbCl7XHJcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gYW5PYmplY3QoTyk7XHJcbiAgICByZXN1bHQgPSBuZXcgRW1wdHk7XHJcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gbnVsbDtcclxuICAgIC8vIGFkZCBcIl9fcHJvdG9fX1wiIGZvciBPYmplY3QuZ2V0UHJvdG90eXBlT2YgcG9seWZpbGxcclxuICAgIHJlc3VsdFtJRV9QUk9UT10gPSBPO1xyXG4gIH0gZWxzZSByZXN1bHQgPSBjcmVhdGVEaWN0KCk7XHJcbiAgcmV0dXJuIFByb3BlcnRpZXMgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IGRQcyhyZXN1bHQsIFByb3BlcnRpZXMpO1xyXG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1jcmVhdGUuanNcbiAqKi8iLCJ2YXIgZFAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKVxyXG4gICwgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKVxyXG4gICwgZ2V0S2V5cyAgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXMgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpe1xyXG4gIGFuT2JqZWN0KE8pO1xyXG4gIHZhciBrZXlzICAgPSBnZXRLZXlzKFByb3BlcnRpZXMpXHJcbiAgICAsIGxlbmd0aCA9IGtleXMubGVuZ3RoXHJcbiAgICAsIGkgPSAwXHJcbiAgICAsIFA7XHJcbiAgd2hpbGUobGVuZ3RoID4gaSlkUC5mKE8sIFAgPSBrZXlzW2krK10sIFByb3BlcnRpZXNbUF0pO1xyXG4gIHJldHVybiBPO1xyXG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcHMuanNcbiAqKi8iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19odG1sLmpzXG4gKiovIiwidmFyIGRlZiA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmZcbiAgLCBoYXMgPSByZXF1aXJlKCcuL19oYXMnKVxuICAsIFRBRyA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCB0YWcsIHN0YXQpe1xuICBpZihpdCAmJiAhaGFzKGl0ID0gc3RhdCA/IGl0IDogaXQucHJvdG90eXBlLCBUQUcpKWRlZihpdCwgVEFHLCB7Y29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogdGFnfSk7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3NldC10by1zdHJpbmctdGFnLmpzXG4gKiovIiwiLy8gMTkuMS4yLjkgLyAxNS4yLjMuMiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoTylcclxudmFyIGhhcyAgICAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcclxuICAsIHRvT2JqZWN0ICAgID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0JylcclxuICAsIElFX1BST1RPICAgID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpXHJcbiAgLCBPYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbihPKXtcclxuICBPID0gdG9PYmplY3QoTyk7XHJcbiAgaWYoaGFzKE8sIElFX1BST1RPKSlyZXR1cm4gT1tJRV9QUk9UT107XHJcbiAgaWYodHlwZW9mIE8uY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBPIGluc3RhbmNlb2YgTy5jb25zdHJ1Y3Rvcil7XHJcbiAgICByZXR1cm4gTy5jb25zdHJ1Y3Rvci5wcm90b3R5cGU7XHJcbiAgfSByZXR1cm4gTyBpbnN0YW5jZW9mIE9iamVjdCA/IE9iamVjdFByb3RvIDogbnVsbDtcclxufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzXG4gKiovIiwidmFyICRpdGVyYXRvcnMgICAgPSByZXF1aXJlKCcuL2VzNi5hcnJheS5pdGVyYXRvcicpXG4gICwgcmVkZWZpbmUgICAgICA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJylcbiAgLCBnbG9iYWwgICAgICAgID0gcmVxdWlyZSgnLi9fZ2xvYmFsJylcbiAgLCBoaWRlICAgICAgICAgID0gcmVxdWlyZSgnLi9faGlkZScpXG4gICwgSXRlcmF0b3JzICAgICA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpXG4gICwgd2tzICAgICAgICAgICA9IHJlcXVpcmUoJy4vX3drcycpXG4gICwgSVRFUkFUT1IgICAgICA9IHdrcygnaXRlcmF0b3InKVxuICAsIFRPX1NUUklOR19UQUcgPSB3a3MoJ3RvU3RyaW5nVGFnJylcbiAgLCBBcnJheVZhbHVlcyAgID0gSXRlcmF0b3JzLkFycmF5O1xuXG5mb3IodmFyIGNvbGxlY3Rpb25zID0gWydOb2RlTGlzdCcsICdET01Ub2tlbkxpc3QnLCAnTWVkaWFMaXN0JywgJ1N0eWxlU2hlZXRMaXN0JywgJ0NTU1J1bGVMaXN0J10sIGkgPSAwOyBpIDwgNTsgaSsrKXtcbiAgdmFyIE5BTUUgICAgICAgPSBjb2xsZWN0aW9uc1tpXVxuICAgICwgQ29sbGVjdGlvbiA9IGdsb2JhbFtOQU1FXVxuICAgICwgcHJvdG8gICAgICA9IENvbGxlY3Rpb24gJiYgQ29sbGVjdGlvbi5wcm90b3R5cGVcbiAgICAsIGtleTtcbiAgaWYocHJvdG8pe1xuICAgIGlmKCFwcm90b1tJVEVSQVRPUl0paGlkZShwcm90bywgSVRFUkFUT1IsIEFycmF5VmFsdWVzKTtcbiAgICBpZighcHJvdG9bVE9fU1RSSU5HX1RBR10paGlkZShwcm90bywgVE9fU1RSSU5HX1RBRywgTkFNRSk7XG4gICAgSXRlcmF0b3JzW05BTUVdID0gQXJyYXlWYWx1ZXM7XG4gICAgZm9yKGtleSBpbiAkaXRlcmF0b3JzKWlmKCFwcm90b1trZXldKXJlZGVmaW5lKHByb3RvLCBrZXksICRpdGVyYXRvcnNba2V5XSwgdHJ1ZSk7XG4gIH1cbn1cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUuanNcbiAqKi8iLCIndXNlIHN0cmljdCc7XG52YXIgYWRkVG9VbnNjb3BhYmxlcyA9IHJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpXG4gICwgc3RlcCAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXItc3RlcCcpXG4gICwgSXRlcmF0b3JzICAgICAgICA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpXG4gICwgdG9JT2JqZWN0ICAgICAgICA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcblxuLy8gMjIuMS4zLjQgQXJyYXkucHJvdG90eXBlLmVudHJpZXMoKVxuLy8gMjIuMS4zLjEzIEFycmF5LnByb3RvdHlwZS5rZXlzKClcbi8vIDIyLjEuMy4yOSBBcnJheS5wcm90b3R5cGUudmFsdWVzKClcbi8vIDIyLjEuMy4zMCBBcnJheS5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpKEFycmF5LCAnQXJyYXknLCBmdW5jdGlvbihpdGVyYXRlZCwga2luZCl7XG4gIHRoaXMuX3QgPSB0b0lPYmplY3QoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbiAgdGhpcy5fayA9IGtpbmQ7ICAgICAgICAgICAgICAgIC8vIGtpbmRcbi8vIDIyLjEuNS4yLjEgJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlLm5leHQoKVxufSwgZnVuY3Rpb24oKXtcbiAgdmFyIE8gICAgID0gdGhpcy5fdFxuICAgICwga2luZCAgPSB0aGlzLl9rXG4gICAgLCBpbmRleCA9IHRoaXMuX2krKztcbiAgaWYoIU8gfHwgaW5kZXggPj0gTy5sZW5ndGgpe1xuICAgIHRoaXMuX3QgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHN0ZXAoMSk7XG4gIH1cbiAgaWYoa2luZCA9PSAna2V5cycgIClyZXR1cm4gc3RlcCgwLCBpbmRleCk7XG4gIGlmKGtpbmQgPT0gJ3ZhbHVlcycpcmV0dXJuIHN0ZXAoMCwgT1tpbmRleF0pO1xuICByZXR1cm4gc3RlcCgwLCBbaW5kZXgsIE9baW5kZXhdXSk7XG59LCAndmFsdWVzJyk7XG5cbi8vIGFyZ3VtZW50c0xpc3RbQEBpdGVyYXRvcl0gaXMgJUFycmF5UHJvdG9fdmFsdWVzJSAoOS40LjQuNiwgOS40LjQuNylcbkl0ZXJhdG9ycy5Bcmd1bWVudHMgPSBJdGVyYXRvcnMuQXJyYXk7XG5cbmFkZFRvVW5zY29wYWJsZXMoJ2tleXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ3ZhbHVlcycpO1xuYWRkVG9VbnNjb3BhYmxlcygnZW50cmllcycpO1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yLmpzXG4gKiovIiwiLy8gMjIuMS4zLjMxIEFycmF5LnByb3RvdHlwZVtAQHVuc2NvcGFibGVzXVxudmFyIFVOU0NPUEFCTEVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3Vuc2NvcGFibGVzJylcbiAgLCBBcnJheVByb3RvICA9IEFycmF5LnByb3RvdHlwZTtcbmlmKEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdID09IHVuZGVmaW5lZClyZXF1aXJlKCcuL19oaWRlJykoQXJyYXlQcm90bywgVU5TQ09QQUJMRVMsIHt9KTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcbiAgQXJyYXlQcm90b1tVTlNDT1BBQkxFU11ba2V5XSA9IHRydWU7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZG9uZSwgdmFsdWUpe1xuICByZXR1cm4ge3ZhbHVlOiB2YWx1ZSwgZG9uZTogISFkb25lfTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faXRlci1zdGVwLmpzXG4gKiovIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKVxuICAsIGdsb2JhbCAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgY3R4ICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fY3R4JylcbiAgLCBjbGFzc29mICAgICAgICAgICAgPSByZXF1aXJlKCcuL19jbGFzc29mJylcbiAgLCAkZXhwb3J0ICAgICAgICAgICAgPSByZXF1aXJlKCcuL19leHBvcnQnKVxuICAsIGlzT2JqZWN0ICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpXG4gICwgYW5PYmplY3QgICAgICAgICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBhRnVuY3Rpb24gICAgICAgICAgPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJylcbiAgLCBhbkluc3RhbmNlICAgICAgICAgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpXG4gICwgZm9yT2YgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fZm9yLW9mJylcbiAgLCBzZXRQcm90byAgICAgICAgICAgPSByZXF1aXJlKCcuL19zZXQtcHJvdG8nKS5zZXRcbiAgLCBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19zcGVjaWVzLWNvbnN0cnVjdG9yJylcbiAgLCB0YXNrICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL190YXNrJykuc2V0XG4gICwgbWljcm90YXNrICAgICAgICAgID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJylcbiAgLCBQUk9NSVNFICAgICAgICAgICAgPSAnUHJvbWlzZSdcbiAgLCBUeXBlRXJyb3IgICAgICAgICAgPSBnbG9iYWwuVHlwZUVycm9yXG4gICwgcHJvY2VzcyAgICAgICAgICAgID0gZ2xvYmFsLnByb2Nlc3NcbiAgLCAkUHJvbWlzZSAgICAgICAgICAgPSBnbG9iYWxbUFJPTUlTRV1cbiAgLCBwcm9jZXNzICAgICAgICAgICAgPSBnbG9iYWwucHJvY2Vzc1xuICAsIGlzTm9kZSAgICAgICAgICAgICA9IGNsYXNzb2YocHJvY2VzcykgPT0gJ3Byb2Nlc3MnXG4gICwgZW1wdHkgICAgICAgICAgICAgID0gZnVuY3Rpb24oKXsgLyogZW1wdHkgKi8gfVxuICAsIEludGVybmFsLCBHZW5lcmljUHJvbWlzZUNhcGFiaWxpdHksIFdyYXBwZXI7XG5cbnZhciBVU0VfTkFUSVZFID0gISFmdW5jdGlvbigpe1xuICB0cnkge1xuICAgIC8vIGNvcnJlY3Qgc3ViY2xhc3Npbmcgd2l0aCBAQHNwZWNpZXMgc3VwcG9ydFxuICAgIHZhciBwcm9taXNlICAgICA9ICRQcm9taXNlLnJlc29sdmUoMSlcbiAgICAgICwgRmFrZVByb21pc2UgPSAocHJvbWlzZS5jb25zdHJ1Y3RvciA9IHt9KVtyZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpXSA9IGZ1bmN0aW9uKGV4ZWMpeyBleGVjKGVtcHR5LCBlbXB0eSk7IH07XG4gICAgLy8gdW5oYW5kbGVkIHJlamVjdGlvbnMgdHJhY2tpbmcgc3VwcG9ydCwgTm9kZUpTIFByb21pc2Ugd2l0aG91dCBpdCBmYWlscyBAQHNwZWNpZXMgdGVzdFxuICAgIHJldHVybiAoaXNOb2RlIHx8IHR5cGVvZiBQcm9taXNlUmVqZWN0aW9uRXZlbnQgPT0gJ2Z1bmN0aW9uJykgJiYgcHJvbWlzZS50aGVuKGVtcHR5KSBpbnN0YW5jZW9mIEZha2VQcm9taXNlO1xuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XG59KCk7XG5cbi8vIGhlbHBlcnNcbnZhciBzYW1lQ29uc3RydWN0b3IgPSBmdW5jdGlvbihhLCBiKXtcbiAgLy8gd2l0aCBsaWJyYXJ5IHdyYXBwZXIgc3BlY2lhbCBjYXNlXG4gIHJldHVybiBhID09PSBiIHx8IGEgPT09ICRQcm9taXNlICYmIGIgPT09IFdyYXBwZXI7XG59O1xudmFyIGlzVGhlbmFibGUgPSBmdW5jdGlvbihpdCl7XG4gIHZhciB0aGVuO1xuICByZXR1cm4gaXNPYmplY3QoaXQpICYmIHR5cGVvZiAodGhlbiA9IGl0LnRoZW4pID09ICdmdW5jdGlvbicgPyB0aGVuIDogZmFsc2U7XG59O1xudmFyIG5ld1Byb21pc2VDYXBhYmlsaXR5ID0gZnVuY3Rpb24oQyl7XG4gIHJldHVybiBzYW1lQ29uc3RydWN0b3IoJFByb21pc2UsIEMpXG4gICAgPyBuZXcgUHJvbWlzZUNhcGFiaWxpdHkoQylcbiAgICA6IG5ldyBHZW5lcmljUHJvbWlzZUNhcGFiaWxpdHkoQyk7XG59O1xudmFyIFByb21pc2VDYXBhYmlsaXR5ID0gR2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5ID0gZnVuY3Rpb24oQyl7XG4gIHZhciByZXNvbHZlLCByZWplY3Q7XG4gIHRoaXMucHJvbWlzZSA9IG5ldyBDKGZ1bmN0aW9uKCQkcmVzb2x2ZSwgJCRyZWplY3Qpe1xuICAgIGlmKHJlc29sdmUgIT09IHVuZGVmaW5lZCB8fCByZWplY3QgIT09IHVuZGVmaW5lZCl0aHJvdyBUeXBlRXJyb3IoJ0JhZCBQcm9taXNlIGNvbnN0cnVjdG9yJyk7XG4gICAgcmVzb2x2ZSA9ICQkcmVzb2x2ZTtcbiAgICByZWplY3QgID0gJCRyZWplY3Q7XG4gIH0pO1xuICB0aGlzLnJlc29sdmUgPSBhRnVuY3Rpb24ocmVzb2x2ZSk7XG4gIHRoaXMucmVqZWN0ICA9IGFGdW5jdGlvbihyZWplY3QpO1xufTtcbnZhciBwZXJmb3JtID0gZnVuY3Rpb24oZXhlYyl7XG4gIHRyeSB7XG4gICAgZXhlYygpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiB7ZXJyb3I6IGV9O1xuICB9XG59O1xudmFyIG5vdGlmeSA9IGZ1bmN0aW9uKHByb21pc2UsIGlzUmVqZWN0KXtcbiAgaWYocHJvbWlzZS5fbilyZXR1cm47XG4gIHByb21pc2UuX24gPSB0cnVlO1xuICB2YXIgY2hhaW4gPSBwcm9taXNlLl9jO1xuICBtaWNyb3Rhc2soZnVuY3Rpb24oKXtcbiAgICB2YXIgdmFsdWUgPSBwcm9taXNlLl92XG4gICAgICAsIG9rICAgID0gcHJvbWlzZS5fcyA9PSAxXG4gICAgICAsIGkgICAgID0gMDtcbiAgICB2YXIgcnVuID0gZnVuY3Rpb24ocmVhY3Rpb24pe1xuICAgICAgdmFyIGhhbmRsZXIgPSBvayA/IHJlYWN0aW9uLm9rIDogcmVhY3Rpb24uZmFpbFxuICAgICAgICAsIHJlc29sdmUgPSByZWFjdGlvbi5yZXNvbHZlXG4gICAgICAgICwgcmVqZWN0ICA9IHJlYWN0aW9uLnJlamVjdFxuICAgICAgICAsIGRvbWFpbiAgPSByZWFjdGlvbi5kb21haW5cbiAgICAgICAgLCByZXN1bHQsIHRoZW47XG4gICAgICB0cnkge1xuICAgICAgICBpZihoYW5kbGVyKXtcbiAgICAgICAgICBpZighb2spe1xuICAgICAgICAgICAgaWYocHJvbWlzZS5faCA9PSAyKW9uSGFuZGxlVW5oYW5kbGVkKHByb21pc2UpO1xuICAgICAgICAgICAgcHJvbWlzZS5faCA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKGhhbmRsZXIgPT09IHRydWUpcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZihkb21haW4pZG9tYWluLmVudGVyKCk7XG4gICAgICAgICAgICByZXN1bHQgPSBoYW5kbGVyKHZhbHVlKTtcbiAgICAgICAgICAgIGlmKGRvbWFpbilkb21haW4uZXhpdCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZihyZXN1bHQgPT09IHJlYWN0aW9uLnByb21pc2Upe1xuICAgICAgICAgICAgcmVqZWN0KFR5cGVFcnJvcignUHJvbWlzZS1jaGFpbiBjeWNsZScpKTtcbiAgICAgICAgICB9IGVsc2UgaWYodGhlbiA9IGlzVGhlbmFibGUocmVzdWx0KSl7XG4gICAgICAgICAgICB0aGVuLmNhbGwocmVzdWx0LCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0gZWxzZSByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0gZWxzZSByZWplY3QodmFsdWUpO1xuICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfVxuICAgIH07XG4gICAgd2hpbGUoY2hhaW4ubGVuZ3RoID4gaSlydW4oY2hhaW5baSsrXSk7IC8vIHZhcmlhYmxlIGxlbmd0aCAtIGNhbid0IHVzZSBmb3JFYWNoXG4gICAgcHJvbWlzZS5fYyA9IFtdO1xuICAgIHByb21pc2UuX24gPSBmYWxzZTtcbiAgICBpZihpc1JlamVjdCAmJiAhcHJvbWlzZS5faClvblVuaGFuZGxlZChwcm9taXNlKTtcbiAgfSk7XG59O1xudmFyIG9uVW5oYW5kbGVkID0gZnVuY3Rpb24ocHJvbWlzZSl7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uKCl7XG4gICAgdmFyIHZhbHVlID0gcHJvbWlzZS5fdlxuICAgICAgLCBhYnJ1cHQsIGhhbmRsZXIsIGNvbnNvbGU7XG4gICAgaWYoaXNVbmhhbmRsZWQocHJvbWlzZSkpe1xuICAgICAgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xuICAgICAgICBpZihpc05vZGUpe1xuICAgICAgICAgIHByb2Nlc3MuZW1pdCgndW5oYW5kbGVkUmVqZWN0aW9uJywgdmFsdWUsIHByb21pc2UpO1xuICAgICAgICB9IGVsc2UgaWYoaGFuZGxlciA9IGdsb2JhbC5vbnVuaGFuZGxlZHJlamVjdGlvbil7XG4gICAgICAgICAgaGFuZGxlcih7cHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiB2YWx1ZX0pO1xuICAgICAgICB9IGVsc2UgaWYoKGNvbnNvbGUgPSBnbG9iYWwuY29uc29sZSkgJiYgY29uc29sZS5lcnJvcil7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignVW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9uJywgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIEJyb3dzZXJzIHNob3VsZCBub3QgdHJpZ2dlciBgcmVqZWN0aW9uSGFuZGxlZGAgZXZlbnQgaWYgaXQgd2FzIGhhbmRsZWQgaGVyZSwgTm9kZUpTIC0gc2hvdWxkXG4gICAgICBwcm9taXNlLl9oID0gaXNOb2RlIHx8IGlzVW5oYW5kbGVkKHByb21pc2UpID8gMiA6IDE7XG4gICAgfSBwcm9taXNlLl9hID0gdW5kZWZpbmVkO1xuICAgIGlmKGFicnVwdCl0aHJvdyBhYnJ1cHQuZXJyb3I7XG4gIH0pO1xufTtcbnZhciBpc1VuaGFuZGxlZCA9IGZ1bmN0aW9uKHByb21pc2Upe1xuICBpZihwcm9taXNlLl9oID09IDEpcmV0dXJuIGZhbHNlO1xuICB2YXIgY2hhaW4gPSBwcm9taXNlLl9hIHx8IHByb21pc2UuX2NcbiAgICAsIGkgICAgID0gMFxuICAgICwgcmVhY3Rpb247XG4gIHdoaWxlKGNoYWluLmxlbmd0aCA+IGkpe1xuICAgIHJlYWN0aW9uID0gY2hhaW5baSsrXTtcbiAgICBpZihyZWFjdGlvbi5mYWlsIHx8ICFpc1VuaGFuZGxlZChyZWFjdGlvbi5wcm9taXNlKSlyZXR1cm4gZmFsc2U7XG4gIH0gcmV0dXJuIHRydWU7XG59O1xudmFyIG9uSGFuZGxlVW5oYW5kbGVkID0gZnVuY3Rpb24ocHJvbWlzZSl7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uKCl7XG4gICAgdmFyIGhhbmRsZXI7XG4gICAgaWYoaXNOb2RlKXtcbiAgICAgIHByb2Nlc3MuZW1pdCgncmVqZWN0aW9uSGFuZGxlZCcsIHByb21pc2UpO1xuICAgIH0gZWxzZSBpZihoYW5kbGVyID0gZ2xvYmFsLm9ucmVqZWN0aW9uaGFuZGxlZCl7XG4gICAgICBoYW5kbGVyKHtwcm9taXNlOiBwcm9taXNlLCByZWFzb246IHByb21pc2UuX3Z9KTtcbiAgICB9XG4gIH0pO1xufTtcbnZhciAkcmVqZWN0ID0gZnVuY3Rpb24odmFsdWUpe1xuICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gIGlmKHByb21pc2UuX2QpcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHByb21pc2UuX3YgPSB2YWx1ZTtcbiAgcHJvbWlzZS5fcyA9IDI7XG4gIGlmKCFwcm9taXNlLl9hKXByb21pc2UuX2EgPSBwcm9taXNlLl9jLnNsaWNlKCk7XG4gIG5vdGlmeShwcm9taXNlLCB0cnVlKTtcbn07XG52YXIgJHJlc29sdmUgPSBmdW5jdGlvbih2YWx1ZSl7XG4gIHZhciBwcm9taXNlID0gdGhpc1xuICAgICwgdGhlbjtcbiAgaWYocHJvbWlzZS5fZClyZXR1cm47XG4gIHByb21pc2UuX2QgPSB0cnVlO1xuICBwcm9taXNlID0gcHJvbWlzZS5fdyB8fCBwcm9taXNlOyAvLyB1bndyYXBcbiAgdHJ5IHtcbiAgICBpZihwcm9taXNlID09PSB2YWx1ZSl0aHJvdyBUeXBlRXJyb3IoXCJQcm9taXNlIGNhbid0IGJlIHJlc29sdmVkIGl0c2VsZlwiKTtcbiAgICBpZih0aGVuID0gaXNUaGVuYWJsZSh2YWx1ZSkpe1xuICAgICAgbWljcm90YXNrKGZ1bmN0aW9uKCl7XG4gICAgICAgIHZhciB3cmFwcGVyID0ge193OiBwcm9taXNlLCBfZDogZmFsc2V9OyAvLyB3cmFwXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBjdHgoJHJlc29sdmUsIHdyYXBwZXIsIDEpLCBjdHgoJHJlamVjdCwgd3JhcHBlciwgMSkpO1xuICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICRyZWplY3QuY2FsbCh3cmFwcGVyLCBlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb21pc2UuX3YgPSB2YWx1ZTtcbiAgICAgIHByb21pc2UuX3MgPSAxO1xuICAgICAgbm90aWZ5KHByb21pc2UsIGZhbHNlKTtcbiAgICB9XG4gIH0gY2F0Y2goZSl7XG4gICAgJHJlamVjdC5jYWxsKHtfdzogcHJvbWlzZSwgX2Q6IGZhbHNlfSwgZSk7IC8vIHdyYXBcbiAgfVxufTtcblxuLy8gY29uc3RydWN0b3IgcG9seWZpbGxcbmlmKCFVU0VfTkFUSVZFKXtcbiAgLy8gMjUuNC4zLjEgUHJvbWlzZShleGVjdXRvcilcbiAgJFByb21pc2UgPSBmdW5jdGlvbiBQcm9taXNlKGV4ZWN1dG9yKXtcbiAgICBhbkluc3RhbmNlKHRoaXMsICRQcm9taXNlLCBQUk9NSVNFLCAnX2gnKTtcbiAgICBhRnVuY3Rpb24oZXhlY3V0b3IpO1xuICAgIEludGVybmFsLmNhbGwodGhpcyk7XG4gICAgdHJ5IHtcbiAgICAgIGV4ZWN1dG9yKGN0eCgkcmVzb2x2ZSwgdGhpcywgMSksIGN0eCgkcmVqZWN0LCB0aGlzLCAxKSk7XG4gICAgfSBjYXRjaChlcnIpe1xuICAgICAgJHJlamVjdC5jYWxsKHRoaXMsIGVycik7XG4gICAgfVxuICB9O1xuICBJbnRlcm5hbCA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3Ipe1xuICAgIHRoaXMuX2MgPSBbXTsgICAgICAgICAgICAgLy8gPC0gYXdhaXRpbmcgcmVhY3Rpb25zXG4gICAgdGhpcy5fYSA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSBjaGVja2VkIGluIGlzVW5oYW5kbGVkIHJlYWN0aW9uc1xuICAgIHRoaXMuX3MgPSAwOyAgICAgICAgICAgICAgLy8gPC0gc3RhdGVcbiAgICB0aGlzLl9kID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIGRvbmVcbiAgICB0aGlzLl92ID0gdW5kZWZpbmVkOyAgICAgIC8vIDwtIHZhbHVlXG4gICAgdGhpcy5faCA9IDA7ICAgICAgICAgICAgICAvLyA8LSByZWplY3Rpb24gc3RhdGUsIDAgLSBkZWZhdWx0LCAxIC0gaGFuZGxlZCwgMiAtIHVuaGFuZGxlZFxuICAgIHRoaXMuX24gPSBmYWxzZTsgICAgICAgICAgLy8gPC0gbm90aWZ5XG4gIH07XG4gIEludGVybmFsLnByb3RvdHlwZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpKCRQcm9taXNlLnByb3RvdHlwZSwge1xuICAgIC8vIDI1LjQuNS4zIFByb21pc2UucHJvdG90eXBlLnRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpXG4gICAgdGhlbjogZnVuY3Rpb24gdGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCl7XG4gICAgICB2YXIgcmVhY3Rpb24gICAgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShzcGVjaWVzQ29uc3RydWN0b3IodGhpcywgJFByb21pc2UpKTtcbiAgICAgIHJlYWN0aW9uLm9rICAgICA9IHR5cGVvZiBvbkZ1bGZpbGxlZCA9PSAnZnVuY3Rpb24nID8gb25GdWxmaWxsZWQgOiB0cnVlO1xuICAgICAgcmVhY3Rpb24uZmFpbCAgID0gdHlwZW9mIG9uUmVqZWN0ZWQgPT0gJ2Z1bmN0aW9uJyAmJiBvblJlamVjdGVkO1xuICAgICAgcmVhY3Rpb24uZG9tYWluID0gaXNOb2RlID8gcHJvY2Vzcy5kb21haW4gOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLl9jLnB1c2gocmVhY3Rpb24pO1xuICAgICAgaWYodGhpcy5fYSl0aGlzLl9hLnB1c2gocmVhY3Rpb24pO1xuICAgICAgaWYodGhpcy5fcylub3RpZnkodGhpcywgZmFsc2UpO1xuICAgICAgcmV0dXJuIHJlYWN0aW9uLnByb21pc2U7XG4gICAgfSxcbiAgICAvLyAyNS40LjUuMSBQcm9taXNlLnByb3RvdHlwZS5jYXRjaChvblJlamVjdGVkKVxuICAgICdjYXRjaCc6IGZ1bmN0aW9uKG9uUmVqZWN0ZWQpe1xuICAgICAgcmV0dXJuIHRoaXMudGhlbih1bmRlZmluZWQsIG9uUmVqZWN0ZWQpO1xuICAgIH1cbiAgfSk7XG4gIFByb21pc2VDYXBhYmlsaXR5ID0gZnVuY3Rpb24oKXtcbiAgICB2YXIgcHJvbWlzZSAgPSBuZXcgSW50ZXJuYWw7XG4gICAgdGhpcy5wcm9taXNlID0gcHJvbWlzZTtcbiAgICB0aGlzLnJlc29sdmUgPSBjdHgoJHJlc29sdmUsIHByb21pc2UsIDEpO1xuICAgIHRoaXMucmVqZWN0ICA9IGN0eCgkcmVqZWN0LCBwcm9taXNlLCAxKTtcbiAgfTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwge1Byb21pc2U6ICRQcm9taXNlfSk7XG5yZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpKCRQcm9taXNlLCBQUk9NSVNFKTtcbnJlcXVpcmUoJy4vX3NldC1zcGVjaWVzJykoUFJPTUlTRSk7XG5XcmFwcGVyID0gcmVxdWlyZSgnLi9fY29yZScpW1BST01JU0VdO1xuXG4vLyBzdGF0aWNzXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC41IFByb21pc2UucmVqZWN0KHIpXG4gIHJlamVjdDogZnVuY3Rpb24gcmVqZWN0KHIpe1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcylcbiAgICAgICwgJCRyZWplY3QgICA9IGNhcGFiaWxpdHkucmVqZWN0O1xuICAgICQkcmVqZWN0KHIpO1xuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XG4gIH1cbn0pO1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoTElCUkFSWSB8fCAhVVNFX05BVElWRSksIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjYgUHJvbWlzZS5yZXNvbHZlKHgpXG4gIHJlc29sdmU6IGZ1bmN0aW9uIHJlc29sdmUoeCl7XG4gICAgLy8gaW5zdGFuY2VvZiBpbnN0ZWFkIG9mIGludGVybmFsIHNsb3QgY2hlY2sgYmVjYXVzZSB3ZSBzaG91bGQgZml4IGl0IHdpdGhvdXQgcmVwbGFjZW1lbnQgbmF0aXZlIFByb21pc2UgY29yZVxuICAgIGlmKHggaW5zdGFuY2VvZiAkUHJvbWlzZSAmJiBzYW1lQ29uc3RydWN0b3IoeC5jb25zdHJ1Y3RvciwgdGhpcykpcmV0dXJuIHg7XG4gICAgdmFyIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eSh0aGlzKVxuICAgICAgLCAkJHJlc29sdmUgID0gY2FwYWJpbGl0eS5yZXNvbHZlO1xuICAgICQkcmVzb2x2ZSh4KTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG59KTtcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIShVU0VfTkFUSVZFICYmIHJlcXVpcmUoJy4vX2l0ZXItZGV0ZWN0JykoZnVuY3Rpb24oaXRlcil7XG4gICRQcm9taXNlLmFsbChpdGVyKVsnY2F0Y2gnXShlbXB0eSk7XG59KSksIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjEgUHJvbWlzZS5hbGwoaXRlcmFibGUpXG4gIGFsbDogZnVuY3Rpb24gYWxsKGl0ZXJhYmxlKXtcbiAgICB2YXIgQyAgICAgICAgICA9IHRoaXNcbiAgICAgICwgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICAsIHJlc29sdmUgICAgPSBjYXBhYmlsaXR5LnJlc29sdmVcbiAgICAgICwgcmVqZWN0ICAgICA9IGNhcGFiaWxpdHkucmVqZWN0O1xuICAgIHZhciBhYnJ1cHQgPSBwZXJmb3JtKGZ1bmN0aW9uKCl7XG4gICAgICB2YXIgdmFsdWVzICAgID0gW11cbiAgICAgICAgLCBpbmRleCAgICAgPSAwXG4gICAgICAgICwgcmVtYWluaW5nID0gMTtcbiAgICAgIGZvck9mKGl0ZXJhYmxlLCBmYWxzZSwgZnVuY3Rpb24ocHJvbWlzZSl7XG4gICAgICAgIHZhciAkaW5kZXggICAgICAgID0gaW5kZXgrK1xuICAgICAgICAgICwgYWxyZWFkeUNhbGxlZCA9IGZhbHNlO1xuICAgICAgICB2YWx1ZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICByZW1haW5pbmcrKztcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oZnVuY3Rpb24odmFsdWUpe1xuICAgICAgICAgIGlmKGFscmVhZHlDYWxsZWQpcmV0dXJuO1xuICAgICAgICAgIGFscmVhZHlDYWxsZWQgID0gdHJ1ZTtcbiAgICAgICAgICB2YWx1ZXNbJGluZGV4XSA9IHZhbHVlO1xuICAgICAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgLS1yZW1haW5pbmcgfHwgcmVzb2x2ZSh2YWx1ZXMpO1xuICAgIH0pO1xuICAgIGlmKGFicnVwdClyZWplY3QoYWJydXB0LmVycm9yKTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9LFxuICAvLyAyNS40LjQuNCBQcm9taXNlLnJhY2UoaXRlcmFibGUpXG4gIHJhY2U6IGZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpe1xuICAgIHZhciBDICAgICAgICAgID0gdGhpc1xuICAgICAgLCBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkoQylcbiAgICAgICwgcmVqZWN0ICAgICA9IGNhcGFiaWxpdHkucmVqZWN0O1xuICAgIHZhciBhYnJ1cHQgPSBwZXJmb3JtKGZ1bmN0aW9uKCl7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uKHByb21pc2Upe1xuICAgICAgICBDLnJlc29sdmUocHJvbWlzZSkudGhlbihjYXBhYmlsaXR5LnJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZihhYnJ1cHQpcmVqZWN0KGFicnVwdC5lcnJvcik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9lczYucHJvbWlzZS5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIENvbnN0cnVjdG9yLCBuYW1lLCBmb3JiaWRkZW5GaWVsZCl7XG4gIGlmKCEoaXQgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgfHwgKGZvcmJpZGRlbkZpZWxkICE9PSB1bmRlZmluZWQgJiYgZm9yYmlkZGVuRmllbGQgaW4gaXQpKXtcbiAgICB0aHJvdyBUeXBlRXJyb3IobmFtZSArICc6IGluY29ycmVjdCBpbnZvY2F0aW9uIScpO1xuICB9IHJldHVybiBpdDtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fYW4taW5zdGFuY2UuanNcbiAqKi8iLCJ2YXIgY3R4ICAgICAgICAgPSByZXF1aXJlKCcuL19jdHgnKVxuICAsIGNhbGwgICAgICAgID0gcmVxdWlyZSgnLi9faXRlci1jYWxsJylcbiAgLCBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKVxuICAsIGFuT2JqZWN0ICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCB0b0xlbmd0aCAgICA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpXG4gICwgZ2V0SXRlckZuICAgPSByZXF1aXJlKCcuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdGVyYWJsZSwgZW50cmllcywgZm4sIHRoYXQsIElURVJBVE9SKXtcbiAgdmFyIGl0ZXJGbiA9IElURVJBVE9SID8gZnVuY3Rpb24oKXsgcmV0dXJuIGl0ZXJhYmxlOyB9IDogZ2V0SXRlckZuKGl0ZXJhYmxlKVxuICAgICwgZiAgICAgID0gY3R4KGZuLCB0aGF0LCBlbnRyaWVzID8gMiA6IDEpXG4gICAgLCBpbmRleCAgPSAwXG4gICAgLCBsZW5ndGgsIHN0ZXAsIGl0ZXJhdG9yO1xuICBpZih0eXBlb2YgaXRlckZuICE9ICdmdW5jdGlvbicpdGhyb3cgVHlwZUVycm9yKGl0ZXJhYmxlICsgJyBpcyBub3QgaXRlcmFibGUhJyk7XG4gIC8vIGZhc3QgY2FzZSBmb3IgYXJyYXlzIHdpdGggZGVmYXVsdCBpdGVyYXRvclxuICBpZihpc0FycmF5SXRlcihpdGVyRm4pKWZvcihsZW5ndGggPSB0b0xlbmd0aChpdGVyYWJsZS5sZW5ndGgpOyBsZW5ndGggPiBpbmRleDsgaW5kZXgrKyl7XG4gICAgZW50cmllcyA/IGYoYW5PYmplY3Qoc3RlcCA9IGl0ZXJhYmxlW2luZGV4XSlbMF0sIHN0ZXBbMV0pIDogZihpdGVyYWJsZVtpbmRleF0pO1xuICB9IGVsc2UgZm9yKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoaXRlcmFibGUpOyAhKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmU7ICl7XG4gICAgY2FsbChpdGVyYXRvciwgZiwgc3RlcC52YWx1ZSwgZW50cmllcyk7XG4gIH1cbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzXG4gKiovIiwiLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0ZXJhdG9yLCBmbiwgdmFsdWUsIGVudHJpZXMpe1xuICB0cnkge1xuICAgIHJldHVybiBlbnRyaWVzID8gZm4oYW5PYmplY3QodmFsdWUpWzBdLCB2YWx1ZVsxXSkgOiBmbih2YWx1ZSk7XG4gIC8vIDcuNC42IEl0ZXJhdG9yQ2xvc2UoaXRlcmF0b3IsIGNvbXBsZXRpb24pXG4gIH0gY2F0Y2goZSl7XG4gICAgdmFyIHJldCA9IGl0ZXJhdG9yWydyZXR1cm4nXTtcbiAgICBpZihyZXQgIT09IHVuZGVmaW5lZClhbk9iamVjdChyZXQuY2FsbChpdGVyYXRvcikpO1xuICAgIHRocm93IGU7XG4gIH1cbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faXRlci1jYWxsLmpzXG4gKiovIiwiLy8gY2hlY2sgb24gZGVmYXVsdCBBcnJheSBpdGVyYXRvclxudmFyIEl0ZXJhdG9ycyAgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKVxuICAsIElURVJBVE9SICAgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKVxuICAsIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXQgIT09IHVuZGVmaW5lZCAmJiAoSXRlcmF0b3JzLkFycmF5ID09PSBpdCB8fCBBcnJheVByb3RvW0lURVJBVE9SXSA9PT0gaXQpO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzXG4gKiovIiwidmFyIGNsYXNzb2YgICA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKVxuICAsIElURVJBVE9SICA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpXG4gICwgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2NvcmUnKS5nZXRJdGVyYXRvck1ldGhvZCA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYoaXQgIT0gdW5kZWZpbmVkKXJldHVybiBpdFtJVEVSQVRPUl1cbiAgICB8fCBpdFsnQEBpdGVyYXRvciddXG4gICAgfHwgSXRlcmF0b3JzW2NsYXNzb2YoaXQpXTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QuanNcbiAqKi8iLCIvLyBXb3JrcyB3aXRoIF9fcHJvdG9fXyBvbmx5LiBPbGQgdjggY2FuJ3Qgd29yayB3aXRoIG51bGwgcHJvdG8gb2JqZWN0cy5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgY2hlY2sgPSBmdW5jdGlvbihPLCBwcm90byl7XG4gIGFuT2JqZWN0KE8pO1xuICBpZighaXNPYmplY3QocHJvdG8pICYmIHByb3RvICE9PSBudWxsKXRocm93IFR5cGVFcnJvcihwcm90byArIFwiOiBjYW4ndCBzZXQgYXMgcHJvdG90eXBlIVwiKTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwgKCdfX3Byb3RvX18nIGluIHt9ID8gLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIGZ1bmN0aW9uKHRlc3QsIGJ1Z2d5LCBzZXQpe1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2V0ID0gcmVxdWlyZSgnLi9fY3R4JykoRnVuY3Rpb24uY2FsbCwgcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mKE9iamVjdC5wcm90b3R5cGUsICdfX3Byb3RvX18nKS5zZXQsIDIpO1xuICAgICAgICBzZXQodGVzdCwgW10pO1xuICAgICAgICBidWdneSA9ICEodGVzdCBpbnN0YW5jZW9mIEFycmF5KTtcbiAgICAgIH0gY2F0Y2goZSl7IGJ1Z2d5ID0gdHJ1ZTsgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNldFByb3RvdHlwZU9mKE8sIHByb3RvKXtcbiAgICAgICAgY2hlY2soTywgcHJvdG8pO1xuICAgICAgICBpZihidWdneSlPLl9fcHJvdG9fXyA9IHByb3RvO1xuICAgICAgICBlbHNlIHNldChPLCBwcm90byk7XG4gICAgICAgIHJldHVybiBPO1xuICAgICAgfTtcbiAgICB9KHt9LCBmYWxzZSkgOiB1bmRlZmluZWQpLFxuICBjaGVjazogY2hlY2tcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzXG4gKiovIiwidmFyIHBJRSAgICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpXHJcbiAgLCBjcmVhdGVEZXNjICAgICA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKVxyXG4gICwgdG9JT2JqZWN0ICAgICAgPSByZXF1aXJlKCcuL190by1pb2JqZWN0JylcclxuICAsIHRvUHJpbWl0aXZlICAgID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJylcclxuICAsIGhhcyAgICAgICAgICAgID0gcmVxdWlyZSgnLi9faGFzJylcclxuICAsIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi9faWU4LWRvbS1kZWZpbmUnKVxyXG4gICwgZ09QRCAgICAgICAgICAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xyXG5cclxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGdPUEQgOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUCl7XHJcbiAgTyA9IHRvSU9iamVjdChPKTtcclxuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XHJcbiAgaWYoSUU4X0RPTV9ERUZJTkUpdHJ5IHtcclxuICAgIHJldHVybiBnT1BEKE8sIFApO1xyXG4gIH0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cclxuICBpZihoYXMoTywgUCkpcmV0dXJuIGNyZWF0ZURlc2MoIXBJRS5mLmNhbGwoTywgUCksIE9bUF0pO1xyXG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BkLmpzXG4gKiovIiwiLy8gNy4zLjIwIFNwZWNpZXNDb25zdHJ1Y3RvcihPLCBkZWZhdWx0Q29uc3RydWN0b3IpXG52YXIgYW5PYmplY3QgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJylcbiAgLCBTUEVDSUVTICAgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihPLCBEKXtcbiAgdmFyIEMgPSBhbk9iamVjdChPKS5jb25zdHJ1Y3RvciwgUztcbiAgcmV0dXJuIEMgPT09IHVuZGVmaW5lZCB8fCAoUyA9IGFuT2JqZWN0KEMpW1NQRUNJRVNdKSA9PSB1bmRlZmluZWQgPyBEIDogYUZ1bmN0aW9uKFMpO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19zcGVjaWVzLWNvbnN0cnVjdG9yLmpzXG4gKiovIiwidmFyIGN0eCAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2N0eCcpXG4gICwgaW52b2tlICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9faW52b2tlJylcbiAgLCBodG1sICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19odG1sJylcbiAgLCBjZWwgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJylcbiAgLCBnbG9iYWwgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIHByb2Nlc3MgICAgICAgICAgICA9IGdsb2JhbC5wcm9jZXNzXG4gICwgc2V0VGFzayAgICAgICAgICAgID0gZ2xvYmFsLnNldEltbWVkaWF0ZVxuICAsIGNsZWFyVGFzayAgICAgICAgICA9IGdsb2JhbC5jbGVhckltbWVkaWF0ZVxuICAsIE1lc3NhZ2VDaGFubmVsICAgICA9IGdsb2JhbC5NZXNzYWdlQ2hhbm5lbFxuICAsIGNvdW50ZXIgICAgICAgICAgICA9IDBcbiAgLCBxdWV1ZSAgICAgICAgICAgICAgPSB7fVxuICAsIE9OUkVBRFlTVEFURUNIQU5HRSA9ICdvbnJlYWR5c3RhdGVjaGFuZ2UnXG4gICwgZGVmZXIsIGNoYW5uZWwsIHBvcnQ7XG52YXIgcnVuID0gZnVuY3Rpb24oKXtcbiAgdmFyIGlkID0gK3RoaXM7XG4gIGlmKHF1ZXVlLmhhc093blByb3BlcnR5KGlkKSl7XG4gICAgdmFyIGZuID0gcXVldWVbaWRdO1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gICAgZm4oKTtcbiAgfVxufTtcbnZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgcnVuLmNhbGwoZXZlbnQuZGF0YSk7XG59O1xuLy8gTm9kZS5qcyAwLjkrICYgSUUxMCsgaGFzIHNldEltbWVkaWF0ZSwgb3RoZXJ3aXNlOlxuaWYoIXNldFRhc2sgfHwgIWNsZWFyVGFzayl7XG4gIHNldFRhc2sgPSBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZm4pe1xuICAgIHZhciBhcmdzID0gW10sIGkgPSAxO1xuICAgIHdoaWxlKGFyZ3VtZW50cy5sZW5ndGggPiBpKWFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgcXVldWVbKytjb3VudGVyXSA9IGZ1bmN0aW9uKCl7XG4gICAgICBpbnZva2UodHlwZW9mIGZuID09ICdmdW5jdGlvbicgPyBmbiA6IEZ1bmN0aW9uKGZuKSwgYXJncyk7XG4gICAgfTtcbiAgICBkZWZlcihjb3VudGVyKTtcbiAgICByZXR1cm4gY291bnRlcjtcbiAgfTtcbiAgY2xlYXJUYXNrID0gZnVuY3Rpb24gY2xlYXJJbW1lZGlhdGUoaWQpe1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gIH07XG4gIC8vIE5vZGUuanMgMC44LVxuICBpZihyZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2Vzcycpe1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhjdHgocnVuLCBpZCwgMSkpO1xuICAgIH07XG4gIC8vIEJyb3dzZXJzIHdpdGggTWVzc2FnZUNoYW5uZWwsIGluY2x1ZGVzIFdlYldvcmtlcnNcbiAgfSBlbHNlIGlmKE1lc3NhZ2VDaGFubmVsKXtcbiAgICBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsO1xuICAgIHBvcnQgICAgPSBjaGFubmVsLnBvcnQyO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbGlzdGVuZXI7XG4gICAgZGVmZXIgPSBjdHgocG9ydC5wb3N0TWVzc2FnZSwgcG9ydCwgMSk7XG4gIC8vIEJyb3dzZXJzIHdpdGggcG9zdE1lc3NhZ2UsIHNraXAgV2ViV29ya2Vyc1xuICAvLyBJRTggaGFzIHBvc3RNZXNzYWdlLCBidXQgaXQncyBzeW5jICYgdHlwZW9mIGl0cyBwb3N0TWVzc2FnZSBpcyAnb2JqZWN0J1xuICB9IGVsc2UgaWYoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIgJiYgdHlwZW9mIHBvc3RNZXNzYWdlID09ICdmdW5jdGlvbicgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKXtcbiAgICBkZWZlciA9IGZ1bmN0aW9uKGlkKXtcbiAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShpZCArICcnLCAnKicpO1xuICAgIH07XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBsaXN0ZW5lciwgZmFsc2UpO1xuICAvLyBJRTgtXG4gIH0gZWxzZSBpZihPTlJFQURZU1RBVEVDSEFOR0UgaW4gY2VsKCdzY3JpcHQnKSl7XG4gICAgZGVmZXIgPSBmdW5jdGlvbihpZCl7XG4gICAgICBodG1sLmFwcGVuZENoaWxkKGNlbCgnc2NyaXB0JykpW09OUkVBRFlTVEFURUNIQU5HRV0gPSBmdW5jdGlvbigpe1xuICAgICAgICBodG1sLnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgICAgICBydW4uY2FsbChpZCk7XG4gICAgICB9O1xuICAgIH07XG4gIC8vIFJlc3Qgb2xkIGJyb3dzZXJzXG4gIH0gZWxzZSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbihpZCl7XG4gICAgICBzZXRUaW1lb3V0KGN0eChydW4sIGlkLCAxKSwgMCk7XG4gICAgfTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogICBzZXRUYXNrLFxuICBjbGVhcjogY2xlYXJUYXNrXG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanNcbiAqKi8iLCIvLyBmYXN0IGFwcGx5LCBodHRwOi8vanNwZXJmLmxua2l0LmNvbS9mYXN0LWFwcGx5LzVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm4sIGFyZ3MsIHRoYXQpe1xuICB2YXIgdW4gPSB0aGF0ID09PSB1bmRlZmluZWQ7XG4gIHN3aXRjaChhcmdzLmxlbmd0aCl7XG4gICAgY2FzZSAwOiByZXR1cm4gdW4gPyBmbigpXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQpO1xuICAgIGNhc2UgMTogcmV0dXJuIHVuID8gZm4oYXJnc1swXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSk7XG4gICAgY2FzZSAyOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICBjYXNlIDM6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgIGNhc2UgNDogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gIH0gcmV0dXJuICAgICAgICAgICAgICBmbi5hcHBseSh0aGF0LCBhcmdzKTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9faW52b2tlLmpzXG4gKiovIiwidmFyIGdsb2JhbCAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgbWFjcm90YXNrID0gcmVxdWlyZSgnLi9fdGFzaycpLnNldFxuICAsIE9ic2VydmVyICA9IGdsb2JhbC5NdXRhdGlvbk9ic2VydmVyIHx8IGdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyXG4gICwgcHJvY2VzcyAgID0gZ2xvYmFsLnByb2Nlc3NcbiAgLCBQcm9taXNlICAgPSBnbG9iYWwuUHJvbWlzZVxuICAsIGlzTm9kZSAgICA9IHJlcXVpcmUoJy4vX2NvZicpKHByb2Nlc3MpID09ICdwcm9jZXNzJ1xuICAsIGhlYWQsIGxhc3QsIG5vdGlmeTtcblxudmFyIGZsdXNoID0gZnVuY3Rpb24oKXtcbiAgdmFyIHBhcmVudCwgZm47XG4gIGlmKGlzTm9kZSAmJiAocGFyZW50ID0gcHJvY2Vzcy5kb21haW4pKXBhcmVudC5leGl0KCk7XG4gIHdoaWxlKGhlYWQpe1xuICAgIGZuID0gaGVhZC5mbjtcbiAgICBmbigpOyAvLyA8LSBjdXJyZW50bHkgd2UgdXNlIGl0IG9ubHkgZm9yIFByb21pc2UgLSB0cnkgLyBjYXRjaCBub3QgcmVxdWlyZWRcbiAgICBoZWFkID0gaGVhZC5uZXh0O1xuICB9IGxhc3QgPSB1bmRlZmluZWQ7XG4gIGlmKHBhcmVudClwYXJlbnQuZW50ZXIoKTtcbn07XG5cbi8vIE5vZGUuanNcbmlmKGlzTm9kZSl7XG4gIG5vdGlmeSA9IGZ1bmN0aW9uKCl7XG4gICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gIH07XG4vLyBicm93c2VycyB3aXRoIE11dGF0aW9uT2JzZXJ2ZXJcbn0gZWxzZSBpZihPYnNlcnZlcil7XG4gIHZhciB0b2dnbGUgPSB0cnVlXG4gICAgLCBub2RlICAgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gIG5ldyBPYnNlcnZlcihmbHVzaCkub2JzZXJ2ZShub2RlLCB7Y2hhcmFjdGVyRGF0YTogdHJ1ZX0pOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICBub3RpZnkgPSBmdW5jdGlvbigpe1xuICAgIG5vZGUuZGF0YSA9IHRvZ2dsZSA9ICF0b2dnbGU7XG4gIH07XG4vLyBlbnZpcm9ubWVudHMgd2l0aCBtYXliZSBub24tY29tcGxldGVseSBjb3JyZWN0LCBidXQgZXhpc3RlbnQgUHJvbWlzZVxufSBlbHNlIGlmKFByb21pc2UgJiYgUHJvbWlzZS5yZXNvbHZlKXtcbiAgbm90aWZ5ID0gZnVuY3Rpb24oKXtcbiAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZsdXNoKTtcbiAgfTtcbi8vIGZvciBvdGhlciBlbnZpcm9ubWVudHMgLSBtYWNyb3Rhc2sgYmFzZWQgb246XG4vLyAtIHNldEltbWVkaWF0ZVxuLy8gLSBNZXNzYWdlQ2hhbm5lbFxuLy8gLSB3aW5kb3cucG9zdE1lc3NhZ1xuLy8gLSBvbnJlYWR5c3RhdGVjaGFuZ2Vcbi8vIC0gc2V0VGltZW91dFxufSBlbHNlIHtcbiAgbm90aWZ5ID0gZnVuY3Rpb24oKXtcbiAgICAvLyBzdHJhbmdlIElFICsgd2VicGFjayBkZXYgc2VydmVyIGJ1ZyAtIHVzZSAuY2FsbChnbG9iYWwpXG4gICAgbWFjcm90YXNrLmNhbGwoZ2xvYmFsLCBmbHVzaCk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm4pe1xuICB2YXIgdGFzayA9IHtmbjogZm4sIG5leHQ6IHVuZGVmaW5lZH07XG4gIGlmKGxhc3QpbGFzdC5uZXh0ID0gdGFzaztcbiAgaWYoIWhlYWQpe1xuICAgIGhlYWQgPSB0YXNrO1xuICAgIG5vdGlmeSgpO1xuICB9IGxhc3QgPSB0YXNrO1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19taWNyb3Rhc2suanNcbiAqKi8iLCJ2YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih0YXJnZXQsIHNyYywgc2FmZSl7XG4gIGZvcih2YXIga2V5IGluIHNyYylyZWRlZmluZSh0YXJnZXQsIGtleSwgc3JjW2tleV0sIHNhZmUpO1xuICByZXR1cm4gdGFyZ2V0O1xufTtcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanNcbiAqKi8iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIGRQICAgICAgICAgID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJylcbiAgLCBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJylcbiAgLCBTUEVDSUVTICAgICA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZKXtcbiAgdmFyIEMgPSBnbG9iYWxbS0VZXTtcbiAgaWYoREVTQ1JJUFRPUlMgJiYgQyAmJiAhQ1tTUEVDSUVTXSlkUC5mKEMsIFNQRUNJRVMsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpeyByZXR1cm4gdGhpczsgfVxuICB9KTtcbn07XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9+L2NvcmUtanMvbW9kdWxlcy9fc2V0LXNwZWNpZXMuanNcbiAqKi8iLCJ2YXIgSVRFUkFUT1IgICAgID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBTQUZFX0NMT1NJTkcgPSBmYWxzZTtcblxudHJ5IHtcbiAgdmFyIHJpdGVyID0gWzddW0lURVJBVE9SXSgpO1xuICByaXRlclsncmV0dXJuJ10gPSBmdW5jdGlvbigpeyBTQUZFX0NMT1NJTkcgPSB0cnVlOyB9O1xuICBBcnJheS5mcm9tKHJpdGVyLCBmdW5jdGlvbigpeyB0aHJvdyAyOyB9KTtcbn0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihleGVjLCBza2lwQ2xvc2luZyl7XG4gIGlmKCFza2lwQ2xvc2luZyAmJiAhU0FGRV9DTE9TSU5HKXJldHVybiBmYWxzZTtcbiAgdmFyIHNhZmUgPSBmYWxzZTtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyICA9IFs3XVxuICAgICAgLCBpdGVyID0gYXJyW0lURVJBVE9SXSgpO1xuICAgIGl0ZXIubmV4dCA9IGZ1bmN0aW9uKCl7IHNhZmUgPSB0cnVlOyB9O1xuICAgIGFycltJVEVSQVRPUl0gPSBmdW5jdGlvbigpeyByZXR1cm4gaXRlcjsgfTtcbiAgICBleGVjKGFycik7XG4gIH0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuIHNhZmU7XG59O1xuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGV0ZWN0LmpzXG4gKiovIiwiY29uc3Qge1xuICBzZXRUaW1lb3V0LCBzZXRUaW1lb3V0TmF0aXZlXG59ID0gZ2xvYmFsXG5cbi8vIGZpeCBubyBzZXRUaW1lb3V0IG9uIEFuZHJvaWQgVjhcbmlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIHNldFRpbWVvdXROYXRpdmUgPT09ICdmdW5jdGlvbicpIHtcbiAgY29uc3QgdGltZW91dE1hcCA9IHt9XG4gIGxldCB0aW1lb3V0SWQgPSAwXG4gIGdsb2JhbC5zZXRUaW1lb3V0ID0gKGNiLCB0aW1lKSA9PiB7XG4gICAgdGltZW91dE1hcFsrK3RpbWVvdXRJZF0gPSBjYlxuICAgIHNldFRpbWVvdXROYXRpdmUodGltZW91dElkLnRvU3RyaW5nKCksIHRpbWUpXG4gIH1cbiAgZ2xvYmFsLnNldFRpbWVvdXRDYWxsYmFjayA9IChpZCkgPT4ge1xuICAgIGlmICh0eXBlb2YgdGltZW91dE1hcFtpZF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRpbWVvdXRNYXBbaWRdKClcbiAgICAgIGRlbGV0ZSB0aW1lb3V0TWFwW2lkXVxuICAgIH1cbiAgfVxufVxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vcG9seWZpbGwvc2V0VGltZW91dC5qc1xuICoqLyIsImNvbnN0IHtjb25zb2xlfSA9IGdsb2JhbFxuXG5pZiAodHlwZW9mIGNvbnNvbGUgPT09ICd1bmRlZmluZWQnKSB7XG4gIGdsb2JhbC5jb25zb2xlID0ge1xuICAgIGxvZzogKC4uLmFyZ3MpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgbmF0aXZlTG9nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIG5hdGl2ZUxvZyguLi5hcmdzKVxuICAgICAgfVxuICAgIH0sXG4gICAgZXJyb3I6ICguLi5hcmdzKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYXJncylcbiAgICB9XG4gIH1cbn1cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL3BvbHlmaWxsL2NvbnNvbGVsb2cuanNcbiAqKi8iLCIvKipcbiAqIEBmaWxlT3ZlcnZpZXcgTWFpbiBlbnRyeSwgaW5zdGFuY2UgbWFuYWdlclxuICpcbiAqIC0gY3JlYXRlSW5zdGFuY2UoaW5zdGFuY2VJZCwgY29kZSwgb3B0aW9ucywgZGF0YSlcbiAqIC0gcmVmcmVzaEluc3RhbmNlKGluc3RhbmNlSWQsIGRhdGEpXG4gKiAtIGRlc3Ryb3lJbnN0YW5jZShpbnN0YW5jZUlkKVxuICogLSByZWdpc3RlckNvbXBvbmVudHMoY29tcG9uZW50cylcbiAqIC0gcmVnaXN0ZXJNb2R1bGVzKG1vZHVsZXMpXG4gKiAtIGdldFJvb3QoaW5zdGFuY2VJZClcbiAqIC0gaW5zdGFuY2VNYXBcbiAqIC0gY2FsbEpTKGluc3RhbmNlSWQsIHRhc2tzKVxuICogICAtIGZpcmVFdmVudChyZWYsIHR5cGUsIGRhdGEpXG4gKiAgIC0gY2FsbGJhY2soZnVuY0lkLCBkYXRhKVxuICovXG5cbmltcG9ydCAqIGFzIHBlcmYgZnJvbSAnLi9wZXJmJ1xuaW1wb3J0ICogYXMgY29uZmlnIGZyb20gJy4vY29uZmlnJ1xuaW1wb3J0IEFwcEluc3RhbmNlIGZyb20gJy4vYXBwJ1xuaW1wb3J0IFZtIGZyb20gJy4vdm0nXG5cbnZhciB7XG4gIG5hdGl2ZUNvbXBvbmVudE1hcFxufSA9IGNvbmZpZ1xudmFyIGluc3RhbmNlTWFwID0ge31cblxuLyoqXG4gKiBjcmVhdGUgYSBXZWV4IGluc3RhbmNlXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBpbnN0YW5jZUlkXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGNvZGVcbiAqIEBwYXJhbSAge29iamVjdH0gW29wdGlvbnNdIG9wdGlvbiBgSEFTX0xPR2AgZW5hYmxlIHByaW50IGxvZ1xuICogQHBhcmFtICB7b2JqZWN0fSBbZGF0YV1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUluc3RhbmNlKGluc3RhbmNlSWQsIGNvZGUsIG9wdGlvbnMsIGRhdGEpIHtcbiAgdmFyIGluc3RhbmNlID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cblxuICBjb25maWcuZGVidWcgPSBvcHRpb25zLmRlYnVnXG5cbiAgdmFyIHJlc3VsdFxuICBpZiAoIWluc3RhbmNlKSB7XG4gICAgcGVyZi5zdGFydCgnY3JlYXRlSW5zdGFuY2UnLCBpbnN0YW5jZUlkKVxuICAgIGluc3RhbmNlID0gbmV3IEFwcEluc3RhbmNlKGluc3RhbmNlSWQsIG9wdGlvbnMpXG4gICAgaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF0gPSBpbnN0YW5jZVxuICAgIHJlc3VsdCA9IGluc3RhbmNlLmluaXQoY29kZSwgZGF0YSlcbiAgICBwZXJmLmVuZCgnY3JlYXRlSW5zdGFuY2UnLCBpbnN0YW5jZUlkKVxuICB9IGVsc2Uge1xuICAgIHJlc3VsdCA9IG5ldyBFcnJvcihgaW52YWxpZCBpbnN0YW5jZSBpZCBcIiR7aW5zdGFuY2VJZH1cImApXG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8qKlxuICogcmVmcmVzaCBhIFdlZXggaW5zdGFuY2VcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGluc3RhbmNlSWRcbiAqIEBwYXJhbSAge29iamVjdH0gZGF0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVmcmVzaEluc3RhbmNlKGluc3RhbmNlSWQsIGRhdGEpIHtcbiAgdmFyIGluc3RhbmNlID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgdmFyIHJlc3VsdFxuICBpZiAoaW5zdGFuY2UpIHtcbiAgICBwZXJmLnN0YXJ0KCdyZWZyZXNoRGF0YScsIGluc3RhbmNlSWQpXG4gICAgcmVzdWx0ID0gaW5zdGFuY2UucmVmcmVzaERhdGEoZGF0YSlcbiAgICBwZXJmLmVuZCgncmVmcmVzaERhdGEnLCBpbnN0YW5jZUlkKVxuICB9IGVsc2Uge1xuICAgIHJlc3VsdCA9IG5ldyBFcnJvcihgaW52YWxpZCBpbnN0YW5jZSBpZCBcIiR7aW5zdGFuY2VJZH1cImApXG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKipcbiAqIGRlc3Ryb3kgYSBXZWV4IGluc3RhbmNlXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGluc3RhbmNlSWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lJbnN0YW5jZShpbnN0YW5jZUlkKSB7XG4gIHZhciBpbnN0YW5jZSA9IGluc3RhbmNlTWFwW2luc3RhbmNlSWRdXG4gIGlmICghaW5zdGFuY2UpIHtcbiAgICByZXR1cm4gbmV3IEVycm9yKGBpbnZhbGlkIGluc3RhbmNlIGlkIFwiJHtpbnN0YW5jZUlkfVwiYClcbiAgfVxuXG4gIHBlcmYuc3RhcnQoJ2Rlc3Ryb3lJbnN0YW5jZScsIGluc3RhbmNlSWQpXG4gIGluc3RhbmNlLmRlc3Ryb3koKVxuICBkZWxldGUgaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgcGVyZi5lbmQoJ2Rlc3Ryb3lJbnN0YW5jZScsIGluc3RhbmNlSWQpXG5cbiAgcmV0dXJuIGluc3RhbmNlTWFwXG59XG5cbi8qKlxuICogcmVnaXN0ZXIgdGhlIG5hbWUgb2YgZWFjaCBuYXRpdmUgY29tcG9uZW50XG4gKiBAcGFyYW0gIHthcnJheX0gY29tcG9uZW50cyBhcnJheSBvZiBuYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckNvbXBvbmVudHMoY29tcG9uZW50cykge1xuICBpZiAoQXJyYXkuaXNBcnJheShjb21wb25lbnRzKSkge1xuICAgIGNvbXBvbmVudHMuZm9yRWFjaChmdW5jdGlvbiByZWdpc3RlcihuYW1lKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbmF0aXZlQ29tcG9uZW50TWFwW25hbWVdID0gdHJ1ZVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbmFtZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG5hbWUudHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbmF0aXZlQ29tcG9uZW50TWFwW25hbWUudHlwZV0gPSBuYW1lXG4gICAgICB9XG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIHJlZ2lzdGVyIHRoZSBuYW1lIGFuZCBtZXRob2RzIG9mIGVhY2ggbW9kdWxlXG4gKiBAcGFyYW0gIHtvYmplY3R9IG1vZHVsZXMgYSBvYmplY3Qgb2YgbW9kdWxlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJNb2R1bGVzKG1vZHVsZXMpIHtcbiAgaWYgKHR5cGVvZiBtb2R1bGVzID09PSAnb2JqZWN0Jykge1xuICAgIFZtLnJlZ2lzdGVyTW9kdWxlcyhtb2R1bGVzKVxuICB9XG59XG5cbi8qKlxuICogcmVnaXN0ZXIgdGhlIG5hbWUgYW5kIG1ldGhvZHMgb2YgZWFjaCBhcGlcbiAqIEBwYXJhbSAge29iamVjdH0gYXBpcyBhIG9iamVjdCBvZiBhcGlzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3Rlck1ldGhvZHMoYXBpcykge1xuICBpZiAodHlwZW9mIGFwaXMgPT09ICdvYmplY3QnKSB7XG4gICAgVm0ucmVnaXN0ZXJNZXRob2RzKGFwaXMpXG4gIH1cbn1cblxuLyoqXG4gKiBnZXQgYSB3aG9sZSBlbGVtZW50IHRyZWUgb2YgYW4gaW5zdGFuY2VcbiAqIGZvciBkZWJ1Z2dpbmdcbiAqIEBwYXJhbSAge3N0cmluZ30gaW5zdGFuY2VJZFxuICogQHJldHVybiB7b2JqZWN0fSBhIHZpcnR1YWwgZG9tIHRyZWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJvb3QoaW5zdGFuY2VJZCkge1xuICB2YXIgaW5zdGFuY2UgPSBpbnN0YW5jZU1hcFtpbnN0YW5jZUlkXVxuICB2YXIgcmVzdWx0XG4gIGlmIChpbnN0YW5jZSkge1xuICAgIHJlc3VsdCA9IGluc3RhbmNlLmdldFJvb3RFbGVtZW50KClcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBuZXcgRXJyb3IoYGludmFsaWQgaW5zdGFuY2UgaWQgXCIke2luc3RhbmNlSWR9XCJgKVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxudmFyIGpzSGFuZGxlcnMgPSB7XG4gIGZpcmVFdmVudDogZnVuY3Rpb24gZmlyZUV2ZW50KGluc3RhbmNlSWQsIHJlZiwgdHlwZSwgZGF0YSkge1xuICAgIHZhciBpbnN0YW5jZSA9IGluc3RhbmNlTWFwW2luc3RhbmNlSWRdXG4gICAgdmFyIHJlc3VsdFxuICAgIHBlcmYuc3RhcnQoJ2ZpcmVFdmVudCcsIGluc3RhbmNlSWQgKyAnLScgKyByZWYgKyAnLScgKyB0eXBlKVxuICAgIHJlc3VsdCA9IGluc3RhbmNlLmZpcmVFdmVudChyZWYsIHR5cGUsIGRhdGEpXG4gICAgcGVyZi5lbmQoJ2ZpcmVFdmVudCcsIGluc3RhbmNlSWQgKyAnLScgKyByZWYgKyAnLScgKyB0eXBlKVxuICAgIHJldHVybiByZXN1bHRcbiAgfSxcblxuICBjYWxsYmFjazogZnVuY3Rpb24gY2FsbGJhY2soaW5zdGFuY2VJZCwgZnVuY0lkLCBkYXRhLCBpZkxhc3QpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBpbnN0YW5jZU1hcFtpbnN0YW5jZUlkXVxuICAgIHZhciByZXN1bHRcbiAgICBwZXJmLnN0YXJ0KCdjYWxsYmFjaycsXG4gICAgICBpbnN0YW5jZUlkICsgJy0nICsgZnVuY0lkICsgJy0nICsgZGF0YSArICctJyArIGlmTGFzdClcbiAgICByZXN1bHQgPSBpbnN0YW5jZS5jYWxsYmFjayhmdW5jSWQsIGRhdGEsIGlmTGFzdClcbiAgICBwZXJmLmVuZCgnY2FsbGJhY2snLFxuICAgICAgaW5zdGFuY2VJZCArICctJyArIGZ1bmNJZCArICctJyArIGRhdGEgKyAnLScgKyBpZkxhc3QpXG4gICAgcmV0dXJuIHJlc3VsdFxuICB9XG59XG5cbi8qKlxuICogYWNjZXB0IGNhbGxzIGZyb20gbmF0aXZlIChldmVudCBvciBjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGluc3RhbmNlSWRcbiAqIEBwYXJhbSAge2FycmF5fSB0YXNrcyBsaXN0IHdpdGggYG1ldGhvZGAgYW5kIGBhcmdzYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsbEpTKGluc3RhbmNlSWQsIHRhc2tzKSB7XG4gIGNvbnN0IGluc3RhbmNlID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgbGV0IHJlc3VsdHMgPSBbXVxuICBpZiAoaW5zdGFuY2UgJiYgQXJyYXkuaXNBcnJheSh0YXNrcykpIHtcbiAgICB0YXNrcy5mb3JFYWNoKCh0YXNrKSA9PiB7XG4gICAgICBjb25zdCBoYW5kbGVyID0ganNIYW5kbGVyc1t0YXNrLm1ldGhvZF1cbiAgICAgIGNvbnN0IGFyZ3MgPSBbLi4udGFzay5hcmdzXVxuICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGxvZygnamF2YXNjcmlwdDonLCB0YXNrLm1ldGhvZCwgdGFzay5hcmdzKVxuICAgICAgICBhcmdzLnVuc2hpZnQoaW5zdGFuY2VJZClcbiAgICAgICAgcmVzdWx0cy5wdXNoKGhhbmRsZXIoLi4uYXJncykpXG4gICAgICB9XG4gICAgfSlcbiAgfSBlbHNlIHtcbiAgICByZXN1bHRzLnB1c2gobmV3IEVycm9yKGBpbnZhbGlkIGluc3RhbmNlIGlkIFwiJHtpbnN0YW5jZUlkfVwiIG9yIHRhc2tzYCkpXG4gIH1cblxuICByZXR1cm4gcmVzdWx0c1xufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvZnJhbWV3b3JrLmpzXG4gKiovIiwiaW1wb3J0IGxvZyBmcm9tICcuL2xvZydcblxudmFyIGRhdGEgPSB7dHlwZTogJ3Jvb3QnLCBjaGlsZHJlbjogW119XG52YXIgY3VycmVudCA9IGRhdGFcbnZhciBzdGFjayA9IFtjdXJyZW50XVxuXG5mdW5jdGlvbiBzcGFjZXMobnVtKSB7XG4gIHJldHVybiBBcnJheShudW0pLmpvaW4oJyAnKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RhcnQodHlwZSwgaWQpIHtcbiAgdmFyIHRhc2sgPSB7dHlwZTogdHlwZSwgaWQ6IGlkLCBjaGlsZHJlbjogW10sIHN0YXJ0OiBEYXRlLm5vdygpfVxuICBjdXJyZW50LmNoaWxkcmVuLnB1c2godGFzaylcbiAgc3RhY2sucHVzaCh0YXNrKVxuICBjdXJyZW50ID0gdGFza1xuICBsb2coJ3BlcmY6JyArIHNwYWNlcyhzdGFjay5sZW5ndGggLSAxKSwgJ3N0YXJ0JywgdGFzay50eXBlLCB0YXNrLmlkKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5kKHR5cGUsIGlkKSB7XG4gIHZhciB0YXNrID0gc3RhY2sucG9wKClcbiAgdGFzay5lbmQgPSBEYXRlLm5vdygpXG4gIGN1cnJlbnQgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXVxuICBsb2coJ3BlcmY6JyArIHNwYWNlcyhzdGFjay5sZW5ndGgpLCAnZW5kJyxcbiAgICAodGFzay5lbmQgLSB0YXNrLnN0YXJ0KSArICdtcycsIHRhc2sudHlwZSwgdGFzay5pZClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc2V0KCkge1xuICBkYXRhLmNoaWxkcmVuID0gW11cbiAgY3VycmVudCA9IGRhdGFcbiAgc3RhY2subGVuZ3RoID0gMFxuICBzdGFjay5wdXNoKGN1cnJlbnQpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b0pTT04oKSB7XG4gIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGRhdGEpKVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvcGVyZi5qc1xuICoqLyIsImltcG9ydCAqIGFzIGNvbmZpZyBmcm9tICcuL2NvbmZpZydcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbG9nKC4uLmFyZ3MpIHtcbiAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgIGdsb2JhbC5jb25zb2xlLmxvZyguLi5hcmdzKVxuICB9XG59XG5cbmdsb2JhbC5sb2cgPSBsb2dcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi9sb2cuanNcbiAqKi8iLCJleHBvcnQgY29uc3QgbmF0aXZlQ29tcG9uZW50TWFwID0ge1xuICB0ZXh0OiB0cnVlLFxuICBpbWFnZTogdHJ1ZSxcbiAgY29udGFpbmVyOiB0cnVlLFxuICBzbGlkZXI6IHtcbiAgICB0eXBlOiAnc2xpZGVyJyxcbiAgICBhcHBlbmQ6ICd0cmVlJ1xuICB9LFxuICBjZWxsOiB7XG4gICAgdHlwZTogJ2NlbGwnLFxuICAgIGFwcGVuZDogJ3RyZWUnXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGN1c3RvbUNvbXBvbmVudE1hcCA9IHt9XG5cbmV4cG9ydCB2YXIgZGVidWcgPSBmYWxzZVxuXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi9jb25maWcuanNcbiAqKi8iLCIvKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIFdlZXggaW5zdGFuY2UgY29uc3RydWN0b3IgJiBkZWZpbml0aW9uXG4gKi9cblxuaW1wb3J0IHt0eXBvZiwgZXh0ZW5kfSBmcm9tICcuLi91dGlsJ1xuaW1wb3J0ICogYXMgcGVyZiBmcm9tICcuLi9wZXJmJ1xuaW1wb3J0ICogYXMgYnVuZGxlIGZyb20gJy4vYnVuZGxlJ1xuaW1wb3J0ICogYXMgY3RybCBmcm9tICcuL2N0cmwnXG5pbXBvcnQgRGlmZmVyIGZyb20gJy4vZGlmZmVyJ1xuXG5pbXBvcnQgRXZlbnRNYW5hZ2VyIGZyb20gJy4vZXZlbnQnXG5pbXBvcnQgTGlzdGVuZXIgZnJvbSAnLi9kb20tbGlzdGVuZXInXG5pbXBvcnQge0RvY3VtZW50LCBOb2RlfSBmcm9tICcuL2RvbSdcbmltcG9ydCB7cmVnaXN0ZXJDb21wb25lbnQsIHJlcXVpcmVDb21wb25lbnQsIHJlcXVpcmVNb2R1bGV9IGZyb20gJy4vcmVnaXN0ZXInXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFwcEluc3RhbmNlKGluc3RhbmNlSWQsIG9wdGlvbnMpIHtcbiAgcGVyZi5zdGFydCgnaW5pdEluc3RhbmNlJywgaW5zdGFuY2VJZClcbiAgdGhpcy5pZCA9IGluc3RhbmNlSWRcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICB0aGlzLnZtID0gbnVsbFxuICB0aGlzLmRvYyA9IG5ldyBEb2N1bWVudChpbnN0YW5jZUlkKVxuICB0aGlzLmN1c3RvbUNvbXBvbmVudE1hcCA9IHt9XG4gIHRoaXMuY2FsbGJhY2tzID0ge31cbiAgdGhpcy5kaWZmZXIgPSBuZXcgRGlmZmVyKGluc3RhbmNlSWQpXG4gIHRoaXMudWlkID0gMFxuICB0aGlzLnJlbmRlcmVkID0gZmFsc2VcbiAgdGhpcy5ldmVudE1hbmFnZXIgPSBuZXcgRXZlbnRNYW5hZ2VyKClcbiAgdGhpcy5saXN0ZW5lciA9IG5ldyBMaXN0ZW5lcih0aGlzLmlkLCAodGFza3MpID0+IHtcbiAgICB0aGlzLmNhbGxUYXNrcyh0YXNrcylcbiAgfSlcbiAgdGhpcy5kb2Muc2V0RXZlbnRNYW5hZ2VyKHRoaXMuZXZlbnRNYW5hZ2VyKVxuICB0aGlzLmRvYy5zZXRMaXN0ZW5lcih0aGlzLmxpc3RlbmVyKVxuXG4gIHBlcmYuZW5kKCdpbml0SW5zdGFuY2UnLCBpbnN0YW5jZUlkKVxufVxuXG5mdW5jdGlvbiBub3JtYWxpemUoYXBwLCB2KSB7XG4gIHZhciB0eXBlID0gdHlwb2YodilcblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICd1bmRlZmluZWQnOlxuICAgIGNhc2UgJ251bGwnOlxuICAgICAgcmV0dXJuICcnXG4gICAgY2FzZSAncmVnZXhwJzpcbiAgICAgIHJldHVybiB2LnRvU3RyaW5nKClcbiAgICBjYXNlICdkYXRlJzpcbiAgICAgIHJldHVybiB2LnRvSVNPU3RyaW5nKClcbiAgICBjYXNlICdudW1iZXInOlxuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgY2FzZSAnYXJyYXknOlxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAodiBpbnN0YW5jZW9mIE5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHYucmVmXG4gICAgICB9XG4gICAgICByZXR1cm4gdlxuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgIGFwcC5jYWxsYmFja3NbKythcHAudWlkXSA9IHZcbiAgICAgIHJldHVybiBhcHAudWlkLnRvU3RyaW5nKClcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHYpXG4gIH1cbn1cblxuQXBwSW5zdGFuY2UucHJvdG90eXBlLmNhbGxUYXNrcyA9IGZ1bmN0aW9uICh0YXNrcykge1xuICBpZiAodHlwb2YodGFza3MpICE9PSAnYXJyYXknKSB7XG4gICAgdGFza3MgPSBbdGFza3NdXG4gIH1cblxuICB0YXNrcy5mb3JFYWNoKCh0YXNrKSA9PiB7XG4gICAgdGFzay5hcmdzID0gdGFzay5hcmdzLm1hcChhcmcgPT4gbm9ybWFsaXplKHRoaXMsIGFyZykpXG4gIH0pXG5cbiAgY2FsbE5hdGl2ZSh0aGlzLmlkLCB0YXNrcywgJy0xJylcbn1cblxuZXh0ZW5kKEFwcEluc3RhbmNlLnByb3RvdHlwZSwgYnVuZGxlLCBjdHJsLCB7XG4gIHJlZ2lzdGVyQ29tcG9uZW50LFxuICByZXF1aXJlQ29tcG9uZW50LFxuICByZXF1aXJlTW9kdWxlXG59KVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL2luZGV4LmpzXG4gKiovIiwiLy8vIGxhbmcuanNcbmltcG9ydCBDb25maWcgZnJvbSAnLi4vY29uZmlnJ1xuXG4vKipcbiAqIENoZWNrIGlzIGEgc3RyaW5nIHN0YXJ0cyB3aXRoICQgb3IgX1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblxuZXhwb3J0IHZhciBpc1Jlc2VydmVkID0gKHN0cikgPT4ge1xuICBsZXQgYyA9IChzdHIgKyAnJykuY2hhckNvZGVBdCgwKVxuICByZXR1cm4gYyA9PT0gMHgyNCB8fCBjID09PSAweDVGXG59XG5cbi8qKlxuICogQ2FtZWxpemUgYSBoeXBoZW4tZGVsbWl0ZWQgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuXG5sZXQgY2FtZWxSRSA9IC8tKFxcdykvZ1xuZnVuY3Rpb24gdG9VcHBlciAoXywgYykge1xuICByZXR1cm4gYyA/IGMudG9VcHBlckNhc2UgKCkgOiAnJ1xufVxuZXhwb3J0IHZhciBjYW1lbGl6ZSA9IChzdHIpID0+IHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKGNhbWVsUkUsIHRvVXBwZXIpXG59XG5cbi8qKlxuICogU2ltcGxlIGJpbmQsIGZhc3RlciB0aGFuIG5hdGl2ZVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5leHBvcnQgdmFyIGJpbmQgPSBmdW5jdGlvbiAoZm4sIGN0eCkge1xuICByZXR1cm4gZnVuY3Rpb24gKGEpIHtcbiAgICBsZXQgbCA9IGFyZ3VtZW50cy5sZW5ndGhcbiAgICByZXR1cm4gbFxuICAgICAgPyBsID4gMVxuICAgICAgICA/IGZuLmFwcGx5KGN0eCwgYXJndW1lbnRzKVxuICAgICAgICA6IGZuLmNhbGwoY3R4LCBhKVxuICAgICAgOiBmbi5jYWxsKGN0eClcbiAgfVxufVxuXG4vKipcbiAqIENvbnZlcnQgYW4gQXJyYXktbGlrZSBvYmplY3QgdG8gYSByZWFsIEFycmF5LlxuICpcbiAqIEBwYXJhbSB7QXJyYXktbGlrZX0gbGlzdFxuICogQHBhcmFtIHtOdW1iZXJ9IFtzdGFydF0gLSBzdGFydCBpbmRleFxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cblxuZXhwb3J0IHZhciB0b0FycmF5ID0gKGxpc3QsIHN0YXJ0KSA9PiB7XG4gIHN0YXJ0ID0gc3RhcnQgfHwgMFxuICBsZXQgaSA9IGxpc3QubGVuZ3RoIC0gc3RhcnRcbiAgbGV0IHJldCA9IG5ldyBBcnJheShpKVxuICB3aGlsZSAoaS0tKSB7XG4gICAgcmV0W2ldID0gbGlzdFtpICsgc3RhcnRdXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG4vKipcbiAqIE1peCBwcm9wZXJ0aWVzIGludG8gdGFyZ2V0IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdG9cbiAqIEBwYXJhbSB7T2JqZWN0fSBmcm9tXG4gKi9cblxuZXhwb3J0IHZhciBleHRlbmQgPSAodGFyZ2V0LCAuLi5zcmMpID0+IHtcbiAgaWYgKHR5cGVvZiBPYmplY3QuYXNzaWduID09PSAnZnVuY3Rpb24nKSB7XG4gICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIC4uLnNyYylcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBmaXJzdCA9IHNyYy5zaGlmdCgpXG4gICAgZm9yIChjb25zdCBrZXkgaW4gZmlyc3QpIHtcbiAgICAgIHRhcmdldFtrZXldID0gZmlyc3Rba2V5XVxuICAgIH1cbiAgICBpZiAoc3JjLmxlbmd0aCkge1xuICAgICAgZXh0ZW5kKHRhcmdldCwgLi4uc3JjKVxuICAgIH1cbiAgfVxuICByZXR1cm4gdGFyZ2V0XG59XG5cbi8qKlxuICogUXVpY2sgb2JqZWN0IGNoZWNrIC0gdGhpcyBpcyBwcmltYXJpbHkgdXNlZCB0byB0ZWxsXG4gKiBPYmplY3RzIGZyb20gcHJpbWl0aXZlIHZhbHVlcyB3aGVuIHdlIGtub3cgdGhlIHZhbHVlXG4gKiBpcyBhIEpTT04tY29tcGxpYW50IHR5cGUuXG4gKlxuICogQHBhcmFtIHsqfSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblxuZXhwb3J0IHZhciBpc09iamVjdCA9IChvYmopID0+IHtcbiAgcmV0dXJuICEhKG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jylcbn1cblxuLyoqXG4gKiBTdHJpY3Qgb2JqZWN0IHR5cGUgY2hlY2suIE9ubHkgcmV0dXJucyB0cnVlXG4gKiBmb3IgcGxhaW4gSmF2YVNjcmlwdCBvYmplY3RzLlxuICpcbiAqIEBwYXJhbSB7Kn0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmxldCB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdcbmV4cG9ydCB2YXIgaXNQbGFpbk9iamVjdCA9IChvYmopID0+IHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgT2JqZWN0XSdcbn1cblxuLyoqXG4gKiBBcnJheSB0eXBlIGNoZWNrLlxuICpcbiAqIEBwYXJhbSB7Kn0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmV4cG9ydCB2YXIgaXNBcnJheSA9IChvYmopID0+IHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkob2JqKVxufVxuXG5leHBvcnQgdmFyIHN0cmluZ2lmeSA9ICh4KSA9PiB7XG4gIHJldHVybiB0eXBlb2YgeCA9PT0gJ3VuZGVmaW5lZCcgfHwgeCA9PT0gbnVsbCB8fCB0eXBlb2YoeCkgPT09ICdmdW5jdGlvbidcbiAgICA/ICcnXG4gICAgOiB0eXBlb2YgeCA9PT0gJ29iamVjdCdcbiAgICAgID8geCBpbnN0YW5jZW9mIFJlZ0V4cFxuICAgICAgICA/IHgudG9TdHJpbmcoKVxuICAgICAgICA6IHggaW5zdGFuY2VvZiBEYXRlXG4gICAgICAgICAgPyBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHgpKVxuICAgICAgICAgIDogSlNPTi5zdHJpbmdpZnkoeClcbiAgICAgIDogeC50b1N0cmluZygpXG59XG5cbmV4cG9ydCB2YXIgdHlwb2YgPSAodikgPT4ge1xuICBsZXQgcyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KVxuICByZXR1cm4gcy5zdWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKS50b0xvd2VyQ2FzZSgpXG59XG5cbmV4cG9ydCB2YXIgbm9ybWFsaXplID0gKHYpID0+IHtcbiAgbGV0IHR5cGUgPSB0eXBvZih2KVxuXG4gIHN3aXRjaCh0eXBlKSB7XG4gICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICBjYXNlICdudWxsJzpcbiAgICAgIHJldHVybiAnJ1xuICAgIGNhc2UgJ3JlZ2V4cCc6XG4gICAgICByZXR1cm4gdi50b1N0cmluZygpXG4gICAgY2FzZSAnZGF0ZSc6XG4gICAgICByZXR1cm4gdi50b0lTT1N0cmluZygpXG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgIGNhc2UgJ2FycmF5JzpcbiAgICBjYXNlICdvYmplY3QnOlxuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgIHJldHVybiB2XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2KVxuICB9XG59XG5cbi8qKlxuICogRGVmaW5lIGEgbm9uLWVudW1lcmFibGUgcHJvcGVydHlcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHBhcmFtIHtCb29sZWFufSBbZW51bWVyYWJsZV1cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmluZSA9IChvYmosIGtleSwgdmFsLCBlbnVtZXJhYmxlKSA9PiB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgIHZhbHVlOiB2YWwsXG4gICAgZW51bWVyYWJsZTogISFlbnVtZXJhYmxlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KVxufVxuXG4vKipcbiAqIE1hbnVhbCBpbmRleE9mIGJlY2F1c2UgaXQncyBzbGlnaHRseSBmYXN0ZXIgdGhhblxuICogbmF0aXZlLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGFyclxuICogQHBhcmFtIHsqfSBvYmpcbiAqL1xuXG5leHBvcnQgdmFyIGluZGV4T2YgPSAoYXJyLCBvYmopID0+IHtcbiAgZm9yIChsZXQgaSA9IDAsIGwgPSBhcnIubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKGFycltpXSA9PT0gb2JqKSByZXR1cm4gaVxuICB9XG4gIHJldHVybiAtMVxufVxuXG5cbi8vLyBkZWJ1Zy5qc1xuXG5cbmNvbnN0IGhhc0NvbnNvbGUgPSB0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCdcblxuLyoqXG4gKiBMb2cgYSBtZXNzYWdlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2dcbiAqL1xuXG5leHBvcnQgdmFyIGxvZyA9IChtc2cpID0+IHtcbiAgY29uc3QgX2NvbmZpZyA9IENvbmZpZyB8fCB7fVxuICBpZiAoaGFzQ29uc29sZSAmJiBfY29uZmlnLmRlYnVnKSB7XG4gICAgY29uc29sZS5sb2cuY2FsbCh0aGlzLCAnW2luZm9dOiAnLCBtc2cpXG4gIH1cbn1cblxuLyoqXG4gKiBXZSd2ZSBnb3QgYSBwcm9ibGVtIGhlcmUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1zZ1xuICovXG5cbmV4cG9ydCB2YXIgd2FybiA9IChtc2cpID0+IHtcbiAgLy8gaWYgKGhhc0NvbnNvbGUgJiYgKCFjb25maWcuc2lsZW50IHx8IGNvbmZpZy5kZWJ1ZykpIHtcbiAgaWYgKGhhc0NvbnNvbGUpIHtcbiAgICBjb25zb2xlLndhcm4uY2FsbCh0aGlzLCAnW3dhcm5dOiAnLCBtc2cpXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgLy8gaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgIC8vICAgLyoganNoaW50IGRlYnVnOiB0cnVlICovXG4gICAgLy8gICBkZWJ1Z2dlclxuICAgIC8vIH1cbiAgfVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdXRpbC9pbmRleC5qc1xuICoqLyIsIi8qKlxuICogQGZpbGVPdmVydmlld1xuICogYXBpIHRoYXQgaW52b2tlZCBieSBqcyBidW5kbGUgY29kZVxuICpcbiAqIC0gZGVmaW5lKG5hbWUsIGZhY3RvcnkpOiBkZWZpbmUgYSBuZXcgY29tcG9zZWQgY29tcG9uZW50IHR5cGVcbiAqIC0gYm9vdHN0cmFwKHR5cGUsIGNvbmZpZywgZGF0YSk6IHJlcXVpcmUgYSBjZXJ0YWluIHR5cGUgJlxuICogICAgICAgICByZW5kZXIgd2l0aCAob3B0aW9uYWwpIGRhdGFcbiAqXG4gKiBkZXByZWNhdGVkOlxuICogLSByZWdpc3Rlcih0eXBlLCBvcHRpb25zKTogcmVnaXN0ZXIgYSBuZXcgY29tcG9zZWQgY29tcG9uZW50IHR5cGVcbiAqIC0gcmVuZGVyKHR5cGUsIGRhdGEpOiByZW5kZXIgYnkgYSBjZXJ0YWluIHR5cGUgd2l0aCAob3B0aW9uYWwpIGRhdGFcbiAqIC0gcmVxdWlyZSh0eXBlKShkYXRhKTogcmVxdWlyZSBhIHR5cGUgdGhlbiByZW5kZXIgd2l0aCBkYXRhXG4gKi9cblxuaW1wb3J0IHNlbXZlciBmcm9tICdzZW12ZXInXG5pbXBvcnQgKiBhcyBfIGZyb20gJy4uL3V0aWwnXG5pbXBvcnQgKiBhcyBjb25maWcgZnJvbSAnLi4vY29uZmlnJ1xuaW1wb3J0ICogYXMgcGVyZiBmcm9tICcuLi9wZXJmJ1xuaW1wb3J0IFZtIGZyb20gJy4uL3ZtJ1xuaW1wb3J0ICogYXMgZG93bmdyYWRlIGZyb20gJy4vZG93bmdyYWRlJ1xuXG5jb25zdCBXRUVYX0NPTVBPTkVOVF9SRUcgPSAvXlxcQHdlZXgtY29tcG9uZW50XFwvL1xuY29uc3QgV0VFWF9NT0RVTEVfUkVHID0gL15cXEB3ZWV4LW1vZHVsZVxcLy9cbmNvbnN0IE5PUk1BTF9NT0RVTEVfUkVHID0gL15cXC57MSwyfVxcLy9cbmNvbnN0IEpTX1NVUkZJWF9SRUcgPSAvXFwuanMkL1xuXG5jb25zdCBpc1dlZXhDb21wb25lbnQgPSBuYW1lID0+ICEhbmFtZS5tYXRjaChXRUVYX0NPTVBPTkVOVF9SRUcpXG5jb25zdCBpc1dlZXhNb2R1bGUgPSBuYW1lID0+ICEhbmFtZS5tYXRjaChXRUVYX01PRFVMRV9SRUcpXG5jb25zdCBpc05vcm1hbE1vZHVsZSA9IG5hbWUgPT4gISFuYW1lLm1hdGNoKE5PUk1BTF9NT0RVTEVfUkVHKVxuY29uc3QgaXNOcG1Nb2R1bGUgPSBuYW1lID0+ICFpc1dlZXhDb21wb25lbnQobmFtZSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFpc1dlZXhNb2R1bGUobmFtZSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFpc05vcm1hbE1vZHVsZShuYW1lKVxuXG5mdW5jdGlvbiByZW1vdmVXZWV4UHJlZml4KHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoV0VFWF9DT01QT05FTlRfUkVHLCAnJylcbiAgICAgICAgICAucmVwbGFjZShXRUVYX01PRFVMRV9SRUcsICcnKVxufVxuXG5mdW5jdGlvbiByZW1vdmVKU1N1cmZpeChzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKEpTX1NVUkZJWF9SRUcsICcnKVxufVxuXG5sZXQgY29tbW9uTW9kdWxlcyA9IHt9XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhckNvbW1vbk1vZHVsZXMoKSB7XG4gIGNvbW1vbk1vZHVsZXMgPSB7fVxufVxuXG4vLyBkZWZpbmUobmFtZSwgZmFjdG9yeSkgZm9yIHByaW1hcnkgdXNhZ2Vcbi8vIG9yXG4vLyBkZWZpbmUobmFtZSwgZGVwcywgZmFjdG9yeSkgZm9yIGNvbXBhdGliaWxpdHlcbi8vIE5vdGljZTogRE8gTk9UIHVzZSBmdW5jdGlvbiBkZWZpbmUoKSB7fSxcbi8vIGl0IHdpbGwgY2F1c2UgZXJyb3IgYWZ0ZXIgYnVpbGRlZCBieSB3ZWJwYWNrXG5leHBvcnQgdmFyIGRlZmluZSA9IGZ1bmN0aW9uIChuYW1lLCBkZXBzLCBmYWN0b3J5KSB7XG4gIHBlcmYuc3RhcnQoJ2RlZmluZScsIG5hbWUpXG5cbiAgaWYgKF8udHlwb2YoZGVwcykgPT09ICdmdW5jdGlvbicpIHtcbiAgICBmYWN0b3J5ID0gZGVwc1xuICAgIGRlcHMgPSBbXVxuICB9XG5cbiAgbGV0IF9yZXF1aXJlID0gKG5hbWUpID0+IHtcbiAgICBsZXQgY2xlYW5OYW1lXG5cbiAgICBpZiAoaXNXZWV4Q29tcG9uZW50KG5hbWUpKSB7XG4gICAgICBjbGVhbk5hbWUgPSByZW1vdmVXZWV4UHJlZml4KG5hbWUpXG4gICAgICByZXR1cm4gdGhpcy5yZXF1aXJlQ29tcG9uZW50KGNsZWFuTmFtZSlcbiAgICB9XG4gICAgaWYgKGlzV2VleE1vZHVsZShuYW1lKSkge1xuICAgICAgY2xlYW5OYW1lID0gcmVtb3ZlV2VleFByZWZpeChuYW1lKVxuICAgICAgcmV0dXJuIHRoaXMucmVxdWlyZU1vZHVsZShjbGVhbk5hbWUpXG4gICAgfVxuICAgIGlmIChpc05vcm1hbE1vZHVsZShuYW1lKSkge1xuICAgICAgY2xlYW5OYW1lID0gcmVtb3ZlSlNTdXJmaXgobmFtZSlcbiAgICAgIHJldHVybiBjb21tb25Nb2R1bGVzW25hbWVdXG4gICAgfVxuICAgIGlmIChpc05wbU1vZHVsZShuYW1lKSkge1xuICAgICAgY2xlYW5OYW1lID0gcmVtb3ZlSlNTdXJmaXgobmFtZSlcbiAgICAgIHJldHVybiBjb21tb25Nb2R1bGVzW25hbWVdXG4gICAgfVxuICB9XG4gIGxldCBfbW9kdWxlID0ge2V4cG9ydHM6IHt9fVxuXG4gIGxldCBjbGVhbk5hbWVcbiAgaWYgKGlzV2VleENvbXBvbmVudChuYW1lKSkge1xuICAgIGNsZWFuTmFtZSA9IHJlbW92ZVdlZXhQcmVmaXgobmFtZSlcblxuICAgIGZhY3RvcnkoX3JlcXVpcmUsIF9tb2R1bGUuZXhwb3J0cywgX21vZHVsZSlcblxuICAgIHRoaXMucmVnaXN0ZXJDb21wb25lbnQoY2xlYW5OYW1lLCBfbW9kdWxlLmV4cG9ydHMpXG4gIH0gZWxzZSBpZiAoaXNXZWV4TW9kdWxlKG5hbWUpKSB7XG4gICAgY2xlYW5OYW1lID0gcmVtb3ZlV2VleFByZWZpeChuYW1lKVxuXG4gICAgZmFjdG9yeShfcmVxdWlyZSwgX21vZHVsZS5leHBvcnRzLCBfbW9kdWxlKVxuXG4gICAgVm0ucmVnaXN0ZXJNb2R1bGVzKHtcbiAgICAgIFtjbGVhbk5hbWVdOiBfbW9kdWxlLmV4cG9ydHNcbiAgICB9KVxuICB9IGVsc2UgaWYgKGlzTm9ybWFsTW9kdWxlKG5hbWUpKSB7XG4gICAgY2xlYW5OYW1lID0gcmVtb3ZlSlNTdXJmaXgobmFtZSlcblxuICAgIGZhY3RvcnkoX3JlcXVpcmUsIF9tb2R1bGUuZXhwb3J0cywgX21vZHVsZSlcblxuICAgIGNvbW1vbk1vZHVsZXNbY2xlYW5OYW1lXSA9IF9tb2R1bGUuZXhwb3J0c1xuICB9IGVsc2UgaWYgKGlzTnBtTW9kdWxlKG5hbWUpKSB7XG4gICAgY2xlYW5OYW1lID0gcmVtb3ZlSlNTdXJmaXgobmFtZSlcblxuICAgIGZhY3RvcnkoX3JlcXVpcmUsIF9tb2R1bGUuZXhwb3J0cywgX21vZHVsZSlcblxuICAgIGxldCBleHBvcnRzID0gX21vZHVsZS5leHBvcnRzXG4gICAgaWYgKGV4cG9ydHMudGVtcGxhdGUgfHxcbiAgICAgICAgZXhwb3J0cy5zdHlsZSB8fFxuICAgICAgICBleHBvcnRzLm1ldGhvZHMpIHtcbiAgICAgIC8vIGRvd25ncmFkZSB0byBvbGQgZGVmaW5lIG1ldGhvZCAoZGVmaW5lKCdjb21wb25lbnROYW1lJywgZmFjdG9yeSkpXG4gICAgICAvLyB0aGUgZXhwb3J0cyBjb250YWluIG9uZSBrZXkgb2YgdGVtcGxhdGUsIHN0eWxlIG9yIG1ldGhvZHNcbiAgICAgIC8vIGJ1dCBpdCBoYXMgcmlzayEhIVxuICAgICAgdGhpcy5yZWdpc3RlckNvbXBvbmVudChjbGVhbk5hbWUsIGV4cG9ydHMpXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbW1vbk1vZHVsZXNbY2xlYW5OYW1lXSA9IF9tb2R1bGUuZXhwb3J0c1xuICAgIH1cbiAgfVxuXG4gIHBlcmYuZW5kKCdkZWZpbmUnLCBuYW1lKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYm9vdHN0cmFwKG5hbWUsIGNvbmZpZywgZGF0YSkge1xuICBsZXQgY2xlYW5OYW1lXG5cbiAgaWYgKGlzV2VleENvbXBvbmVudChuYW1lKSkge1xuICAgIGNsZWFuTmFtZSA9IHJlbW92ZVdlZXhQcmVmaXgobmFtZSlcbiAgfSBlbHNlIGlmIChpc05wbU1vZHVsZShuYW1lKSkge1xuICAgIGNsZWFuTmFtZSA9IHJlbW92ZUpTU3VyZml4KG5hbWUpXG4gICAgLy8gY2hlY2sgaWYgZGVmaW5lIGJ5IG9sZCAnZGVmaW5lJyBtZXRob2RcbiAgICBpZiAoIXRoaXMuY3VzdG9tQ29tcG9uZW50TWFwW2NsZWFuTmFtZV0pIHtcbiAgICAgIHJldHVybiBuZXcgRXJyb3IoYEl0J3Mgbm90IGEgY29tcG9uZW50OiAke25hbWV9YClcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcihgV3JvbmcgY29tcG9uZW50IG5hbWU6ICR7bmFtZX1gKVxuICB9XG5cbiAgY29uZmlnID0gXy5pc1BsYWluT2JqZWN0KGNvbmZpZykgPyBjb25maWcgOiB7fVxuXG4gIGlmICh0eXBlb2YgY29uZmlnLnRyYW5zZm9ybWVyVmVyc2lvbiA9PT0gJ3N0cmluZycgJiZcbiAgICB0eXBlb2YgZ2xvYmFsLm5lZWRUcmFuc2Zvcm1lclZlcnNpb24gPT09ICdzdHJpbmcnICYmXG4gICAgIXNlbXZlci5zYXRpc2ZpZXMoY29uZmlnLnRyYW5zZm9ybWVyVmVyc2lvbixcbiAgICAgIGdsb2JhbC5uZWVkVHJhbnNmb3JtZXJWZXJzaW9uKSkge1xuICAgIHJldHVybiBuZXcgRXJyb3IoYEpTIEJ1bmRsZSB2ZXJzaW9uOiAke2NvbmZpZy50cmFuc2Zvcm1lclZlcnNpb259IGAgK1xuICAgICAgYG5vdCBjb21wYXRpYmxlIHdpdGggJHtnbG9iYWwubmVlZFRyYW5zZm9ybWVyVmVyc2lvbn1gKVxuICB9XG5cbiAgbGV0IF9jaGVja0Rvd25ncmFkZSA9IGRvd25ncmFkZS5jaGVjayhjb25maWcuZG93bmdyYWRlKVxuICBpZiAoX2NoZWNrRG93bmdyYWRlLmlzRG93bmdyYWRlKSB7XG4gICAgdGhpcy5jYWxsVGFza3MoW3tcbiAgICAgIG1vZHVsZTogJ2luc3RhbmNlV3JhcCcsXG4gICAgICBtZXRob2Q6ICdlcnJvcicsXG4gICAgICBhcmdzOiBbXG4gICAgICAgIF9jaGVja0Rvd25ncmFkZS5lcnJvclR5cGUsXG4gICAgICAgIF9jaGVja0Rvd25ncmFkZS5jb2RlLFxuICAgICAgICBfY2hlY2tEb3duZ3JhZGUuZXJyb3JNZXNzYWdlXG4gICAgICBdXG4gICAgfV0pXG4gICAgcmV0dXJuIG5ldyBFcnJvcihgRG93bmdyYWRlOiAke2NvbmZpZy5kb3duZ3JhZGV9YClcbiAgfVxuXG4gIHBlcmYuc3RhcnQoJ2NyZWF0ZSB2bScsIGNsZWFuTmFtZSlcblxuICB0aGlzLnZtID0gbmV3IFZtKGNsZWFuTmFtZSwge19hcHA6IHRoaXN9LCBudWxsLCBkYXRhLCB7XG4gICAgJ2hvb2s6cmVhZHknOiAoKSA9PiB7XG4gICAgICBwZXJmLmVuZCgnY3JlYXRlIHZtJywgY2xlYW5OYW1lKVxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXIodHlwZSwgb3B0aW9ucykge1xuICBwZXJmLnN0YXJ0KCdyZWdpc3RlcicsIHR5cGUpXG4gIHRoaXMucmVnaXN0ZXJDb21wb25lbnQodHlwZSwgb3B0aW9ucylcbiAgcGVyZi5lbmQoJ3JlZ2lzdGVyJywgdHlwZSlcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyKHR5cGUsIGRhdGEpIHtcbiAgcmV0dXJuIHRoaXMuYm9vdHN0cmFwKHR5cGUsIHt9LCBkYXRhKVxufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlKHR5cGUpIHtcbiAgcmV0dXJuIChkYXRhKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuYm9vdHN0cmFwKHR5cGUsIHt9LCBkYXRhKVxuICB9XG59XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi9hcHAvYnVuZGxlLmpzXG4gKiovIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gU2VtVmVyO1xuXG4vLyBUaGUgZGVidWcgZnVuY3Rpb24gaXMgZXhjbHVkZWQgZW50aXJlbHkgZnJvbSB0aGUgbWluaWZpZWQgdmVyc2lvbi5cbi8qIG5vbWluICovIHZhciBkZWJ1Zztcbi8qIG5vbWluICovIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ29iamVjdCcgJiZcbiAgICAvKiBub21pbiAqLyBwcm9jZXNzLmVudiAmJlxuICAgIC8qIG5vbWluICovIHByb2Nlc3MuZW52Lk5PREVfREVCVUcgJiZcbiAgICAvKiBub21pbiAqLyAvXFxic2VtdmVyXFxiL2kudGVzdChwcm9jZXNzLmVudi5OT0RFX0RFQlVHKSlcbiAgLyogbm9taW4gKi8gZGVidWcgPSBmdW5jdGlvbigpIHtcbiAgICAvKiBub21pbiAqLyB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG4gICAgLyogbm9taW4gKi8gYXJncy51bnNoaWZ0KCdTRU1WRVInKTtcbiAgICAvKiBub21pbiAqLyBjb25zb2xlLmxvZy5hcHBseShjb25zb2xlLCBhcmdzKTtcbiAgICAvKiBub21pbiAqLyB9O1xuLyogbm9taW4gKi8gZWxzZVxuICAvKiBub21pbiAqLyBkZWJ1ZyA9IGZ1bmN0aW9uKCkge307XG5cbi8vIE5vdGU6IHRoaXMgaXMgdGhlIHNlbXZlci5vcmcgdmVyc2lvbiBvZiB0aGUgc3BlYyB0aGF0IGl0IGltcGxlbWVudHNcbi8vIE5vdCBuZWNlc3NhcmlseSB0aGUgcGFja2FnZSB2ZXJzaW9uIG9mIHRoaXMgY29kZS5cbmV4cG9ydHMuU0VNVkVSX1NQRUNfVkVSU0lPTiA9ICcyLjAuMCc7XG5cbnZhciBNQVhfTEVOR1RIID0gMjU2O1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiB8fCA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vLyBUaGUgYWN0dWFsIHJlZ2V4cHMgZ28gb24gZXhwb3J0cy5yZVxudmFyIHJlID0gZXhwb3J0cy5yZSA9IFtdO1xudmFyIHNyYyA9IGV4cG9ydHMuc3JjID0gW107XG52YXIgUiA9IDA7XG5cbi8vIFRoZSBmb2xsb3dpbmcgUmVndWxhciBFeHByZXNzaW9ucyBjYW4gYmUgdXNlZCBmb3IgdG9rZW5pemluZyxcbi8vIHZhbGlkYXRpbmcsIGFuZCBwYXJzaW5nIFNlbVZlciB2ZXJzaW9uIHN0cmluZ3MuXG5cbi8vICMjIE51bWVyaWMgSWRlbnRpZmllclxuLy8gQSBzaW5nbGUgYDBgLCBvciBhIG5vbi16ZXJvIGRpZ2l0IGZvbGxvd2VkIGJ5IHplcm8gb3IgbW9yZSBkaWdpdHMuXG5cbnZhciBOVU1FUklDSURFTlRJRklFUiA9IFIrKztcbnNyY1tOVU1FUklDSURFTlRJRklFUl0gPSAnMHxbMS05XVxcXFxkKic7XG52YXIgTlVNRVJJQ0lERU5USUZJRVJMT09TRSA9IFIrKztcbnNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSA9ICdbMC05XSsnO1xuXG5cbi8vICMjIE5vbi1udW1lcmljIElkZW50aWZpZXJcbi8vIFplcm8gb3IgbW9yZSBkaWdpdHMsIGZvbGxvd2VkIGJ5IGEgbGV0dGVyIG9yIGh5cGhlbiwgYW5kIHRoZW4gemVybyBvclxuLy8gbW9yZSBsZXR0ZXJzLCBkaWdpdHMsIG9yIGh5cGhlbnMuXG5cbnZhciBOT05OVU1FUklDSURFTlRJRklFUiA9IFIrKztcbnNyY1tOT05OVU1FUklDSURFTlRJRklFUl0gPSAnXFxcXGQqW2EtekEtWi1dW2EtekEtWjAtOS1dKic7XG5cblxuLy8gIyMgTWFpbiBWZXJzaW9uXG4vLyBUaHJlZSBkb3Qtc2VwYXJhdGVkIG51bWVyaWMgaWRlbnRpZmllcnMuXG5cbnZhciBNQUlOVkVSU0lPTiA9IFIrKztcbnNyY1tNQUlOVkVSU0lPTl0gPSAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gKyAnKVxcXFwuJyArXG4gICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSXSArICcpJztcblxudmFyIE1BSU5WRVJTSU9OTE9PU0UgPSBSKys7XG5zcmNbTUFJTlZFUlNJT05MT09TRV0gPSAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnKVxcXFwuJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnKVxcXFwuJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gKyAnKSc7XG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb24gSWRlbnRpZmllclxuLy8gQSBudW1lcmljIGlkZW50aWZpZXIsIG9yIGEgbm9uLW51bWVyaWMgaWRlbnRpZmllci5cblxudmFyIFBSRVJFTEVBU0VJREVOVElGSUVSID0gUisrO1xuc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSXSA9ICcoPzonICsgc3JjW05VTUVSSUNJREVOVElGSUVSXSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3wnICsgc3JjW05PTk5VTUVSSUNJREVOVElGSUVSXSArICcpJztcblxudmFyIFBSRVJFTEVBU0VJREVOVElGSUVSTE9PU0UgPSBSKys7XG5zcmNbUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV0gPSAnKD86JyArIHNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnfCcgKyBzcmNbTk9OTlVNRVJJQ0lERU5USUZJRVJdICsgJyknO1xuXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb25cbi8vIEh5cGhlbiwgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgZG90LXNlcGFyYXRlZCBwcmUtcmVsZWFzZSB2ZXJzaW9uXG4vLyBpZGVudGlmaWVycy5cblxudmFyIFBSRVJFTEVBU0UgPSBSKys7XG5zcmNbUFJFUkVMRUFTRV0gPSAnKD86LSgnICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSXSArXG4gICAgICAgICAgICAgICAgICAnKD86XFxcXC4nICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSXSArICcpKikpJztcblxudmFyIFBSRVJFTEVBU0VMT09TRSA9IFIrKztcbnNyY1tQUkVSRUxFQVNFTE9PU0VdID0gJyg/Oi0/KCcgKyBzcmNbUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4nICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdICsgJykqKSknO1xuXG4vLyAjIyBCdWlsZCBNZXRhZGF0YSBJZGVudGlmaWVyXG4vLyBBbnkgY29tYmluYXRpb24gb2YgZGlnaXRzLCBsZXR0ZXJzLCBvciBoeXBoZW5zLlxuXG52YXIgQlVJTERJREVOVElGSUVSID0gUisrO1xuc3JjW0JVSUxESURFTlRJRklFUl0gPSAnWzAtOUEtWmEtei1dKyc7XG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhXG4vLyBQbHVzIHNpZ24sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIHBlcmlvZC1zZXBhcmF0ZWQgYnVpbGQgbWV0YWRhdGFcbi8vIGlkZW50aWZpZXJzLlxuXG52YXIgQlVJTEQgPSBSKys7XG5zcmNbQlVJTERdID0gJyg/OlxcXFwrKCcgKyBzcmNbQlVJTERJREVOVElGSUVSXSArXG4gICAgICAgICAgICAgJyg/OlxcXFwuJyArIHNyY1tCVUlMRElERU5USUZJRVJdICsgJykqKSknO1xuXG5cbi8vICMjIEZ1bGwgVmVyc2lvbiBTdHJpbmdcbi8vIEEgbWFpbiB2ZXJzaW9uLCBmb2xsb3dlZCBvcHRpb25hbGx5IGJ5IGEgcHJlLXJlbGVhc2UgdmVyc2lvbiBhbmRcbi8vIGJ1aWxkIG1ldGFkYXRhLlxuXG4vLyBOb3RlIHRoYXQgdGhlIG9ubHkgbWFqb3IsIG1pbm9yLCBwYXRjaCwgYW5kIHByZS1yZWxlYXNlIHNlY3Rpb25zIG9mXG4vLyB0aGUgdmVyc2lvbiBzdHJpbmcgYXJlIGNhcHR1cmluZyBncm91cHMuICBUaGUgYnVpbGQgbWV0YWRhdGEgaXMgbm90IGFcbi8vIGNhcHR1cmluZyBncm91cCwgYmVjYXVzZSBpdCBzaG91bGQgbm90IGV2ZXIgYmUgdXNlZCBpbiB2ZXJzaW9uXG4vLyBjb21wYXJpc29uLlxuXG52YXIgRlVMTCA9IFIrKztcbnZhciBGVUxMUExBSU4gPSAndj8nICsgc3JjW01BSU5WRVJTSU9OXSArXG4gICAgICAgICAgICAgICAgc3JjW1BSRVJFTEVBU0VdICsgJz8nICtcbiAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nO1xuXG5zcmNbRlVMTF0gPSAnXicgKyBGVUxMUExBSU4gKyAnJCc7XG5cbi8vIGxpa2UgZnVsbCwgYnV0IGFsbG93cyB2MS4yLjMgYW5kID0xLjIuMywgd2hpY2ggcGVvcGxlIGRvIHNvbWV0aW1lcy5cbi8vIGFsc28sIDEuMC4wYWxwaGExIChwcmVyZWxlYXNlIHdpdGhvdXQgdGhlIGh5cGhlbikgd2hpY2ggaXMgcHJldHR5XG4vLyBjb21tb24gaW4gdGhlIG5wbSByZWdpc3RyeS5cbnZhciBMT09TRVBMQUlOID0gJ1t2PVxcXFxzXSonICsgc3JjW01BSU5WRVJTSU9OTE9PU0VdICtcbiAgICAgICAgICAgICAgICAgc3JjW1BSRVJFTEVBU0VMT09TRV0gKyAnPycgK1xuICAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nO1xuXG52YXIgTE9PU0UgPSBSKys7XG5zcmNbTE9PU0VdID0gJ14nICsgTE9PU0VQTEFJTiArICckJztcblxudmFyIEdUTFQgPSBSKys7XG5zcmNbR1RMVF0gPSAnKCg/Ojx8Pik/PT8pJztcblxuLy8gU29tZXRoaW5nIGxpa2UgXCIyLipcIiBvciBcIjEuMi54XCIuXG4vLyBOb3RlIHRoYXQgXCJ4LnhcIiBpcyBhIHZhbGlkIHhSYW5nZSBpZGVudGlmZXIsIG1lYW5pbmcgXCJhbnkgdmVyc2lvblwiXG4vLyBPbmx5IHRoZSBmaXJzdCBpdGVtIGlzIHN0cmljdGx5IHJlcXVpcmVkLlxudmFyIFhSQU5HRUlERU5USUZJRVJMT09TRSA9IFIrKztcbnNyY1tYUkFOR0VJREVOVElGSUVSTE9PU0VdID0gc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJ3x4fFh8XFxcXConO1xudmFyIFhSQU5HRUlERU5USUZJRVIgPSBSKys7XG5zcmNbWFJBTkdFSURFTlRJRklFUl0gPSBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJ3x4fFh8XFxcXConO1xuXG52YXIgWFJBTkdFUExBSU4gPSBSKys7XG5zcmNbWFJBTkdFUExBSU5dID0gJ1t2PVxcXFxzXSooJyArIHNyY1tYUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnKD86JyArIHNyY1tQUkVSRUxFQVNFXSArICcpPycgK1xuICAgICAgICAgICAgICAgICAgIHNyY1tCVUlMRF0gKyAnPycgK1xuICAgICAgICAgICAgICAgICAgICcpPyk/JztcblxudmFyIFhSQU5HRVBMQUlOTE9PU0UgPSBSKys7XG5zcmNbWFJBTkdFUExBSU5MT09TRV0gPSAnW3Y9XFxcXHNdKignICsgc3JjW1hSQU5HRUlERU5USUZJRVJMT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1tYUkFOR0VJREVOVElGSUVSTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoPzonICsgc3JjW1BSRVJFTEVBU0VMT09TRV0gKyAnKT8nICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNyY1tCVUlMRF0gKyAnPycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyk/KT8nO1xuXG52YXIgWFJBTkdFID0gUisrO1xuc3JjW1hSQU5HRV0gPSAnXicgKyBzcmNbR1RMVF0gKyAnXFxcXHMqJyArIHNyY1tYUkFOR0VQTEFJTl0gKyAnJCc7XG52YXIgWFJBTkdFTE9PU0UgPSBSKys7XG5zcmNbWFJBTkdFTE9PU0VdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKicgKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnJCc7XG5cbi8vIFRpbGRlIHJhbmdlcy5cbi8vIE1lYW5pbmcgaXMgXCJyZWFzb25hYmx5IGF0IG9yIGdyZWF0ZXIgdGhhblwiXG52YXIgTE9ORVRJTERFID0gUisrO1xuc3JjW0xPTkVUSUxERV0gPSAnKD86fj4/KSc7XG5cbnZhciBUSUxERVRSSU0gPSBSKys7XG5zcmNbVElMREVUUklNXSA9ICcoXFxcXHMqKScgKyBzcmNbTE9ORVRJTERFXSArICdcXFxccysnO1xucmVbVElMREVUUklNXSA9IG5ldyBSZWdFeHAoc3JjW1RJTERFVFJJTV0sICdnJyk7XG52YXIgdGlsZGVUcmltUmVwbGFjZSA9ICckMX4nO1xuXG52YXIgVElMREUgPSBSKys7XG5zcmNbVElMREVdID0gJ14nICsgc3JjW0xPTkVUSUxERV0gKyBzcmNbWFJBTkdFUExBSU5dICsgJyQnO1xudmFyIFRJTERFTE9PU0UgPSBSKys7XG5zcmNbVElMREVMT09TRV0gPSAnXicgKyBzcmNbTE9ORVRJTERFXSArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICckJztcblxuLy8gQ2FyZXQgcmFuZ2VzLlxuLy8gTWVhbmluZyBpcyBcImF0IGxlYXN0IGFuZCBiYWNrd2FyZHMgY29tcGF0aWJsZSB3aXRoXCJcbnZhciBMT05FQ0FSRVQgPSBSKys7XG5zcmNbTE9ORUNBUkVUXSA9ICcoPzpcXFxcXiknO1xuXG52YXIgQ0FSRVRUUklNID0gUisrO1xuc3JjW0NBUkVUVFJJTV0gPSAnKFxcXFxzKiknICsgc3JjW0xPTkVDQVJFVF0gKyAnXFxcXHMrJztcbnJlW0NBUkVUVFJJTV0gPSBuZXcgUmVnRXhwKHNyY1tDQVJFVFRSSU1dLCAnZycpO1xudmFyIGNhcmV0VHJpbVJlcGxhY2UgPSAnJDFeJztcblxudmFyIENBUkVUID0gUisrO1xuc3JjW0NBUkVUXSA9ICdeJyArIHNyY1tMT05FQ0FSRVRdICsgc3JjW1hSQU5HRVBMQUlOXSArICckJztcbnZhciBDQVJFVExPT1NFID0gUisrO1xuc3JjW0NBUkVUTE9PU0VdID0gJ14nICsgc3JjW0xPTkVDQVJFVF0gKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnJCc7XG5cbi8vIEEgc2ltcGxlIGd0L2x0L2VxIHRoaW5nLCBvciBqdXN0IFwiXCIgdG8gaW5kaWNhdGUgXCJhbnkgdmVyc2lvblwiXG52YXIgQ09NUEFSQVRPUkxPT1NFID0gUisrO1xuc3JjW0NPTVBBUkFUT1JMT09TRV0gPSAnXicgKyBzcmNbR1RMVF0gKyAnXFxcXHMqKCcgKyBMT09TRVBMQUlOICsgJykkfF4kJztcbnZhciBDT01QQVJBVE9SID0gUisrO1xuc3JjW0NPTVBBUkFUT1JdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKignICsgRlVMTFBMQUlOICsgJykkfF4kJztcblxuXG4vLyBBbiBleHByZXNzaW9uIHRvIHN0cmlwIGFueSB3aGl0ZXNwYWNlIGJldHdlZW4gdGhlIGd0bHQgYW5kIHRoZSB0aGluZ1xuLy8gaXQgbW9kaWZpZXMsIHNvIHRoYXQgYD4gMS4yLjNgID09PiBgPjEuMi4zYFxudmFyIENPTVBBUkFUT1JUUklNID0gUisrO1xuc3JjW0NPTVBBUkFUT1JUUklNXSA9ICcoXFxcXHMqKScgKyBzcmNbR1RMVF0gK1xuICAgICAgICAgICAgICAgICAgICAgICdcXFxccyooJyArIExPT1NFUExBSU4gKyAnfCcgKyBzcmNbWFJBTkdFUExBSU5dICsgJyknO1xuXG4vLyB0aGlzIG9uZSBoYXMgdG8gdXNlIHRoZSAvZyBmbGFnXG5yZVtDT01QQVJBVE9SVFJJTV0gPSBuZXcgUmVnRXhwKHNyY1tDT01QQVJBVE9SVFJJTV0sICdnJyk7XG52YXIgY29tcGFyYXRvclRyaW1SZXBsYWNlID0gJyQxJDIkMyc7XG5cblxuLy8gU29tZXRoaW5nIGxpa2UgYDEuMi4zIC0gMS4yLjRgXG4vLyBOb3RlIHRoYXQgdGhlc2UgYWxsIHVzZSB0aGUgbG9vc2UgZm9ybSwgYmVjYXVzZSB0aGV5J2xsIGJlXG4vLyBjaGVja2VkIGFnYWluc3QgZWl0aGVyIHRoZSBzdHJpY3Qgb3IgbG9vc2UgY29tcGFyYXRvciBmb3JtXG4vLyBsYXRlci5cbnZhciBIWVBIRU5SQU5HRSA9IFIrKztcbnNyY1tIWVBIRU5SQU5HRV0gPSAnXlxcXFxzKignICsgc3JjW1hSQU5HRVBMQUlOXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJ1xcXFxzKy1cXFxccysnICtcbiAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbWFJBTkdFUExBSU5dICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnXFxcXHMqJCc7XG5cbnZhciBIWVBIRU5SQU5HRUxPT1NFID0gUisrO1xuc3JjW0hZUEhFTlJBTkdFTE9PU0VdID0gJ15cXFxccyooJyArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMrLVxcXFxzKycgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdcXFxccyokJztcblxuLy8gU3RhciByYW5nZXMgYmFzaWNhbGx5IGp1c3QgYWxsb3cgYW55dGhpbmcgYXQgYWxsLlxudmFyIFNUQVIgPSBSKys7XG5zcmNbU1RBUl0gPSAnKDx8Pik/PT9cXFxccypcXFxcKic7XG5cbi8vIENvbXBpbGUgdG8gYWN0dWFsIHJlZ2V4cCBvYmplY3RzLlxuLy8gQWxsIGFyZSBmbGFnLWZyZWUsIHVubGVzcyB0aGV5IHdlcmUgY3JlYXRlZCBhYm92ZSB3aXRoIGEgZmxhZy5cbmZvciAodmFyIGkgPSAwOyBpIDwgUjsgaSsrKSB7XG4gIGRlYnVnKGksIHNyY1tpXSk7XG4gIGlmICghcmVbaV0pXG4gICAgcmVbaV0gPSBuZXcgUmVnRXhwKHNyY1tpXSk7XG59XG5cbmV4cG9ydHMucGFyc2UgPSBwYXJzZTtcbmZ1bmN0aW9uIHBhcnNlKHZlcnNpb24sIGxvb3NlKSB7XG4gIGlmICh2ZXJzaW9uIGluc3RhbmNlb2YgU2VtVmVyKVxuICAgIHJldHVybiB2ZXJzaW9uO1xuXG4gIGlmICh0eXBlb2YgdmVyc2lvbiAhPT0gJ3N0cmluZycpXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgaWYgKHZlcnNpb24ubGVuZ3RoID4gTUFYX0xFTkdUSClcbiAgICByZXR1cm4gbnVsbDtcblxuICB2YXIgciA9IGxvb3NlID8gcmVbTE9PU0VdIDogcmVbRlVMTF07XG4gIGlmICghci50ZXN0KHZlcnNpb24pKVxuICAgIHJldHVybiBudWxsO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBTZW1WZXIodmVyc2lvbiwgbG9vc2UpO1xuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydHMudmFsaWQgPSB2YWxpZDtcbmZ1bmN0aW9uIHZhbGlkKHZlcnNpb24sIGxvb3NlKSB7XG4gIHZhciB2ID0gcGFyc2UodmVyc2lvbiwgbG9vc2UpO1xuICByZXR1cm4gdiA/IHYudmVyc2lvbiA6IG51bGw7XG59XG5cblxuZXhwb3J0cy5jbGVhbiA9IGNsZWFuO1xuZnVuY3Rpb24gY2xlYW4odmVyc2lvbiwgbG9vc2UpIHtcbiAgdmFyIHMgPSBwYXJzZSh2ZXJzaW9uLnRyaW0oKS5yZXBsYWNlKC9eWz12XSsvLCAnJyksIGxvb3NlKTtcbiAgcmV0dXJuIHMgPyBzLnZlcnNpb24gOiBudWxsO1xufVxuXG5leHBvcnRzLlNlbVZlciA9IFNlbVZlcjtcblxuZnVuY3Rpb24gU2VtVmVyKHZlcnNpb24sIGxvb3NlKSB7XG4gIGlmICh2ZXJzaW9uIGluc3RhbmNlb2YgU2VtVmVyKSB7XG4gICAgaWYgKHZlcnNpb24ubG9vc2UgPT09IGxvb3NlKVxuICAgICAgcmV0dXJuIHZlcnNpb247XG4gICAgZWxzZVxuICAgICAgdmVyc2lvbiA9IHZlcnNpb24udmVyc2lvbjtcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmVyc2lvbiAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIFZlcnNpb246ICcgKyB2ZXJzaW9uKTtcbiAgfVxuXG4gIGlmICh2ZXJzaW9uLmxlbmd0aCA+IE1BWF9MRU5HVEgpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmVyc2lvbiBpcyBsb25nZXIgdGhhbiAnICsgTUFYX0xFTkdUSCArICcgY2hhcmFjdGVycycpXG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNlbVZlcikpXG4gICAgcmV0dXJuIG5ldyBTZW1WZXIodmVyc2lvbiwgbG9vc2UpO1xuXG4gIGRlYnVnKCdTZW1WZXInLCB2ZXJzaW9uLCBsb29zZSk7XG4gIHRoaXMubG9vc2UgPSBsb29zZTtcbiAgdmFyIG0gPSB2ZXJzaW9uLnRyaW0oKS5tYXRjaChsb29zZSA/IHJlW0xPT1NFXSA6IHJlW0ZVTExdKTtcblxuICBpZiAoIW0pXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBWZXJzaW9uOiAnICsgdmVyc2lvbik7XG5cbiAgdGhpcy5yYXcgPSB2ZXJzaW9uO1xuXG4gIC8vIHRoZXNlIGFyZSBhY3R1YWxseSBudW1iZXJzXG4gIHRoaXMubWFqb3IgPSArbVsxXTtcbiAgdGhpcy5taW5vciA9ICttWzJdO1xuICB0aGlzLnBhdGNoID0gK21bM107XG5cbiAgaWYgKHRoaXMubWFqb3IgPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMubWFqb3IgPCAwKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbWFqb3IgdmVyc2lvbicpXG5cbiAgaWYgKHRoaXMubWlub3IgPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMubWlub3IgPCAwKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbWlub3IgdmVyc2lvbicpXG5cbiAgaWYgKHRoaXMucGF0Y2ggPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMucGF0Y2ggPCAwKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgcGF0Y2ggdmVyc2lvbicpXG5cbiAgLy8gbnVtYmVyaWZ5IGFueSBwcmVyZWxlYXNlIG51bWVyaWMgaWRzXG4gIGlmICghbVs0XSlcbiAgICB0aGlzLnByZXJlbGVhc2UgPSBbXTtcbiAgZWxzZVxuICAgIHRoaXMucHJlcmVsZWFzZSA9IG1bNF0uc3BsaXQoJy4nKS5tYXAoZnVuY3Rpb24oaWQpIHtcbiAgICAgIGlmICgvXlswLTldKyQvLnRlc3QoaWQpKSB7XG4gICAgICAgIHZhciBudW0gPSAraWRcbiAgICAgICAgaWYgKG51bSA+PSAwICYmIG51bSA8IE1BWF9TQUZFX0lOVEVHRVIpXG4gICAgICAgICAgcmV0dXJuIG51bVxuICAgICAgfVxuICAgICAgcmV0dXJuIGlkO1xuICAgIH0pO1xuXG4gIHRoaXMuYnVpbGQgPSBtWzVdID8gbVs1XS5zcGxpdCgnLicpIDogW107XG4gIHRoaXMuZm9ybWF0KCk7XG59XG5cblNlbVZlci5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMudmVyc2lvbiA9IHRoaXMubWFqb3IgKyAnLicgKyB0aGlzLm1pbm9yICsgJy4nICsgdGhpcy5wYXRjaDtcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGgpXG4gICAgdGhpcy52ZXJzaW9uICs9ICctJyArIHRoaXMucHJlcmVsZWFzZS5qb2luKCcuJyk7XG4gIHJldHVybiB0aGlzLnZlcnNpb247XG59O1xuXG5TZW1WZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnZlcnNpb247XG59O1xuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbihvdGhlcikge1xuICBkZWJ1ZygnU2VtVmVyLmNvbXBhcmUnLCB0aGlzLnZlcnNpb24sIHRoaXMubG9vc2UsIG90aGVyKTtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKVxuICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5sb29zZSk7XG5cbiAgcmV0dXJuIHRoaXMuY29tcGFyZU1haW4ob3RoZXIpIHx8IHRoaXMuY29tcGFyZVByZShvdGhlcik7XG59O1xuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmVNYWluID0gZnVuY3Rpb24ob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKVxuICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5sb29zZSk7XG5cbiAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1ham9yLCBvdGhlci5tYWpvcikgfHxcbiAgICAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1pbm9yLCBvdGhlci5taW5vcikgfHxcbiAgICAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLnBhdGNoLCBvdGhlci5wYXRjaCk7XG59O1xuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmVQcmUgPSBmdW5jdGlvbihvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpXG4gICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLmxvb3NlKTtcblxuICAvLyBOT1QgaGF2aW5nIGEgcHJlcmVsZWFzZSBpcyA+IGhhdmluZyBvbmVcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKVxuICAgIHJldHVybiAtMTtcbiAgZWxzZSBpZiAoIXRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpXG4gICAgcmV0dXJuIDE7XG4gIGVsc2UgaWYgKCF0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmICFvdGhlci5wcmVyZWxlYXNlLmxlbmd0aClcbiAgICByZXR1cm4gMDtcblxuICB2YXIgaSA9IDA7XG4gIGRvIHtcbiAgICB2YXIgYSA9IHRoaXMucHJlcmVsZWFzZVtpXTtcbiAgICB2YXIgYiA9IG90aGVyLnByZXJlbGVhc2VbaV07XG4gICAgZGVidWcoJ3ByZXJlbGVhc2UgY29tcGFyZScsIGksIGEsIGIpO1xuICAgIGlmIChhID09PSB1bmRlZmluZWQgJiYgYiA9PT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIDA7XG4gICAgZWxzZSBpZiAoYiA9PT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIDE7XG4gICAgZWxzZSBpZiAoYSA9PT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIC0xO1xuICAgIGVsc2UgaWYgKGEgPT09IGIpXG4gICAgICBjb250aW51ZTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKGEsIGIpO1xuICB9IHdoaWxlICgrK2kpO1xufTtcblxuLy8gcHJlbWlub3Igd2lsbCBidW1wIHRoZSB2ZXJzaW9uIHVwIHRvIHRoZSBuZXh0IG1pbm9yIHJlbGVhc2UsIGFuZCBpbW1lZGlhdGVseVxuLy8gZG93biB0byBwcmUtcmVsZWFzZS4gcHJlbWFqb3IgYW5kIHByZXBhdGNoIHdvcmsgdGhlIHNhbWUgd2F5LlxuU2VtVmVyLnByb3RvdHlwZS5pbmMgPSBmdW5jdGlvbihyZWxlYXNlLCBpZGVudGlmaWVyKSB7XG4gIHN3aXRjaCAocmVsZWFzZSkge1xuICAgIGNhc2UgJ3ByZW1ham9yJzpcbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwO1xuICAgICAgdGhpcy5wYXRjaCA9IDA7XG4gICAgICB0aGlzLm1pbm9yID0gMDtcbiAgICAgIHRoaXMubWFqb3IrKztcbiAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3ByZW1pbm9yJzpcbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwO1xuICAgICAgdGhpcy5wYXRjaCA9IDA7XG4gICAgICB0aGlzLm1pbm9yKys7XG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcik7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwcmVwYXRjaCc6XG4gICAgICAvLyBJZiB0aGlzIGlzIGFscmVhZHkgYSBwcmVyZWxlYXNlLCBpdCB3aWxsIGJ1bXAgdG8gdGhlIG5leHQgdmVyc2lvblxuICAgICAgLy8gZHJvcCBhbnkgcHJlcmVsZWFzZXMgdGhhdCBtaWdodCBhbHJlYWR5IGV4aXN0LCBzaW5jZSB0aGV5IGFyZSBub3RcbiAgICAgIC8vIHJlbGV2YW50IGF0IHRoaXMgcG9pbnQuXG4gICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMuaW5jKCdwYXRjaCcsIGlkZW50aWZpZXIpO1xuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gSWYgdGhlIGlucHV0IGlzIGEgbm9uLXByZXJlbGVhc2UgdmVyc2lvbiwgdGhpcyBhY3RzIHRoZSBzYW1lIGFzXG4gICAgLy8gcHJlcGF0Y2guXG4gICAgY2FzZSAncHJlcmVsZWFzZSc6XG4gICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMClcbiAgICAgICAgdGhpcy5pbmMoJ3BhdGNoJywgaWRlbnRpZmllcik7XG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcik7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ21ham9yJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWFqb3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtYWpvciB2ZXJzaW9uLlxuICAgICAgLy8gT3RoZXJ3aXNlIGluY3JlbWVudCBtYWpvci5cbiAgICAgIC8vIDEuMC4wLTUgYnVtcHMgdG8gMS4wLjBcbiAgICAgIC8vIDEuMS4wIGJ1bXBzIHRvIDIuMC4wXG4gICAgICBpZiAodGhpcy5taW5vciAhPT0gMCB8fCB0aGlzLnBhdGNoICE9PSAwIHx8IHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApXG4gICAgICAgIHRoaXMubWFqb3IrKztcbiAgICAgIHRoaXMubWlub3IgPSAwO1xuICAgICAgdGhpcy5wYXRjaCA9IDA7XG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ21pbm9yJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWlub3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtaW5vciB2ZXJzaW9uLlxuICAgICAgLy8gT3RoZXJ3aXNlIGluY3JlbWVudCBtaW5vci5cbiAgICAgIC8vIDEuMi4wLTUgYnVtcHMgdG8gMS4yLjBcbiAgICAgIC8vIDEuMi4xIGJ1bXBzIHRvIDEuMy4wXG4gICAgICBpZiAodGhpcy5wYXRjaCAhPT0gMCB8fCB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKVxuICAgICAgICB0aGlzLm1pbm9yKys7XG4gICAgICB0aGlzLnBhdGNoID0gMDtcbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAncGF0Y2gnOlxuICAgICAgLy8gSWYgdGhpcyBpcyBub3QgYSBwcmUtcmVsZWFzZSB2ZXJzaW9uLCBpdCB3aWxsIGluY3JlbWVudCB0aGUgcGF0Y2guXG4gICAgICAvLyBJZiBpdCBpcyBhIHByZS1yZWxlYXNlIGl0IHdpbGwgYnVtcCB1cCB0byB0aGUgc2FtZSBwYXRjaCB2ZXJzaW9uLlxuICAgICAgLy8gMS4yLjAtNSBwYXRjaGVzIHRvIDEuMi4wXG4gICAgICAvLyAxLjIuMCBwYXRjaGVzIHRvIDEuMi4xXG4gICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMClcbiAgICAgICAgdGhpcy5wYXRjaCsrO1xuICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW107XG4gICAgICBicmVhaztcbiAgICAvLyBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSB1c2VkIHB1YmxpY2x5LlxuICAgIC8vIDEuMC4wIFwicHJlXCIgd291bGQgYmVjb21lIDEuMC4wLTAgd2hpY2ggaXMgdGhlIHdyb25nIGRpcmVjdGlvbi5cbiAgICBjYXNlICdwcmUnOlxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApXG4gICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFswXTtcbiAgICAgIGVsc2Uge1xuICAgICAgICB2YXIgaSA9IHRoaXMucHJlcmVsZWFzZS5sZW5ndGg7XG4gICAgICAgIHdoaWxlICgtLWkgPj0gMCkge1xuICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcmVyZWxlYXNlW2ldID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlW2ldKys7XG4gICAgICAgICAgICBpID0gLTI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSAtMSkgLy8gZGlkbid0IGluY3JlbWVudCBhbnl0aGluZ1xuICAgICAgICAgIHRoaXMucHJlcmVsZWFzZS5wdXNoKDApO1xuICAgICAgfVxuICAgICAgaWYgKGlkZW50aWZpZXIpIHtcbiAgICAgICAgLy8gMS4yLjAtYmV0YS4xIGJ1bXBzIHRvIDEuMi4wLWJldGEuMixcbiAgICAgICAgLy8gMS4yLjAtYmV0YS5mb29ibHogb3IgMS4yLjAtYmV0YSBidW1wcyB0byAxLjIuMC1iZXRhLjBcbiAgICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZVswXSA9PT0gaWRlbnRpZmllcikge1xuICAgICAgICAgIGlmIChpc05hTih0aGlzLnByZXJlbGVhc2VbMV0pKVxuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW2lkZW50aWZpZXIsIDBdO1xuICAgICAgICB9IGVsc2VcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbaWRlbnRpZmllciwgMF07XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5jcmVtZW50IGFyZ3VtZW50OiAnICsgcmVsZWFzZSk7XG4gIH1cbiAgdGhpcy5mb3JtYXQoKTtcbiAgdGhpcy5yYXcgPSB0aGlzLnZlcnNpb247XG4gIHJldHVybiB0aGlzO1xufTtcblxuZXhwb3J0cy5pbmMgPSBpbmM7XG5mdW5jdGlvbiBpbmModmVyc2lvbiwgcmVsZWFzZSwgbG9vc2UsIGlkZW50aWZpZXIpIHtcbiAgaWYgKHR5cGVvZihsb29zZSkgPT09ICdzdHJpbmcnKSB7XG4gICAgaWRlbnRpZmllciA9IGxvb3NlO1xuICAgIGxvb3NlID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gbmV3IFNlbVZlcih2ZXJzaW9uLCBsb29zZSkuaW5jKHJlbGVhc2UsIGlkZW50aWZpZXIpLnZlcnNpb247XG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZXhwb3J0cy5kaWZmID0gZGlmZjtcbmZ1bmN0aW9uIGRpZmYodmVyc2lvbjEsIHZlcnNpb24yKSB7XG4gIGlmIChlcSh2ZXJzaW9uMSwgdmVyc2lvbjIpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHYxID0gcGFyc2UodmVyc2lvbjEpO1xuICAgIHZhciB2MiA9IHBhcnNlKHZlcnNpb24yKTtcbiAgICBpZiAodjEucHJlcmVsZWFzZS5sZW5ndGggfHwgdjIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiB2MSkge1xuICAgICAgICBpZiAoa2V5ID09PSAnbWFqb3InIHx8IGtleSA9PT0gJ21pbm9yJyB8fCBrZXkgPT09ICdwYXRjaCcpIHtcbiAgICAgICAgICBpZiAodjFba2V5XSAhPT0gdjJba2V5XSkge1xuICAgICAgICAgICAgcmV0dXJuICdwcmUnK2tleTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAncHJlcmVsZWFzZSc7XG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiB2MSkge1xuICAgICAgaWYgKGtleSA9PT0gJ21ham9yJyB8fCBrZXkgPT09ICdtaW5vcicgfHwga2V5ID09PSAncGF0Y2gnKSB7XG4gICAgICAgIGlmICh2MVtrZXldICE9PSB2MltrZXldKSB7XG4gICAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnRzLmNvbXBhcmVJZGVudGlmaWVycyA9IGNvbXBhcmVJZGVudGlmaWVycztcblxudmFyIG51bWVyaWMgPSAvXlswLTldKyQvO1xuZnVuY3Rpb24gY29tcGFyZUlkZW50aWZpZXJzKGEsIGIpIHtcbiAgdmFyIGFudW0gPSBudW1lcmljLnRlc3QoYSk7XG4gIHZhciBibnVtID0gbnVtZXJpYy50ZXN0KGIpO1xuXG4gIGlmIChhbnVtICYmIGJudW0pIHtcbiAgICBhID0gK2E7XG4gICAgYiA9ICtiO1xuICB9XG5cbiAgcmV0dXJuIChhbnVtICYmICFibnVtKSA/IC0xIDpcbiAgICAgICAgIChibnVtICYmICFhbnVtKSA/IDEgOlxuICAgICAgICAgYSA8IGIgPyAtMSA6XG4gICAgICAgICBhID4gYiA/IDEgOlxuICAgICAgICAgMDtcbn1cblxuZXhwb3J0cy5yY29tcGFyZUlkZW50aWZpZXJzID0gcmNvbXBhcmVJZGVudGlmaWVycztcbmZ1bmN0aW9uIHJjb21wYXJlSWRlbnRpZmllcnMoYSwgYikge1xuICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKGIsIGEpO1xufVxuXG5leHBvcnRzLm1ham9yID0gbWFqb3I7XG5mdW5jdGlvbiBtYWpvcihhLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkubWFqb3I7XG59XG5cbmV4cG9ydHMubWlub3IgPSBtaW5vcjtcbmZ1bmN0aW9uIG1pbm9yKGEsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5taW5vcjtcbn1cblxuZXhwb3J0cy5wYXRjaCA9IHBhdGNoO1xuZnVuY3Rpb24gcGF0Y2goYSwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLnBhdGNoO1xufVxuXG5leHBvcnRzLmNvbXBhcmUgPSBjb21wYXJlO1xuZnVuY3Rpb24gY29tcGFyZShhLCBiLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkuY29tcGFyZShiKTtcbn1cblxuZXhwb3J0cy5jb21wYXJlTG9vc2UgPSBjb21wYXJlTG9vc2U7XG5mdW5jdGlvbiBjb21wYXJlTG9vc2UoYSwgYikge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCB0cnVlKTtcbn1cblxuZXhwb3J0cy5yY29tcGFyZSA9IHJjb21wYXJlO1xuZnVuY3Rpb24gcmNvbXBhcmUoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYiwgYSwgbG9vc2UpO1xufVxuXG5leHBvcnRzLnNvcnQgPSBzb3J0O1xuZnVuY3Rpb24gc29ydChsaXN0LCBsb29zZSkge1xuICByZXR1cm4gbGlzdC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5jb21wYXJlKGEsIGIsIGxvb3NlKTtcbiAgfSk7XG59XG5cbmV4cG9ydHMucnNvcnQgPSByc29ydDtcbmZ1bmN0aW9uIHJzb3J0KGxpc3QsIGxvb3NlKSB7XG4gIHJldHVybiBsaXN0LnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgIHJldHVybiBleHBvcnRzLnJjb21wYXJlKGEsIGIsIGxvb3NlKTtcbiAgfSk7XG59XG5cbmV4cG9ydHMuZ3QgPSBndDtcbmZ1bmN0aW9uIGd0KGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA+IDA7XG59XG5cbmV4cG9ydHMubHQgPSBsdDtcbmZ1bmN0aW9uIGx0KGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA8IDA7XG59XG5cbmV4cG9ydHMuZXEgPSBlcTtcbmZ1bmN0aW9uIGVxKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA9PT0gMDtcbn1cblxuZXhwb3J0cy5uZXEgPSBuZXE7XG5mdW5jdGlvbiBuZXEoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpICE9PSAwO1xufVxuXG5leHBvcnRzLmd0ZSA9IGd0ZTtcbmZ1bmN0aW9uIGd0ZShhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPj0gMDtcbn1cblxuZXhwb3J0cy5sdGUgPSBsdGU7XG5mdW5jdGlvbiBsdGUoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpIDw9IDA7XG59XG5cbmV4cG9ydHMuY21wID0gY21wO1xuZnVuY3Rpb24gY21wKGEsIG9wLCBiLCBsb29zZSkge1xuICB2YXIgcmV0O1xuICBzd2l0Y2ggKG9wKSB7XG4gICAgY2FzZSAnPT09JzpcbiAgICAgIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpIGEgPSBhLnZlcnNpb247XG4gICAgICBpZiAodHlwZW9mIGIgPT09ICdvYmplY3QnKSBiID0gYi52ZXJzaW9uO1xuICAgICAgcmV0ID0gYSA9PT0gYjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJyE9PSc6XG4gICAgICBpZiAodHlwZW9mIGEgPT09ICdvYmplY3QnKSBhID0gYS52ZXJzaW9uO1xuICAgICAgaWYgKHR5cGVvZiBiID09PSAnb2JqZWN0JykgYiA9IGIudmVyc2lvbjtcbiAgICAgIHJldCA9IGEgIT09IGI7XG4gICAgICBicmVhaztcbiAgICBjYXNlICcnOiBjYXNlICc9JzogY2FzZSAnPT0nOiByZXQgPSBlcShhLCBiLCBsb29zZSk7IGJyZWFrO1xuICAgIGNhc2UgJyE9JzogcmV0ID0gbmVxKGEsIGIsIGxvb3NlKTsgYnJlYWs7XG4gICAgY2FzZSAnPic6IHJldCA9IGd0KGEsIGIsIGxvb3NlKTsgYnJlYWs7XG4gICAgY2FzZSAnPj0nOiByZXQgPSBndGUoYSwgYiwgbG9vc2UpOyBicmVhaztcbiAgICBjYXNlICc8JzogcmV0ID0gbHQoYSwgYiwgbG9vc2UpOyBicmVhaztcbiAgICBjYXNlICc8PSc6IHJldCA9IGx0ZShhLCBiLCBsb29zZSk7IGJyZWFrO1xuICAgIGRlZmF1bHQ6IHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgb3BlcmF0b3I6ICcgKyBvcCk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0cy5Db21wYXJhdG9yID0gQ29tcGFyYXRvcjtcbmZ1bmN0aW9uIENvbXBhcmF0b3IoY29tcCwgbG9vc2UpIHtcbiAgaWYgKGNvbXAgaW5zdGFuY2VvZiBDb21wYXJhdG9yKSB7XG4gICAgaWYgKGNvbXAubG9vc2UgPT09IGxvb3NlKVxuICAgICAgcmV0dXJuIGNvbXA7XG4gICAgZWxzZVxuICAgICAgY29tcCA9IGNvbXAudmFsdWU7XG4gIH1cblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ29tcGFyYXRvcikpXG4gICAgcmV0dXJuIG5ldyBDb21wYXJhdG9yKGNvbXAsIGxvb3NlKTtcblxuICBkZWJ1ZygnY29tcGFyYXRvcicsIGNvbXAsIGxvb3NlKTtcbiAgdGhpcy5sb29zZSA9IGxvb3NlO1xuICB0aGlzLnBhcnNlKGNvbXApO1xuXG4gIGlmICh0aGlzLnNlbXZlciA9PT0gQU5ZKVxuICAgIHRoaXMudmFsdWUgPSAnJztcbiAgZWxzZVxuICAgIHRoaXMudmFsdWUgPSB0aGlzLm9wZXJhdG9yICsgdGhpcy5zZW12ZXIudmVyc2lvbjtcblxuICBkZWJ1ZygnY29tcCcsIHRoaXMpO1xufVxuXG52YXIgQU5ZID0ge307XG5Db21wYXJhdG9yLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKGNvbXApIHtcbiAgdmFyIHIgPSB0aGlzLmxvb3NlID8gcmVbQ09NUEFSQVRPUkxPT1NFXSA6IHJlW0NPTVBBUkFUT1JdO1xuICB2YXIgbSA9IGNvbXAubWF0Y2gocik7XG5cbiAgaWYgKCFtKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgY29tcGFyYXRvcjogJyArIGNvbXApO1xuXG4gIHRoaXMub3BlcmF0b3IgPSBtWzFdO1xuICBpZiAodGhpcy5vcGVyYXRvciA9PT0gJz0nKVxuICAgIHRoaXMub3BlcmF0b3IgPSAnJztcblxuICAvLyBpZiBpdCBsaXRlcmFsbHkgaXMganVzdCAnPicgb3IgJycgdGhlbiBhbGxvdyBhbnl0aGluZy5cbiAgaWYgKCFtWzJdKVxuICAgIHRoaXMuc2VtdmVyID0gQU5ZO1xuICBlbHNlXG4gICAgdGhpcy5zZW12ZXIgPSBuZXcgU2VtVmVyKG1bMl0sIHRoaXMubG9vc2UpO1xufTtcblxuQ29tcGFyYXRvci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMudmFsdWU7XG59O1xuXG5Db21wYXJhdG9yLnByb3RvdHlwZS50ZXN0ID0gZnVuY3Rpb24odmVyc2lvbikge1xuICBkZWJ1ZygnQ29tcGFyYXRvci50ZXN0JywgdmVyc2lvbiwgdGhpcy5sb29zZSk7XG5cbiAgaWYgKHRoaXMuc2VtdmVyID09PSBBTlkpXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uID09PSAnc3RyaW5nJylcbiAgICB2ZXJzaW9uID0gbmV3IFNlbVZlcih2ZXJzaW9uLCB0aGlzLmxvb3NlKTtcblxuICByZXR1cm4gY21wKHZlcnNpb24sIHRoaXMub3BlcmF0b3IsIHRoaXMuc2VtdmVyLCB0aGlzLmxvb3NlKTtcbn07XG5cblxuZXhwb3J0cy5SYW5nZSA9IFJhbmdlO1xuZnVuY3Rpb24gUmFuZ2UocmFuZ2UsIGxvb3NlKSB7XG4gIGlmICgocmFuZ2UgaW5zdGFuY2VvZiBSYW5nZSkgJiYgcmFuZ2UubG9vc2UgPT09IGxvb3NlKVxuICAgIHJldHVybiByYW5nZTtcblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmFuZ2UpKVxuICAgIHJldHVybiBuZXcgUmFuZ2UocmFuZ2UsIGxvb3NlKTtcblxuICB0aGlzLmxvb3NlID0gbG9vc2U7XG5cbiAgLy8gRmlyc3QsIHNwbGl0IGJhc2VkIG9uIGJvb2xlYW4gb3IgfHxcbiAgdGhpcy5yYXcgPSByYW5nZTtcbiAgdGhpcy5zZXQgPSByYW5nZS5zcGxpdCgvXFxzKlxcfFxcfFxccyovKS5tYXAoZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICByZXR1cm4gdGhpcy5wYXJzZVJhbmdlKHJhbmdlLnRyaW0oKSk7XG4gIH0sIHRoaXMpLmZpbHRlcihmdW5jdGlvbihjKSB7XG4gICAgLy8gdGhyb3cgb3V0IGFueSB0aGF0IGFyZSBub3QgcmVsZXZhbnQgZm9yIHdoYXRldmVyIHJlYXNvblxuICAgIHJldHVybiBjLmxlbmd0aDtcbiAgfSk7XG5cbiAgaWYgKCF0aGlzLnNldC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIFNlbVZlciBSYW5nZTogJyArIHJhbmdlKTtcbiAgfVxuXG4gIHRoaXMuZm9ybWF0KCk7XG59XG5cblJhbmdlLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5yYW5nZSA9IHRoaXMuc2V0Lm1hcChmdW5jdGlvbihjb21wcykge1xuICAgIHJldHVybiBjb21wcy5qb2luKCcgJykudHJpbSgpO1xuICB9KS5qb2luKCd8fCcpLnRyaW0oKTtcbiAgcmV0dXJuIHRoaXMucmFuZ2U7XG59O1xuXG5SYW5nZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMucmFuZ2U7XG59O1xuXG5SYW5nZS5wcm90b3R5cGUucGFyc2VSYW5nZSA9IGZ1bmN0aW9uKHJhbmdlKSB7XG4gIHZhciBsb29zZSA9IHRoaXMubG9vc2U7XG4gIHJhbmdlID0gcmFuZ2UudHJpbSgpO1xuICBkZWJ1ZygncmFuZ2UnLCByYW5nZSwgbG9vc2UpO1xuICAvLyBgMS4yLjMgLSAxLjIuNGAgPT4gYD49MS4yLjMgPD0xLjIuNGBcbiAgdmFyIGhyID0gbG9vc2UgPyByZVtIWVBIRU5SQU5HRUxPT1NFXSA6IHJlW0hZUEhFTlJBTkdFXTtcbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKGhyLCBoeXBoZW5SZXBsYWNlKTtcbiAgZGVidWcoJ2h5cGhlbiByZXBsYWNlJywgcmFuZ2UpO1xuICAvLyBgPiAxLjIuMyA8IDEuMi41YCA9PiBgPjEuMi4zIDwxLjIuNWBcbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKHJlW0NPTVBBUkFUT1JUUklNXSwgY29tcGFyYXRvclRyaW1SZXBsYWNlKTtcbiAgZGVidWcoJ2NvbXBhcmF0b3IgdHJpbScsIHJhbmdlLCByZVtDT01QQVJBVE9SVFJJTV0pO1xuXG4gIC8vIGB+IDEuMi4zYCA9PiBgfjEuMi4zYFxuICByYW5nZSA9IHJhbmdlLnJlcGxhY2UocmVbVElMREVUUklNXSwgdGlsZGVUcmltUmVwbGFjZSk7XG5cbiAgLy8gYF4gMS4yLjNgID0+IGBeMS4yLjNgXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShyZVtDQVJFVFRSSU1dLCBjYXJldFRyaW1SZXBsYWNlKTtcblxuICAvLyBub3JtYWxpemUgc3BhY2VzXG4gIHJhbmdlID0gcmFuZ2Uuc3BsaXQoL1xccysvKS5qb2luKCcgJyk7XG5cbiAgLy8gQXQgdGhpcyBwb2ludCwgdGhlIHJhbmdlIGlzIGNvbXBsZXRlbHkgdHJpbW1lZCBhbmRcbiAgLy8gcmVhZHkgdG8gYmUgc3BsaXQgaW50byBjb21wYXJhdG9ycy5cblxuICB2YXIgY29tcFJlID0gbG9vc2UgPyByZVtDT01QQVJBVE9STE9PU0VdIDogcmVbQ09NUEFSQVRPUl07XG4gIHZhciBzZXQgPSByYW5nZS5zcGxpdCgnICcpLm1hcChmdW5jdGlvbihjb21wKSB7XG4gICAgcmV0dXJuIHBhcnNlQ29tcGFyYXRvcihjb21wLCBsb29zZSk7XG4gIH0pLmpvaW4oJyAnKS5zcGxpdCgvXFxzKy8pO1xuICBpZiAodGhpcy5sb29zZSkge1xuICAgIC8vIGluIGxvb3NlIG1vZGUsIHRocm93IG91dCBhbnkgdGhhdCBhcmUgbm90IHZhbGlkIGNvbXBhcmF0b3JzXG4gICAgc2V0ID0gc2V0LmZpbHRlcihmdW5jdGlvbihjb21wKSB7XG4gICAgICByZXR1cm4gISFjb21wLm1hdGNoKGNvbXBSZSk7XG4gICAgfSk7XG4gIH1cbiAgc2V0ID0gc2V0Lm1hcChmdW5jdGlvbihjb21wKSB7XG4gICAgcmV0dXJuIG5ldyBDb21wYXJhdG9yKGNvbXAsIGxvb3NlKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHNldDtcbn07XG5cbi8vIE1vc3RseSBqdXN0IGZvciB0ZXN0aW5nIGFuZCBsZWdhY3kgQVBJIHJlYXNvbnNcbmV4cG9ydHMudG9Db21wYXJhdG9ycyA9IHRvQ29tcGFyYXRvcnM7XG5mdW5jdGlvbiB0b0NvbXBhcmF0b3JzKHJhbmdlLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSkuc2V0Lm1hcChmdW5jdGlvbihjb21wKSB7XG4gICAgcmV0dXJuIGNvbXAubWFwKGZ1bmN0aW9uKGMpIHtcbiAgICAgIHJldHVybiBjLnZhbHVlO1xuICAgIH0pLmpvaW4oJyAnKS50cmltKCkuc3BsaXQoJyAnKTtcbiAgfSk7XG59XG5cbi8vIGNvbXByaXNlZCBvZiB4cmFuZ2VzLCB0aWxkZXMsIHN0YXJzLCBhbmQgZ3RsdCdzIGF0IHRoaXMgcG9pbnQuXG4vLyBhbHJlYWR5IHJlcGxhY2VkIHRoZSBoeXBoZW4gcmFuZ2VzXG4vLyB0dXJuIGludG8gYSBzZXQgb2YgSlVTVCBjb21wYXJhdG9ycy5cbmZ1bmN0aW9uIHBhcnNlQ29tcGFyYXRvcihjb21wLCBsb29zZSkge1xuICBkZWJ1ZygnY29tcCcsIGNvbXApO1xuICBjb21wID0gcmVwbGFjZUNhcmV0cyhjb21wLCBsb29zZSk7XG4gIGRlYnVnKCdjYXJldCcsIGNvbXApO1xuICBjb21wID0gcmVwbGFjZVRpbGRlcyhjb21wLCBsb29zZSk7XG4gIGRlYnVnKCd0aWxkZXMnLCBjb21wKTtcbiAgY29tcCA9IHJlcGxhY2VYUmFuZ2VzKGNvbXAsIGxvb3NlKTtcbiAgZGVidWcoJ3hyYW5nZScsIGNvbXApO1xuICBjb21wID0gcmVwbGFjZVN0YXJzKGNvbXAsIGxvb3NlKTtcbiAgZGVidWcoJ3N0YXJzJywgY29tcCk7XG4gIHJldHVybiBjb21wO1xufVxuXG5mdW5jdGlvbiBpc1goaWQpIHtcbiAgcmV0dXJuICFpZCB8fCBpZC50b0xvd2VyQ2FzZSgpID09PSAneCcgfHwgaWQgPT09ICcqJztcbn1cblxuLy8gfiwgfj4gLS0+ICogKGFueSwga2luZGEgc2lsbHkpXG4vLyB+MiwgfjIueCwgfjIueC54LCB+PjIsIH4+Mi54IH4+Mi54LnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyB+Mi4wLCB+Mi4wLngsIH4+Mi4wLCB+PjIuMC54IC0tPiA+PTIuMC4wIDwyLjEuMFxuLy8gfjEuMiwgfjEuMi54LCB+PjEuMiwgfj4xLjIueCAtLT4gPj0xLjIuMCA8MS4zLjBcbi8vIH4xLjIuMywgfj4xLjIuMyAtLT4gPj0xLjIuMyA8MS4zLjBcbi8vIH4xLjIuMCwgfj4xLjIuMCAtLT4gPj0xLjIuMCA8MS4zLjBcbmZ1bmN0aW9uIHJlcGxhY2VUaWxkZXMoY29tcCwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXAudHJpbSgpLnNwbGl0KC9cXHMrLykubWFwKGZ1bmN0aW9uKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZVRpbGRlKGNvbXAsIGxvb3NlKTtcbiAgfSkuam9pbignICcpO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlVGlsZGUoY29tcCwgbG9vc2UpIHtcbiAgdmFyIHIgPSBsb29zZSA/IHJlW1RJTERFTE9PU0VdIDogcmVbVElMREVdO1xuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uKF8sIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ3RpbGRlJywgY29tcCwgXywgTSwgbSwgcCwgcHIpO1xuICAgIHZhciByZXQ7XG5cbiAgICBpZiAoaXNYKE0pKVxuICAgICAgcmV0ID0gJyc7XG4gICAgZWxzZSBpZiAoaXNYKG0pKVxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnO1xuICAgIGVsc2UgaWYgKGlzWChwKSlcbiAgICAgIC8vIH4xLjIgPT0gPj0xLjIuMC0gPDEuMy4wLVxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJztcbiAgICBlbHNlIGlmIChwcikge1xuICAgICAgZGVidWcoJ3JlcGxhY2VUaWxkZSBwcicsIHByKTtcbiAgICAgIGlmIChwci5jaGFyQXQoMCkgIT09ICctJylcbiAgICAgICAgcHIgPSAnLScgKyBwcjtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgKyBwciArXG4gICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJztcbiAgICB9IGVsc2VcbiAgICAgIC8vIH4xLjIuMyA9PSA+PTEuMi4zIDwxLjMuMFxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJztcblxuICAgIGRlYnVnKCd0aWxkZSByZXR1cm4nLCByZXQpO1xuICAgIHJldHVybiByZXQ7XG4gIH0pO1xufVxuXG4vLyBeIC0tPiAqIChhbnksIGtpbmRhIHNpbGx5KVxuLy8gXjIsIF4yLngsIF4yLngueCAtLT4gPj0yLjAuMCA8My4wLjBcbi8vIF4yLjAsIF4yLjAueCAtLT4gPj0yLjAuMCA8My4wLjBcbi8vIF4xLjIsIF4xLjIueCAtLT4gPj0xLjIuMCA8Mi4wLjBcbi8vIF4xLjIuMyAtLT4gPj0xLjIuMyA8Mi4wLjBcbi8vIF4xLjIuMCAtLT4gPj0xLjIuMCA8Mi4wLjBcbmZ1bmN0aW9uIHJlcGxhY2VDYXJldHMoY29tcCwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXAudHJpbSgpLnNwbGl0KC9cXHMrLykubWFwKGZ1bmN0aW9uKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZUNhcmV0KGNvbXAsIGxvb3NlKTtcbiAgfSkuam9pbignICcpO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlQ2FyZXQoY29tcCwgbG9vc2UpIHtcbiAgZGVidWcoJ2NhcmV0JywgY29tcCwgbG9vc2UpO1xuICB2YXIgciA9IGxvb3NlID8gcmVbQ0FSRVRMT09TRV0gOiByZVtDQVJFVF07XG4gIHJldHVybiBjb21wLnJlcGxhY2UociwgZnVuY3Rpb24oXywgTSwgbSwgcCwgcHIpIHtcbiAgICBkZWJ1ZygnY2FyZXQnLCBjb21wLCBfLCBNLCBtLCBwLCBwcik7XG4gICAgdmFyIHJldDtcblxuICAgIGlmIChpc1goTSkpXG4gICAgICByZXQgPSAnJztcbiAgICBlbHNlIGlmIChpc1gobSkpXG4gICAgICByZXQgPSAnPj0nICsgTSArICcuMC4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCc7XG4gICAgZWxzZSBpZiAoaXNYKHApKSB7XG4gICAgICBpZiAoTSA9PT0gJzAnKVxuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLjAgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnO1xuICAgICAgZWxzZVxuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLjAgPCcgKyAoK00gKyAxKSArICcuMC4wJztcbiAgICB9IGVsc2UgaWYgKHByKSB7XG4gICAgICBkZWJ1ZygncmVwbGFjZUNhcmV0IHByJywgcHIpO1xuICAgICAgaWYgKHByLmNoYXJBdCgwKSAhPT0gJy0nKVxuICAgICAgICBwciA9ICctJyArIHByO1xuICAgICAgaWYgKE0gPT09ICcwJykge1xuICAgICAgICBpZiAobSA9PT0gJzAnKVxuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgKyBwciArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyBtICsgJy4nICsgKCtwICsgMSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgcHIgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgKCttICsgMSkgKyAnLjAnO1xuICAgICAgfSBlbHNlXG4gICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgKyBwciArXG4gICAgICAgICAgICAgICcgPCcgKyAoK00gKyAxKSArICcuMC4wJztcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWcoJ25vIHByJyk7XG4gICAgICBpZiAoTSA9PT0gJzAnKSB7XG4gICAgICAgIGlmIChtID09PSAnMCcpXG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyBtICsgJy4nICsgKCtwICsgMSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJztcbiAgICAgIH0gZWxzZVxuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICtcbiAgICAgICAgICAgICAgJyA8JyArICgrTSArIDEpICsgJy4wLjAnO1xuICAgIH1cblxuICAgIGRlYnVnKCdjYXJldCByZXR1cm4nLCByZXQpO1xuICAgIHJldHVybiByZXQ7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlWFJhbmdlcyhjb21wLCBsb29zZSkge1xuICBkZWJ1ZygncmVwbGFjZVhSYW5nZXMnLCBjb21wLCBsb29zZSk7XG4gIHJldHVybiBjb21wLnNwbGl0KC9cXHMrLykubWFwKGZ1bmN0aW9uKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZVhSYW5nZShjb21wLCBsb29zZSk7XG4gIH0pLmpvaW4oJyAnKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZVhSYW5nZShjb21wLCBsb29zZSkge1xuICBjb21wID0gY29tcC50cmltKCk7XG4gIHZhciByID0gbG9vc2UgPyByZVtYUkFOR0VMT09TRV0gOiByZVtYUkFOR0VdO1xuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uKHJldCwgZ3RsdCwgTSwgbSwgcCwgcHIpIHtcbiAgICBkZWJ1ZygneFJhbmdlJywgY29tcCwgcmV0LCBndGx0LCBNLCBtLCBwLCBwcik7XG4gICAgdmFyIHhNID0gaXNYKE0pO1xuICAgIHZhciB4bSA9IHhNIHx8IGlzWChtKTtcbiAgICB2YXIgeHAgPSB4bSB8fCBpc1gocCk7XG4gICAgdmFyIGFueVggPSB4cDtcblxuICAgIGlmIChndGx0ID09PSAnPScgJiYgYW55WClcbiAgICAgIGd0bHQgPSAnJztcblxuICAgIGlmICh4TSkge1xuICAgICAgaWYgKGd0bHQgPT09ICc+JyB8fCBndGx0ID09PSAnPCcpIHtcbiAgICAgICAgLy8gbm90aGluZyBpcyBhbGxvd2VkXG4gICAgICAgIHJldCA9ICc8MC4wLjAnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gbm90aGluZyBpcyBmb3JiaWRkZW5cbiAgICAgICAgcmV0ID0gJyonO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZ3RsdCAmJiBhbnlYKSB7XG4gICAgICAvLyByZXBsYWNlIFggd2l0aCAwXG4gICAgICBpZiAoeG0pXG4gICAgICAgIG0gPSAwO1xuICAgICAgaWYgKHhwKVxuICAgICAgICBwID0gMDtcblxuICAgICAgaWYgKGd0bHQgPT09ICc+Jykge1xuICAgICAgICAvLyA+MSA9PiA+PTIuMC4wXG4gICAgICAgIC8vID4xLjIgPT4gPj0xLjMuMFxuICAgICAgICAvLyA+MS4yLjMgPT4gPj0gMS4yLjRcbiAgICAgICAgZ3RsdCA9ICc+PSc7XG4gICAgICAgIGlmICh4bSkge1xuICAgICAgICAgIE0gPSArTSArIDE7XG4gICAgICAgICAgbSA9IDA7XG4gICAgICAgICAgcCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoeHApIHtcbiAgICAgICAgICBtID0gK20gKyAxO1xuICAgICAgICAgIHAgPSAwO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGd0bHQgPT09ICc8PScpIHtcbiAgICAgICAgLy8gPD0wLjcueCBpcyBhY3R1YWxseSA8MC44LjAsIHNpbmNlIGFueSAwLjcueCBzaG91bGRcbiAgICAgICAgLy8gcGFzcy4gIFNpbWlsYXJseSwgPD03LnggaXMgYWN0dWFsbHkgPDguMC4wLCBldGMuXG4gICAgICAgIGd0bHQgPSAnPCdcbiAgICAgICAgaWYgKHhtKVxuICAgICAgICAgIE0gPSArTSArIDFcbiAgICAgICAgZWxzZVxuICAgICAgICAgIG0gPSArbSArIDFcbiAgICAgIH1cblxuICAgICAgcmV0ID0gZ3RsdCArIE0gKyAnLicgKyBtICsgJy4nICsgcDtcbiAgICB9IGVsc2UgaWYgKHhtKSB7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuMC4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCc7XG4gICAgfSBlbHNlIGlmICh4cCkge1xuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJztcbiAgICB9XG5cbiAgICBkZWJ1ZygneFJhbmdlIHJldHVybicsIHJldCk7XG5cbiAgICByZXR1cm4gcmV0O1xuICB9KTtcbn1cblxuLy8gQmVjYXVzZSAqIGlzIEFORC1lZCB3aXRoIGV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgY29tcGFyYXRvcixcbi8vIGFuZCAnJyBtZWFucyBcImFueSB2ZXJzaW9uXCIsIGp1c3QgcmVtb3ZlIHRoZSAqcyBlbnRpcmVseS5cbmZ1bmN0aW9uIHJlcGxhY2VTdGFycyhjb21wLCBsb29zZSkge1xuICBkZWJ1ZygncmVwbGFjZVN0YXJzJywgY29tcCwgbG9vc2UpO1xuICAvLyBMb29zZW5lc3MgaXMgaWdub3JlZCBoZXJlLiAgc3RhciBpcyBhbHdheXMgYXMgbG9vc2UgYXMgaXQgZ2V0cyFcbiAgcmV0dXJuIGNvbXAudHJpbSgpLnJlcGxhY2UocmVbU1RBUl0sICcnKTtcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyBwYXNzZWQgdG8gc3RyaW5nLnJlcGxhY2UocmVbSFlQSEVOUkFOR0VdKVxuLy8gTSwgbSwgcGF0Y2gsIHByZXJlbGVhc2UsIGJ1aWxkXG4vLyAxLjIgLSAzLjQuNSA9PiA+PTEuMi4wIDw9My40LjVcbi8vIDEuMi4zIC0gMy40ID0+ID49MS4yLjAgPDMuNS4wIEFueSAzLjQueCB3aWxsIGRvXG4vLyAxLjIgLSAzLjQgPT4gPj0xLjIuMCA8My41LjBcbmZ1bmN0aW9uIGh5cGhlblJlcGxhY2UoJDAsXG4gICAgICAgICAgICAgICAgICAgICAgIGZyb20sIGZNLCBmbSwgZnAsIGZwciwgZmIsXG4gICAgICAgICAgICAgICAgICAgICAgIHRvLCB0TSwgdG0sIHRwLCB0cHIsIHRiKSB7XG5cbiAgaWYgKGlzWChmTSkpXG4gICAgZnJvbSA9ICcnO1xuICBlbHNlIGlmIChpc1goZm0pKVxuICAgIGZyb20gPSAnPj0nICsgZk0gKyAnLjAuMCc7XG4gIGVsc2UgaWYgKGlzWChmcCkpXG4gICAgZnJvbSA9ICc+PScgKyBmTSArICcuJyArIGZtICsgJy4wJztcbiAgZWxzZVxuICAgIGZyb20gPSAnPj0nICsgZnJvbTtcblxuICBpZiAoaXNYKHRNKSlcbiAgICB0byA9ICcnO1xuICBlbHNlIGlmIChpc1godG0pKVxuICAgIHRvID0gJzwnICsgKCt0TSArIDEpICsgJy4wLjAnO1xuICBlbHNlIGlmIChpc1godHApKVxuICAgIHRvID0gJzwnICsgdE0gKyAnLicgKyAoK3RtICsgMSkgKyAnLjAnO1xuICBlbHNlIGlmICh0cHIpXG4gICAgdG8gPSAnPD0nICsgdE0gKyAnLicgKyB0bSArICcuJyArIHRwICsgJy0nICsgdHByO1xuICBlbHNlXG4gICAgdG8gPSAnPD0nICsgdG87XG5cbiAgcmV0dXJuIChmcm9tICsgJyAnICsgdG8pLnRyaW0oKTtcbn1cblxuXG4vLyBpZiBBTlkgb2YgdGhlIHNldHMgbWF0Y2ggQUxMIG9mIGl0cyBjb21wYXJhdG9ycywgdGhlbiBwYXNzXG5SYW5nZS5wcm90b3R5cGUudGVzdCA9IGZ1bmN0aW9uKHZlcnNpb24pIHtcbiAgaWYgKCF2ZXJzaW9uKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIHZlcnNpb24gPT09ICdzdHJpbmcnKVxuICAgIHZlcnNpb24gPSBuZXcgU2VtVmVyKHZlcnNpb24sIHRoaXMubG9vc2UpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zZXQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodGVzdFNldCh0aGlzLnNldFtpXSwgdmVyc2lvbikpXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5mdW5jdGlvbiB0ZXN0U2V0KHNldCwgdmVyc2lvbikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKykge1xuICAgIGlmICghc2V0W2ldLnRlc3QodmVyc2lvbikpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAodmVyc2lvbi5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgIC8vIEZpbmQgdGhlIHNldCBvZiB2ZXJzaW9ucyB0aGF0IGFyZSBhbGxvd2VkIHRvIGhhdmUgcHJlcmVsZWFzZXNcbiAgICAvLyBGb3IgZXhhbXBsZSwgXjEuMi4zLXByLjEgZGVzdWdhcnMgdG8gPj0xLjIuMy1wci4xIDwyLjAuMFxuICAgIC8vIFRoYXQgc2hvdWxkIGFsbG93IGAxLjIuMy1wci4yYCB0byBwYXNzLlxuICAgIC8vIEhvd2V2ZXIsIGAxLjIuNC1hbHBoYS5ub3RyZWFkeWAgc2hvdWxkIE5PVCBiZSBhbGxvd2VkLFxuICAgIC8vIGV2ZW4gdGhvdWdoIGl0J3Mgd2l0aGluIHRoZSByYW5nZSBzZXQgYnkgdGhlIGNvbXBhcmF0b3JzLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBkZWJ1ZyhzZXRbaV0uc2VtdmVyKTtcbiAgICAgIGlmIChzZXRbaV0uc2VtdmVyID09PSBBTlkpXG4gICAgICAgIGNvbnRpbnVlO1xuXG4gICAgICBpZiAoc2V0W2ldLnNlbXZlci5wcmVyZWxlYXNlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdmFyIGFsbG93ZWQgPSBzZXRbaV0uc2VtdmVyO1xuICAgICAgICBpZiAoYWxsb3dlZC5tYWpvciA9PT0gdmVyc2lvbi5tYWpvciAmJlxuICAgICAgICAgICAgYWxsb3dlZC5taW5vciA9PT0gdmVyc2lvbi5taW5vciAmJlxuICAgICAgICAgICAgYWxsb3dlZC5wYXRjaCA9PT0gdmVyc2lvbi5wYXRjaClcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBWZXJzaW9uIGhhcyBhIC1wcmUsIGJ1dCBpdCdzIG5vdCBvbmUgb2YgdGhlIG9uZXMgd2UgbGlrZS5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0cy5zYXRpc2ZpZXMgPSBzYXRpc2ZpZXM7XG5mdW5jdGlvbiBzYXRpc2ZpZXModmVyc2lvbiwgcmFuZ2UsIGxvb3NlKSB7XG4gIHRyeSB7XG4gICAgcmFuZ2UgPSBuZXcgUmFuZ2UocmFuZ2UsIGxvb3NlKTtcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHJhbmdlLnRlc3QodmVyc2lvbik7XG59XG5cbmV4cG9ydHMubWF4U2F0aXNmeWluZyA9IG1heFNhdGlzZnlpbmc7XG5mdW5jdGlvbiBtYXhTYXRpc2Z5aW5nKHZlcnNpb25zLCByYW5nZSwgbG9vc2UpIHtcbiAgcmV0dXJuIHZlcnNpb25zLmZpbHRlcihmdW5jdGlvbih2ZXJzaW9uKSB7XG4gICAgcmV0dXJuIHNhdGlzZmllcyh2ZXJzaW9uLCByYW5nZSwgbG9vc2UpO1xuICB9KS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gcmNvbXBhcmUoYSwgYiwgbG9vc2UpO1xuICB9KVswXSB8fCBudWxsO1xufVxuXG5leHBvcnRzLnZhbGlkUmFuZ2UgPSB2YWxpZFJhbmdlO1xuZnVuY3Rpb24gdmFsaWRSYW5nZShyYW5nZSwgbG9vc2UpIHtcbiAgdHJ5IHtcbiAgICAvLyBSZXR1cm4gJyonIGluc3RlYWQgb2YgJycgc28gdGhhdCB0cnV0aGluZXNzIHdvcmtzLlxuICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBpZiBpdCdzIGludmFsaWQgYW55d2F5XG4gICAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZSwgbG9vc2UpLnJhbmdlIHx8ICcqJztcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vLyBEZXRlcm1pbmUgaWYgdmVyc2lvbiBpcyBsZXNzIHRoYW4gYWxsIHRoZSB2ZXJzaW9ucyBwb3NzaWJsZSBpbiB0aGUgcmFuZ2VcbmV4cG9ydHMubHRyID0gbHRyO1xuZnVuY3Rpb24gbHRyKHZlcnNpb24sIHJhbmdlLCBsb29zZSkge1xuICByZXR1cm4gb3V0c2lkZSh2ZXJzaW9uLCByYW5nZSwgJzwnLCBsb29zZSk7XG59XG5cbi8vIERldGVybWluZSBpZiB2ZXJzaW9uIGlzIGdyZWF0ZXIgdGhhbiBhbGwgdGhlIHZlcnNpb25zIHBvc3NpYmxlIGluIHRoZSByYW5nZS5cbmV4cG9ydHMuZ3RyID0gZ3RyO1xuZnVuY3Rpb24gZ3RyKHZlcnNpb24sIHJhbmdlLCBsb29zZSkge1xuICByZXR1cm4gb3V0c2lkZSh2ZXJzaW9uLCByYW5nZSwgJz4nLCBsb29zZSk7XG59XG5cbmV4cG9ydHMub3V0c2lkZSA9IG91dHNpZGU7XG5mdW5jdGlvbiBvdXRzaWRlKHZlcnNpb24sIHJhbmdlLCBoaWxvLCBsb29zZSkge1xuICB2ZXJzaW9uID0gbmV3IFNlbVZlcih2ZXJzaW9uLCBsb29zZSk7XG4gIHJhbmdlID0gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSk7XG5cbiAgdmFyIGd0Zm4sIGx0ZWZuLCBsdGZuLCBjb21wLCBlY29tcDtcbiAgc3dpdGNoIChoaWxvKSB7XG4gICAgY2FzZSAnPic6XG4gICAgICBndGZuID0gZ3Q7XG4gICAgICBsdGVmbiA9IGx0ZTtcbiAgICAgIGx0Zm4gPSBsdDtcbiAgICAgIGNvbXAgPSAnPic7XG4gICAgICBlY29tcCA9ICc+PSc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICc8JzpcbiAgICAgIGd0Zm4gPSBsdDtcbiAgICAgIGx0ZWZuID0gZ3RlO1xuICAgICAgbHRmbiA9IGd0O1xuICAgICAgY29tcCA9ICc8JztcbiAgICAgIGVjb21wID0gJzw9JztcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdNdXN0IHByb3ZpZGUgYSBoaWxvIHZhbCBvZiBcIjxcIiBvciBcIj5cIicpO1xuICB9XG5cbiAgLy8gSWYgaXQgc2F0aXNpZmVzIHRoZSByYW5nZSBpdCBpcyBub3Qgb3V0c2lkZVxuICBpZiAoc2F0aXNmaWVzKHZlcnNpb24sIHJhbmdlLCBsb29zZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBGcm9tIG5vdyBvbiwgdmFyaWFibGUgdGVybXMgYXJlIGFzIGlmIHdlJ3JlIGluIFwiZ3RyXCIgbW9kZS5cbiAgLy8gYnV0IG5vdGUgdGhhdCBldmVyeXRoaW5nIGlzIGZsaXBwZWQgZm9yIHRoZSBcImx0clwiIGZ1bmN0aW9uLlxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2Uuc2V0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGNvbXBhcmF0b3JzID0gcmFuZ2Uuc2V0W2ldO1xuXG4gICAgdmFyIGhpZ2ggPSBudWxsO1xuICAgIHZhciBsb3cgPSBudWxsO1xuXG4gICAgY29tcGFyYXRvcnMuZm9yRWFjaChmdW5jdGlvbihjb21wYXJhdG9yKSB7XG4gICAgICBpZiAoY29tcGFyYXRvci5zZW12ZXIgPT09IEFOWSkge1xuICAgICAgICBjb21wYXJhdG9yID0gbmV3IENvbXBhcmF0b3IoJz49MC4wLjAnKVxuICAgICAgfVxuICAgICAgaGlnaCA9IGhpZ2ggfHwgY29tcGFyYXRvcjtcbiAgICAgIGxvdyA9IGxvdyB8fCBjb21wYXJhdG9yO1xuICAgICAgaWYgKGd0Zm4oY29tcGFyYXRvci5zZW12ZXIsIGhpZ2guc2VtdmVyLCBsb29zZSkpIHtcbiAgICAgICAgaGlnaCA9IGNvbXBhcmF0b3I7XG4gICAgICB9IGVsc2UgaWYgKGx0Zm4oY29tcGFyYXRvci5zZW12ZXIsIGxvdy5zZW12ZXIsIGxvb3NlKSkge1xuICAgICAgICBsb3cgPSBjb21wYXJhdG9yO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gSWYgdGhlIGVkZ2UgdmVyc2lvbiBjb21wYXJhdG9yIGhhcyBhIG9wZXJhdG9yIHRoZW4gb3VyIHZlcnNpb25cbiAgICAvLyBpc24ndCBvdXRzaWRlIGl0XG4gICAgaWYgKGhpZ2gub3BlcmF0b3IgPT09IGNvbXAgfHwgaGlnaC5vcGVyYXRvciA9PT0gZWNvbXApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgbG93ZXN0IHZlcnNpb24gY29tcGFyYXRvciBoYXMgYW4gb3BlcmF0b3IgYW5kIG91ciB2ZXJzaW9uXG4gICAgLy8gaXMgbGVzcyB0aGFuIGl0IHRoZW4gaXQgaXNuJ3QgaGlnaGVyIHRoYW4gdGhlIHJhbmdlXG4gICAgaWYgKCghbG93Lm9wZXJhdG9yIHx8IGxvdy5vcGVyYXRvciA9PT0gY29tcCkgJiZcbiAgICAgICAgbHRlZm4odmVyc2lvbiwgbG93LnNlbXZlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKGxvdy5vcGVyYXRvciA9PT0gZWNvbXAgJiYgbHRmbih2ZXJzaW9uLCBsb3cuc2VtdmVyKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vfi9zZW12ZXIvc2VtdmVyLmpzXG4gKiovIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL34vcHJvY2Vzcy9icm93c2VyLmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBWaWV3TW9kZWwgQ29uc3RydWN0b3IgJiBkZWZpbml0aW9uXG4gKi9cblxuaW1wb3J0IHtleHRlbmQsIHRvQXJyYXl9IGZyb20gJy4uL3V0aWwnXG5cbmltcG9ydCAqIGFzIHNjb3BlIGZyb20gJy4vaW5zdGFuY2Uvc2NvcGUnXG5pbXBvcnQgKiBhcyBjb21waWxlciBmcm9tICcuL2NvbXBpbGVyJ1xuaW1wb3J0ICogYXMgZGlyZWN0aXZlIGZyb20gJy4vZGlyZWN0aXZlJ1xuaW1wb3J0ICogYXMgZG9tSGVscGVyIGZyb20gJy4vZG9tLWhlbHBlcidcbmltcG9ydCAqIGFzIGV2ZW50cyBmcm9tICcuL2V2ZW50cydcbi8vIGltcG9ydCAqIGFzIG1vZHVsZXMgZnJvbSAnLi8uLi9hcGkvbW9kdWxlcydcbi8vIGltcG9ydCAqIGFzIGFwaSBmcm9tICcuLy4uL2FwaS9hcGknXG5cbmltcG9ydCB7cmVnaXN0ZXJNb2R1bGVzLCByZWdpc3Rlck1ldGhvZHN9IGZyb20gJy4uL2FwcC9yZWdpc3RlcidcblxuZnVuY3Rpb24gY2FsbE9sZFJlYWR5RW50cnkodm0sIGNvbXBvbmVudCkge1xuICBpZiAoY29tcG9uZW50Lm1ldGhvZHMgJiZcbiAgICAgIGNvbXBvbmVudC5tZXRob2RzLnJlYWR5KSB7XG4gICAgY29tcG9uZW50Lm1ldGhvZHMucmVhZHkuY2FsbCh2bSlcbiAgfVxufVxuXG4vKipcbiAqIFZpZXdNb2RlbCBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyZW50Vm0gICB3aGljaCBjb250YWlucyBfYXBwXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyZW50RWwgICByb290IGVsZW1lbnQgb3IgZnJhZyBibG9ja1xuICogQHBhcmFtIHtvYmplY3R9IG1lcmdlZERhdGEgZXh0ZXJuYWwgZGF0YVxuICogQHBhcmFtIHtvYmplY3R9IGV4dGVybmFsRXZlbnRzIGV4dGVybmFsIGV2ZW50c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBWbShcbiAgdHlwZSxcbiAgcGFyZW50Vm0sXG4gIHBhcmVudEVsLFxuICBtZXJnZWREYXRhLFxuICBleHRlcm5hbEV2ZW50c1xuKSB7XG4gIHRoaXMuX3BhcmVudCA9IHBhcmVudFZtLl9yZWFsUGFyZW50ID8gcGFyZW50Vm0uX3JlYWxQYXJlbnQgOiBwYXJlbnRWbVxuICB0aGlzLl9hcHAgPSBwYXJlbnRWbS5fYXBwXG4gIHBhcmVudFZtLl9jaGlsZHJlblZtcyAmJiBwYXJlbnRWbS5fY2hpbGRyZW5WbXMucHVzaCh0aGlzKVxuXG4gIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuX2FwcC5jdXN0b21Db21wb25lbnRNYXBbdHlwZV0gfHwge31cbiAgY29uc3QgZGF0YSA9IGNvbXBvbmVudC5kYXRhIHx8IHt9XG5cbiAgdGhpcy5fb3B0aW9ucyA9IGNvbXBvbmVudFxuICB0aGlzLl9tZXRob2RzID0gY29tcG9uZW50Lm1ldGhvZHMgfHwge31cbiAgdGhpcy5fY29tcHV0ZWQgPSBjb21wb25lbnQuY29tcHV0ZWQgfHwge31cbiAgdGhpcy5fY3NzID0gY29tcG9uZW50LnN0eWxlIHx8IHt9XG4gIHRoaXMuX2lkcyA9IHt9XG4gIHRoaXMuX3dhdGNoZXJzID0gW11cbiAgdGhpcy5fdm1FdmVudHMgPSB7fVxuICB0aGlzLl9jaGlsZHJlblZtcyA9IFtdXG4gIHRoaXMuX3R5cGUgPSB0eXBlXG5cbiAgLy8gYmluZCBldmVudHMgYW5kIGxpZmVjeWNsZXNcbiAgdGhpcy5faW5pdEV2ZW50cyhleHRlcm5hbEV2ZW50cylcblxuICB0aGlzLiRlbWl0KCdob29rOmluaXQnKVxuICB0aGlzLl9pbml0ZWQgPSB0cnVlXG4gIC8vIHByb3h5IGRhdGEgYW5kIG1ldGhvZHNcbiAgLy8gb2JzZXJ2ZSBkYXRhIGFuZCBhZGQgdGhpcyB0byB2bXNcbiAgdGhpcy5fZGF0YSA9IHR5cGVvZiBkYXRhID09PSAnZnVuY3Rpb24nID8gZGF0YSgpIDogZGF0YVxuICBpZiAobWVyZ2VkRGF0YSkge1xuICAgIGV4dGVuZCh0aGlzLl9kYXRhLCBtZXJnZWREYXRhKVxuICB9XG4gIHRoaXMuX2luaXRTY29wZSgpXG5cbiAgdGhpcy4kZW1pdCgnaG9vazpjcmVhdGVkJylcbiAgdGhpcy5fY3JlYXRlZCA9IHRydWVcbiAgLy8gYmFja3dhcmQgb2xkIHJlYWR5IGVudHJ5XG4gIGNhbGxPbGRSZWFkeUVudHJ5KHRoaXMsIGNvbXBvbmVudClcblxuICAvLyBpZiBubyBwYXJlbnRFbGVtZW50IHRoZW4gc3BlY2lmeSB0aGUgZG9jdW1lbnRFbGVtZW50XG4gIHRoaXMuX3BhcmVudEVsID0gcGFyZW50RWwgfHwgdGhpcy5fYXBwLmRvYy5kb2N1bWVudEVsZW1lbnRcbiAgdGhpcy5fYnVpbGQoKVxufVxuXG5leHRlbmQoVm0ucHJvdG90eXBlLCBzY29wZSwgY29tcGlsZXIsIGRpcmVjdGl2ZSwgZG9tSGVscGVyLCBldmVudHMpXG5leHRlbmQoVm0sIHtcbiAgcmVnaXN0ZXJNb2R1bGVzLFxuICByZWdpc3Rlck1ldGhvZHNcbn0pXG4vLyBWbS5yZWdpc3Rlck1vZHVsZXMobW9kdWxlcylcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3ZtL2luZGV4LmpzXG4gKiovIiwidmFyIF8gPSByZXF1aXJlKCcuLi91dGlsJylcbnZhciBPYnNlcnZlciA9IHJlcXVpcmUoJy4uL29ic2VydmVyJylcbnZhciBEZXAgPSByZXF1aXJlKCcuLi9vYnNlcnZlci9kZXAnKVxuXG4vKipcbiAqIFNldHVwIHRoZSBzY29wZSBvZiBhbiBpbnN0YW5jZSwgd2hpY2ggY29udGFpbnM6XG4gKiAtIG9ic2VydmVkIGRhdGFcbiAqIC0gY29tcHV0ZWQgcHJvcGVydGllc1xuICogLSB1c2VyIG1ldGhvZHNcbiAqIC0gbWV0YSBwcm9wZXJ0aWVzXG4gKi9cblxuZXhwb3J0cy5faW5pdFNjb3BlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9pbml0RGF0YSgpXG4gIHRoaXMuX2luaXRDb21wdXRlZCgpXG4gIHRoaXMuX2luaXRNZXRob2RzKClcbiAgLy8gdGhpcy5faW5pdE1ldGEoKVxufVxuXG4vKipcbiAqIEluaXRpYWxpemUgdGhlIGRhdGEuIFxuICovXG5cbmV4cG9ydHMuX2luaXREYXRhID0gZnVuY3Rpb24gKCkge1xuICAvLyBwcm94eSBkYXRhIG9uIGluc3RhbmNlXG4gIHZhciBkYXRhID0gdGhpcy5fZGF0YVxuICB2YXIgaSwga2V5XG4gIC8vIC8vIG1ha2Ugc3VyZSBhbGwgcHJvcHMgcHJvcGVydGllcyBhcmUgb2JzZXJ2ZWRcbiAgLy8gdmFyIHByb3BzID0gdGhpcy4kb3B0aW9ucy5wcm9wc1xuICAvLyBpZiAocHJvcHMpIHtcbiAgLy8gICBpID0gcHJvcHMubGVuZ3RoXG4gIC8vICAgd2hpbGUgKGktLSkge1xuICAvLyAgICAga2V5ID0gXy5jYW1lbGl6ZShwcm9wc1tpXSlcbiAgLy8gICAgIGlmICghKGtleSBpbiBkYXRhKSkge1xuICAvLyAgICAgICBkYXRhW2tleV0gPSBudWxsXG4gIC8vICAgICB9XG4gIC8vICAgfVxuICAvLyB9XG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZGF0YSlcbiAgaSA9IGtleXMubGVuZ3RoXG4gIHdoaWxlIChpLS0pIHtcbiAgICBrZXkgPSBrZXlzW2ldXG4gICAgaWYgKCFfLmlzUmVzZXJ2ZWQoa2V5KSkge1xuICAgICAgdGhpcy5fcHJveHkoa2V5KVxuICAgIH1cbiAgfVxuICAvLyBvYnNlcnZlIGRhdGFcbiAgT2JzZXJ2ZXIuY3JlYXRlKGRhdGEpLmFkZFZtKHRoaXMpXG59XG5cbi8vIC8qKlxuLy8gICogU3dhcCB0aGUgaXNudGFuY2UncyAkZGF0YS4gQ2FsbGVkIGluICRkYXRhJ3Mgc2V0dGVyLlxuLy8gICpcbi8vICAqIEBwYXJhbSB7T2JqZWN0fSBuZXdEYXRhXG4vLyAgKi9cblxuLy8gZXhwb3J0cy5fc2V0RGF0YSA9IGZ1bmN0aW9uIChuZXdEYXRhKSB7XG4vLyAgIG5ld0RhdGEgPSBuZXdEYXRhIHx8IHt9XG4vLyAgIHZhciBvbGREYXRhID0gdGhpcy5fZGF0YVxuLy8gICB0aGlzLl9kYXRhID0gbmV3RGF0YVxuLy8gICB2YXIga2V5cywga2V5LCBpXG4vLyAgIC8vIHVucHJveHkga2V5cyBub3QgcHJlc2VudCBpbiBuZXcgZGF0YVxuLy8gICBrZXlzID0gT2JqZWN0LmtleXMob2xkRGF0YSlcbi8vICAgaSA9IGtleXMubGVuZ3RoXG4vLyAgIHdoaWxlIChpLS0pIHtcbi8vICAgICBrZXkgPSBrZXlzW2ldXG4vLyAgICAgaWYgKCFfLmlzUmVzZXJ2ZWQoa2V5KSAmJiAhKGtleSBpbiBuZXdEYXRhKSkge1xuLy8gICAgICAgdGhpcy5fdW5wcm94eShrZXkpXG4vLyAgICAgfVxuLy8gICB9XG4vLyAgIC8vIHByb3h5IGtleXMgbm90IGFscmVhZHkgcHJveGllZCxcbi8vICAgLy8gYW5kIHRyaWdnZXIgY2hhbmdlIGZvciBjaGFuZ2VkIHZhbHVlc1xuLy8gICBrZXlzID0gT2JqZWN0LmtleXMobmV3RGF0YSlcbi8vICAgaSA9IGtleXMubGVuZ3RoXG4vLyAgIHdoaWxlIChpLS0pIHtcbi8vICAgICBrZXkgPSBrZXlzW2ldXG4vLyAgICAgaWYgKCF0aGlzLmhhc093blByb3BlcnR5KGtleSkgJiYgIV8uaXNSZXNlcnZlZChrZXkpKSB7XG4vLyAgICAgICAvLyBuZXcgcHJvcGVydHlcbi8vICAgICAgIHRoaXMuX3Byb3h5KGtleSlcbi8vICAgICB9XG4vLyAgIH1cbi8vICAgb2xkRGF0YS5fX29iX18ucmVtb3ZlVm0odGhpcylcbi8vICAgT2JzZXJ2ZXIuY3JlYXRlKG5ld0RhdGEpLmFkZFZtKHRoaXMpXG4vLyAgIHRoaXMuX2RpZ2VzdCgpXG4vLyB9XG5cbi8qKlxuICogUHJveHkgYSBwcm9wZXJ0eSwgc28gdGhhdFxuICogdm0ucHJvcCA9PT0gdm0uX2RhdGEucHJvcFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqL1xuXG5leHBvcnRzLl9wcm94eSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgLy8gbmVlZCB0byBzdG9yZSByZWYgdG8gc2VsZiBoZXJlXG4gIC8vIGJlY2F1c2UgdGhlc2UgZ2V0dGVyL3NldHRlcnMgbWlnaHRcbiAgLy8gYmUgY2FsbGVkIGJ5IGNoaWxkIGluc3RhbmNlcyFcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZWxmLCBrZXksIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uIHByb3h5R2V0dGVyICgpIHtcbiAgICAgIHJldHVybiBzZWxmLl9kYXRhW2tleV1cbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gcHJveHlTZXR0ZXIgKHZhbCkge1xuICAgICAgc2VsZi5fZGF0YVtrZXldID0gdmFsXG4gICAgfVxuICB9KVxufVxuXG4vKipcbiAqIFVucHJveHkgYSBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKi9cblxuZXhwb3J0cy5fdW5wcm94eSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgZGVsZXRlIHRoaXNba2V5XVxufVxuXG4vLyAvKipcbi8vICAqIEZvcmNlIHVwZGF0ZSBvbiBldmVyeSB3YXRjaGVyIGluIHNjb3BlLlxuLy8gICovXG5cbi8vIGV4cG9ydHMuX2RpZ2VzdCA9IGZ1bmN0aW9uICgpIHtcbi8vICAgdmFyIGkgPSB0aGlzLl93YXRjaGVycy5sZW5ndGhcbi8vICAgd2hpbGUgKGktLSkge1xuLy8gICAgIHRoaXMuX3dhdGNoZXJzW2ldLnVwZGF0ZSgpXG4vLyAgIH1cbi8vICAgdmFyIGNoaWxkcmVuID0gdGhpcy5fY2hpbGRyZW5cbi8vICAgaSA9IGNoaWxkcmVuLmxlbmd0aFxuLy8gICB3aGlsZSAoaS0tKSB7XG4vLyAgICAgdmFyIGNoaWxkID0gY2hpbGRyZW5baV1cbi8vICAgICBpZiAoY2hpbGQuJG9wdGlvbnMuaW5oZXJpdCkge1xuLy8gICAgICAgY2hpbGQuX2RpZ2VzdCgpXG4vLyAgICAgfVxuLy8gICB9XG4vLyB9XG5cbi8qKlxuICogU2V0dXAgY29tcHV0ZWQgcHJvcGVydGllcy4gVGhleSBhcmUgZXNzZW50aWFsbHlcbiAqIHNwZWNpYWwgZ2V0dGVyL3NldHRlcnNcbiAqL1xuXG5mdW5jdGlvbiBub29wICgpIHt9XG5leHBvcnRzLl9pbml0Q29tcHV0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIHZhciBjb21wdXRlZCA9IHRoaXMuJG9wdGlvbnMuY29tcHV0ZWRcbiAgdmFyIGNvbXB1dGVkID0gdGhpcy5fY29tcHV0ZWRcbiAgaWYgKGNvbXB1dGVkKSB7XG4gICAgZm9yICh2YXIga2V5IGluIGNvbXB1dGVkKSB7XG4gICAgICB2YXIgdXNlckRlZiA9IGNvbXB1dGVkW2tleV1cbiAgICAgIHZhciBkZWYgPSB7XG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB1c2VyRGVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGRlZi5nZXQgPSBfLmJpbmQodXNlckRlZiwgdGhpcylcbiAgICAgICAgZGVmLnNldCA9IG5vb3BcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlZi5nZXQgPSB1c2VyRGVmLmdldFxuICAgICAgICAgID8gXy5iaW5kKHVzZXJEZWYuZ2V0LCB0aGlzKVxuICAgICAgICAgIDogbm9vcFxuICAgICAgICBkZWYuc2V0ID0gdXNlckRlZi5zZXRcbiAgICAgICAgICA/IF8uYmluZCh1c2VyRGVmLnNldCwgdGhpcylcbiAgICAgICAgICA6IG5vb3BcbiAgICAgIH1cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBrZXksIGRlZilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBTZXR1cCBpbnN0YW5jZSBtZXRob2RzLiBNZXRob2RzIG11c3QgYmUgYm91bmQgdG8gdGhlXG4gKiBpbnN0YW5jZSBzaW5jZSB0aGV5IG1pZ2h0IGJlIGNhbGxlZCBieSBjaGlsZHJlblxuICogaW5oZXJpdGluZyB0aGVtLlxuICovXG5cbmV4cG9ydHMuX2luaXRNZXRob2RzID0gZnVuY3Rpb24gKCkge1xuICAvLyB2YXIgbWV0aG9kcyA9IHRoaXMuJG9wdGlvbnMubWV0aG9kc1xuICB2YXIgbWV0aG9kcyA9IHRoaXMuX21ldGhvZHNcbiAgaWYgKG1ldGhvZHMpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gbWV0aG9kcykge1xuICAgICAgdGhpc1trZXldID0gXy5iaW5kKG1ldGhvZHNba2V5XSwgdGhpcylcbiAgICB9XG4gIH1cbn1cblxuLy8gLyoqXG4vLyAgKiBJbml0aWFsaXplIG1ldGEgaW5mb3JtYXRpb24gbGlrZSAkaW5kZXgsICRrZXkgJiAkdmFsdWUuXG4vLyAgKi9cblxuLy8gZXhwb3J0cy5faW5pdE1ldGEgPSBmdW5jdGlvbiAoKSB7XG4vLyAgIHZhciBtZXRhcyA9IHRoaXMuJG9wdGlvbnMuX21ldGFcbi8vICAgaWYgKG1ldGFzKSB7XG4vLyAgICAgZm9yICh2YXIga2V5IGluIG1ldGFzKSB7XG4vLyAgICAgICB0aGlzLl9kZWZpbmVNZXRhKGtleSwgbWV0YXNba2V5XSlcbi8vICAgICB9XG4vLyAgIH1cbi8vIH1cblxuLy8gLyoqXG4vLyAgKiBEZWZpbmUgYSBtZXRhIHByb3BlcnR5LCBlLmcgJGluZGV4LCAka2V5LCAkdmFsdWVcbi8vICAqIHdoaWNoIG9ubHkgZXhpc3RzIG9uIHRoZSB2bSBpbnN0YW5jZSBidXQgbm90IGluICRkYXRhLlxuLy8gICpcbi8vICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbi8vICAqIEBwYXJhbSB7Kn0gdmFsdWVcbi8vICAqL1xuXG4vLyBleHBvcnRzLl9kZWZpbmVNZXRhID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbi8vICAgdmFyIGRlcCA9IG5ldyBEZXAoKVxuLy8gICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XG4vLyAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbi8vICAgICBjb25maWd1cmFibGU6IHRydWUsXG4vLyAgICAgZ2V0OiBmdW5jdGlvbiBtZXRhR2V0dGVyICgpIHtcbi8vICAgICAgIGlmIChPYnNlcnZlci50YXJnZXQpIHtcbi8vICAgICAgICAgT2JzZXJ2ZXIudGFyZ2V0LmFkZERlcChkZXApXG4vLyAgICAgICB9XG4vLyAgICAgICByZXR1cm4gdmFsdWVcbi8vICAgICB9LFxuLy8gICAgIHNldDogZnVuY3Rpb24gbWV0YVNldHRlciAodmFsKSB7XG4vLyAgICAgICBpZiAodmFsICE9PSB2YWx1ZSkge1xuLy8gICAgICAgICB2YWx1ZSA9IHZhbFxuLy8gICAgICAgICBkZXAubm90aWZ5KClcbi8vICAgICAgIH1cbi8vICAgICB9XG4vLyAgIH0pXG4vLyB9XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi92bS9pbnN0YW5jZS9zY29wZS5qc1xuICoqLyIsIi8vIHJlcXVpcmVkIGZvciBjb2RlIGluIGluc3RhbmNlL29ic2VydmVyXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uL3V0aWwnKVxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3ZtL3V0aWwuanNcbiAqKi8iLCJ2YXIgXyA9IHJlcXVpcmUoJy4uL3V0aWwnKVxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG52YXIgRGVwID0gcmVxdWlyZSgnLi9kZXAnKVxudmFyIGFycmF5TWV0aG9kcyA9IHJlcXVpcmUoJy4vYXJyYXknKVxudmFyIGFycmF5S2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGFycmF5TWV0aG9kcylcbnJlcXVpcmUoJy4vb2JqZWN0JylcblxudmFyIHVpZCA9IDBcblxuLyoqXG4gKiBUeXBlIGVudW1zXG4gKi9cblxudmFyIEFSUkFZICA9IDBcbnZhciBPQkpFQ1QgPSAxXG5cbi8qKlxuICogQXVnbWVudCBhbiB0YXJnZXQgT2JqZWN0IG9yIEFycmF5IGJ5IGludGVyY2VwdGluZ1xuICogdGhlIHByb3RvdHlwZSBjaGFpbiB1c2luZyBfX3Byb3RvX19cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gdGFyZ2V0XG4gKiBAcGFyYW0ge09iamVjdH0gcHJvdG9cbiAqL1xuXG5mdW5jdGlvbiBwcm90b0F1Z21lbnQgKHRhcmdldCwgc3JjKSB7XG4gIHRhcmdldC5fX3Byb3RvX18gPSBzcmNcbn1cblxuLyoqXG4gKiBBdWdtZW50IGFuIHRhcmdldCBPYmplY3Qgb3IgQXJyYXkgYnkgZGVmaW5pbmdcbiAqIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSB0YXJnZXRcbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90b1xuICovXG5cbmZ1bmN0aW9uIGNvcHlBdWdtZW50ICh0YXJnZXQsIHNyYywga2V5cykge1xuICB2YXIgaSA9IGtleXMubGVuZ3RoXG4gIHZhciBrZXlcbiAgd2hpbGUgKGktLSkge1xuICAgIGtleSA9IGtleXNbaV1cbiAgICBfLmRlZmluZSh0YXJnZXQsIGtleSwgc3JjW2tleV0pXG4gIH1cbn1cblxuLyoqXG4gKiBPYnNlcnZlciBjbGFzcyB0aGF0IGFyZSBhdHRhY2hlZCB0byBlYWNoIG9ic2VydmVkXG4gKiBvYmplY3QuIE9uY2UgYXR0YWNoZWQsIHRoZSBvYnNlcnZlciBjb252ZXJ0cyB0YXJnZXRcbiAqIG9iamVjdCdzIHByb3BlcnR5IGtleXMgaW50byBnZXR0ZXIvc2V0dGVycyB0aGF0XG4gKiBjb2xsZWN0IGRlcGVuZGVuY2llcyBhbmQgZGlzcGF0Y2hlcyB1cGRhdGVzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSB2YWx1ZVxuICogQHBhcmFtIHtOdW1iZXJ9IHR5cGVcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5cbmZ1bmN0aW9uIE9ic2VydmVyICh2YWx1ZSwgdHlwZSkge1xuICB0aGlzLmlkID0gKyt1aWRcbiAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gIHRoaXMuYWN0aXZlID0gdHJ1ZVxuICB0aGlzLmRlcHMgPSBbXVxuICBfLmRlZmluZSh2YWx1ZSwgJ19fb2JfXycsIHRoaXMpXG4gIGlmICh0eXBlID09PSBBUlJBWSkge1xuICAgIHZhciBhdWdtZW50ID0gY29uZmlnLnByb3RvICYmIF8uaGFzUHJvdG9cbiAgICAgID8gcHJvdG9BdWdtZW50XG4gICAgICA6IGNvcHlBdWdtZW50XG4gICAgYXVnbWVudCh2YWx1ZSwgYXJyYXlNZXRob2RzLCBhcnJheUtleXMpXG4gICAgdGhpcy5vYnNlcnZlQXJyYXkodmFsdWUpXG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gT0JKRUNUKSB7XG4gICAgdGhpcy53YWxrKHZhbHVlKVxuICB9XG59XG5cbk9ic2VydmVyLnRhcmdldCA9IG51bGxcblxudmFyIHAgPSBPYnNlcnZlci5wcm90b3R5cGVcblxuLyoqXG4gKiBBdHRlbXB0IHRvIGNyZWF0ZSBhbiBvYnNlcnZlciBpbnN0YW5jZSBmb3IgYSB2YWx1ZSxcbiAqIHJldHVybnMgdGhlIG5ldyBvYnNlcnZlciBpZiBzdWNjZXNzZnVsbHkgb2JzZXJ2ZWQsXG4gKiBvciB0aGUgZXhpc3Rpbmcgb2JzZXJ2ZXIgaWYgdGhlIHZhbHVlIGFscmVhZHkgaGFzIG9uZS5cbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcmV0dXJuIHtPYnNlcnZlcnx1bmRlZmluZWR9XG4gKiBAc3RhdGljXG4gKi9cblxuT2JzZXJ2ZXIuY3JlYXRlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIGlmIChcbiAgICB2YWx1ZSAmJlxuICAgIHZhbHVlLmhhc093blByb3BlcnR5KCdfX29iX18nKSAmJlxuICAgIHZhbHVlLl9fb2JfXyBpbnN0YW5jZW9mIE9ic2VydmVyXG4gICkge1xuICAgIHJldHVybiB2YWx1ZS5fX29iX19cbiAgfSBlbHNlIGlmIChfLmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZlcih2YWx1ZSwgQVJSQVkpXG4gIH0gZWxzZSBpZiAoXG4gICAgXy5pc1BsYWluT2JqZWN0KHZhbHVlKSAmJlxuICAgICF2YWx1ZS5faXNWdWUgLy8gYXZvaWQgVnVlIGluc3RhbmNlXG4gICkge1xuICAgIHJldHVybiBuZXcgT2JzZXJ2ZXIodmFsdWUsIE9CSkVDVClcbiAgfVxufVxuXG4vKipcbiAqIFdhbGsgdGhyb3VnaCBlYWNoIHByb3BlcnR5IGFuZCBjb252ZXJ0IHRoZW0gaW50b1xuICogZ2V0dGVyL3NldHRlcnMuIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIGNhbGxlZCB3aGVuXG4gKiB2YWx1ZSB0eXBlIGlzIE9iamVjdC4gUHJvcGVydGllcyBwcmVmaXhlZCB3aXRoIGAkYCBvciBgX2BcbiAqIGFuZCBhY2Nlc3NvciBwcm9wZXJ0aWVzIGFyZSBpZ25vcmVkLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqL1xuXG5wLndhbGsgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKVxuICB2YXIgaSA9IGtleXMubGVuZ3RoXG4gIHZhciBrZXksIHByZWZpeFxuICB3aGlsZSAoaS0tKSB7XG4gICAga2V5ID0ga2V5c1tpXVxuICAgIHByZWZpeCA9IGtleS5jaGFyQ29kZUF0KDApXG4gICAgaWYgKHByZWZpeCAhPT0gMHgyNCAmJiBwcmVmaXggIT09IDB4NUYpIHsgLy8gc2tpcCAkIG9yIF9cbiAgICAgIHRoaXMuY29udmVydChrZXksIG9ialtrZXldKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRyeSB0byBjYXJldGUgYW4gb2JzZXJ2ZXIgZm9yIGEgY2hpbGQgdmFsdWUsXG4gKiBhbmQgaWYgdmFsdWUgaXMgYXJyYXksIGxpbmsgZGVwIHRvIHRoZSBhcnJheS5cbiAqXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7RGVwfHVuZGVmaW5lZH1cbiAqL1xuXG5wLm9ic2VydmUgPSBmdW5jdGlvbiAodmFsKSB7XG4gIHJldHVybiBPYnNlcnZlci5jcmVhdGUodmFsKVxufVxuXG4vKipcbiAqIE9ic2VydmUgYSBsaXN0IG9mIEFycmF5IGl0ZW1zLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGl0ZW1zXG4gKi9cblxucC5vYnNlcnZlQXJyYXkgPSBmdW5jdGlvbiAoaXRlbXMpIHtcbiAgdmFyIGkgPSBpdGVtcy5sZW5ndGhcbiAgd2hpbGUgKGktLSkge1xuICAgIHRoaXMub2JzZXJ2ZShpdGVtc1tpXSlcbiAgfVxufVxuXG4vKipcbiAqIENvbnZlcnQgYSBwcm9wZXJ0eSBpbnRvIGdldHRlci9zZXR0ZXIgc28gd2UgY2FuIGVtaXRcbiAqIHRoZSBldmVudHMgd2hlbiB0aGUgcHJvcGVydHkgaXMgYWNjZXNzZWQvY2hhbmdlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcGFyYW0geyp9IHZhbFxuICovXG5cbnAuY29udmVydCA9IGZ1bmN0aW9uIChrZXksIHZhbCkge1xuICB2YXIgb2IgPSB0aGlzXG4gIHZhciBjaGlsZE9iID0gb2Iub2JzZXJ2ZSh2YWwpXG4gIHZhciBkZXAgPSBuZXcgRGVwKClcbiAgaWYgKGNoaWxkT2IpIHtcbiAgICBjaGlsZE9iLmRlcHMucHVzaChkZXApXG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iLnZhbHVlLCBrZXksIHtcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIE9ic2VydmVyLnRhcmdldCBpcyBhIHdhdGNoZXIgd2hvc2UgZ2V0dGVyIGlzXG4gICAgICAvLyBjdXJyZW50bHkgYmVpbmcgZXZhbHVhdGVkLlxuICAgICAgaWYgKG9iLmFjdGl2ZSAmJiBPYnNlcnZlci50YXJnZXQpIHtcbiAgICAgICAgT2JzZXJ2ZXIudGFyZ2V0LmFkZERlcChkZXApXG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsXG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uIChuZXdWYWwpIHtcbiAgICAgIGlmIChuZXdWYWwgPT09IHZhbCkgcmV0dXJuXG4gICAgICAvLyByZW1vdmUgZGVwIGZyb20gb2xkIHZhbHVlXG4gICAgICB2YXIgb2xkQ2hpbGRPYiA9IHZhbCAmJiB2YWwuX19vYl9fXG4gICAgICBpZiAob2xkQ2hpbGRPYikge1xuICAgICAgICBvbGRDaGlsZE9iLmRlcHMuJHJlbW92ZShkZXApXG4gICAgICB9XG4gICAgICB2YWwgPSBuZXdWYWxcbiAgICAgIC8vIGFkZCBkZXAgdG8gbmV3IHZhbHVlXG4gICAgICB2YXIgbmV3Q2hpbGRPYiA9IG9iLm9ic2VydmUobmV3VmFsKVxuICAgICAgaWYgKG5ld0NoaWxkT2IpIHtcbiAgICAgICAgbmV3Q2hpbGRPYi5kZXBzLnB1c2goZGVwKVxuICAgICAgfVxuICAgICAgZGVwLm5vdGlmeSgpXG4gICAgfVxuICB9KVxufVxuXG4vKipcbiAqIE5vdGlmeSBjaGFuZ2Ugb24gYWxsIHNlbGYgZGVwcyBvbiBhbiBvYnNlcnZlci5cbiAqIFRoaXMgaXMgY2FsbGVkIHdoZW4gYSBtdXRhYmxlIHZhbHVlIG11dGF0ZXMuIGUuZy5cbiAqIHdoZW4gYW4gQXJyYXkncyBtdXRhdGluZyBtZXRob2RzIGFyZSBjYWxsZWQsIG9yIGFuXG4gKiBPYmplY3QncyAkYWRkLyRkZWxldGUgYXJlIGNhbGxlZC5cbiAqL1xuXG5wLm5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGRlcHMgPSB0aGlzLmRlcHNcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBkZXBzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGRlcHNbaV0ubm90aWZ5KClcbiAgfVxufVxuXG4vKipcbiAqIEFkZCBhbiBvd25lciB2bSwgc28gdGhhdCB3aGVuICRhZGQvJGRlbGV0ZSBtdXRhdGlvbnNcbiAqIGhhcHBlbiB3ZSBjYW4gbm90aWZ5IG93bmVyIHZtcyB0byBwcm94eSB0aGUga2V5cyBhbmRcbiAqIGRpZ2VzdCB0aGUgd2F0Y2hlcnMuIFRoaXMgaXMgb25seSBjYWxsZWQgd2hlbiB0aGUgb2JqZWN0XG4gKiBpcyBvYnNlcnZlZCBhcyBhbiBpbnN0YW5jZSdzIHJvb3QgJGRhdGEuXG4gKlxuICogQHBhcmFtIHtWdWV9IHZtXG4gKi9cblxucC5hZGRWbSA9IGZ1bmN0aW9uICh2bSkge1xuICAodGhpcy52bXMgPSB0aGlzLnZtcyB8fCBbXSkucHVzaCh2bSlcbn1cblxuLyoqXG4gKiBSZW1vdmUgYW4gb3duZXIgdm0uIFRoaXMgaXMgY2FsbGVkIHdoZW4gdGhlIG9iamVjdCBpc1xuICogc3dhcHBlZCBvdXQgYXMgYW4gaW5zdGFuY2UncyAkZGF0YSBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtWdWV9IHZtXG4gKi9cblxucC5yZW1vdmVWbSA9IGZ1bmN0aW9uICh2bSkge1xuICB0aGlzLnZtcy4kcmVtb3ZlKHZtKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IE9ic2VydmVyXG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi92bS9vYnNlcnZlci9pbmRleC5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0ge3Byb3RvOiB0cnVlfVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdm0vY29uZmlnLmpzXG4gKiovIiwidmFyIF8gPSByZXF1aXJlKCcuLi91dGlsJylcblxuLyoqXG4gKiBBIGRlcCBpcyBhbiBvYnNlcnZhYmxlIHRoYXQgY2FuIGhhdmUgbXVsdGlwbGVcbiAqIGRpcmVjdGl2ZXMgc3Vic2NyaWJpbmcgdG8gaXQuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cblxuZnVuY3Rpb24gRGVwICgpIHtcbiAgdGhpcy5zdWJzID0gW11cbn1cblxudmFyIHAgPSBEZXAucHJvdG90eXBlXG5cbi8qKlxuICogQWRkIGEgZGlyZWN0aXZlIHN1YnNjcmliZXIuXG4gKlxuICogQHBhcmFtIHtEaXJlY3RpdmV9IHN1YlxuICovXG5cbnAuYWRkU3ViID0gZnVuY3Rpb24gKHN1Yikge1xuICB0aGlzLnN1YnMucHVzaChzdWIpXG59XG5cbi8qKlxuICogUmVtb3ZlIGEgZGlyZWN0aXZlIHN1YnNjcmliZXIuXG4gKlxuICogQHBhcmFtIHtEaXJlY3RpdmV9IHN1YlxuICovXG5cbnAucmVtb3ZlU3ViID0gZnVuY3Rpb24gKHN1Yikge1xuICB0aGlzLnN1YnMuJHJlbW92ZShzdWIpXG59XG5cbi8qKlxuICogTm90aWZ5IGFsbCBzdWJzY3JpYmVycyBvZiBhIG5ldyB2YWx1ZS5cbiAqL1xuXG5wLm5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gc3RhYmxpemUgdGhlIHN1YnNjcmliZXIgbGlzdCBmaXJzdFxuICB2YXIgc3VicyA9IF8udG9BcnJheSh0aGlzLnN1YnMpXG4gIGZvciAodmFyIGkgPSAwLCBsID0gc3Vicy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBzdWJzW2ldLnVwZGF0ZSgpXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBEZXBcblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi92bS9vYnNlcnZlci9kZXAuanNcbiAqKi8iLCJ2YXIgXyA9IHJlcXVpcmUoJy4uL3V0aWwnKVxudmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGVcbnZhciBhcnJheU1ldGhvZHMgPSBPYmplY3QuY3JlYXRlKGFycmF5UHJvdG8pXG5cbi8qKlxuICogSW50ZXJjZXB0IG11dGF0aW5nIG1ldGhvZHMgYW5kIGVtaXQgZXZlbnRzXG4gKi9cblxuO1tcbiAgJ3B1c2gnLFxuICAncG9wJyxcbiAgJ3NoaWZ0JyxcbiAgJ3Vuc2hpZnQnLFxuICAnc3BsaWNlJyxcbiAgJ3NvcnQnLFxuICAncmV2ZXJzZSdcbl1cbi5mb3JFYWNoKGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgLy8gY2FjaGUgb3JpZ2luYWwgbWV0aG9kXG4gIHZhciBvcmlnaW5hbCA9IGFycmF5UHJvdG9bbWV0aG9kXVxuICBfLmRlZmluZShhcnJheU1ldGhvZHMsIG1ldGhvZCwgZnVuY3Rpb24gbXV0YXRvciAoKSB7XG4gICAgLy8gYXZvaWQgbGVha2luZyBhcmd1bWVudHM6XG4gICAgLy8gaHR0cDovL2pzcGVyZi5jb20vY2xvc3VyZS13aXRoLWFyZ3VtZW50c1xuICAgIHZhciBpID0gYXJndW1lbnRzLmxlbmd0aFxuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGkpXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXVxuICAgIH1cbiAgICB2YXIgcmVzdWx0ID0gb3JpZ2luYWwuYXBwbHkodGhpcywgYXJncylcbiAgICB2YXIgb2IgPSB0aGlzLl9fb2JfX1xuICAgIHZhciBpbnNlcnRlZFxuICAgIHN3aXRjaCAobWV0aG9kKSB7XG4gICAgICBjYXNlICdwdXNoJzpcbiAgICAgICAgaW5zZXJ0ZWQgPSBhcmdzXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICd1bnNoaWZ0JzpcbiAgICAgICAgaW5zZXJ0ZWQgPSBhcmdzXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdzcGxpY2UnOlxuICAgICAgICBpbnNlcnRlZCA9IGFyZ3Muc2xpY2UoMilcbiAgICAgICAgYnJlYWtcbiAgICB9XG4gICAgaWYgKGluc2VydGVkKSBvYi5vYnNlcnZlQXJyYXkoaW5zZXJ0ZWQpXG4gICAgLy8gbm90aWZ5IGNoYW5nZVxuICAgIG9iLm5vdGlmeSgpXG4gICAgcmV0dXJuIHJlc3VsdFxuICB9KVxufSlcblxuLyoqXG4gKiBTd2FwIHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleCB3aXRoIGEgbmV3IHZhbHVlXG4gKiBhbmQgZW1pdHMgY29ycmVzcG9uZGluZyBldmVudC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHsqfSAtIHJlcGxhY2VkIGVsZW1lbnRcbiAqL1xuXG5fLmRlZmluZShcbiAgYXJyYXlQcm90byxcbiAgJyRzZXQnLFxuICBmdW5jdGlvbiAkc2V0IChpbmRleCwgdmFsKSB7XG4gICAgaWYgKGluZGV4ID49IHRoaXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLmxlbmd0aCA9IGluZGV4ICsgMVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zcGxpY2UoaW5kZXgsIDEsIHZhbClbMF1cbiAgfVxuKVxuXG4vKipcbiAqIENvbnZlbmllbmNlIG1ldGhvZCB0byByZW1vdmUgdGhlIGVsZW1lbnQgYXQgZ2l2ZW4gaW5kZXguXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XG4gKiBAcGFyYW0geyp9IHZhbFxuICovXG5cbl8uZGVmaW5lKFxuICBhcnJheVByb3RvLFxuICAnJHJlbW92ZScsXG4gIGZ1bmN0aW9uICRyZW1vdmUgKGluZGV4KSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKCF0aGlzLmxlbmd0aCkgcmV0dXJuXG4gICAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHtcbiAgICAgIGluZGV4ID0gXy5pbmRleE9mKHRoaXMsIGluZGV4KVxuICAgIH1cbiAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgdGhpcy5zcGxpY2UoaW5kZXgsIDEpXG4gICAgfVxuICB9XG4pXG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlNZXRob2RzXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdm0vb2JzZXJ2ZXIvYXJyYXkuanNcbiAqKi8iLCJ2YXIgXyA9IHJlcXVpcmUoJy4uL3V0aWwnKVxudmFyIG9ialByb3RvID0gT2JqZWN0LnByb3RvdHlwZVxuXG4vKipcbiAqIEFkZCBhIG5ldyBwcm9wZXJ0eSB0byBhbiBvYnNlcnZlZCBvYmplY3RcbiAqIGFuZCBlbWl0cyBjb3JyZXNwb25kaW5nIGV2ZW50XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEBwdWJsaWNcbiAqL1xuXG5fLmRlZmluZShcbiAgb2JqUHJvdG8sXG4gICckYWRkJyxcbiAgZnVuY3Rpb24gJGFkZCAoa2V5LCB2YWwpIHtcbiAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSByZXR1cm5cbiAgICB2YXIgb2IgPSB0aGlzLl9fb2JfX1xuICAgIGlmICghb2IgfHwgXy5pc1Jlc2VydmVkKGtleSkpIHtcbiAgICAgIHRoaXNba2V5XSA9IHZhbFxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIG9iLmNvbnZlcnQoa2V5LCB2YWwpXG4gICAgb2Iubm90aWZ5KClcbiAgICBpZiAob2Iudm1zKSB7XG4gICAgICB2YXIgaSA9IG9iLnZtcy5sZW5ndGhcbiAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgdmFyIHZtID0gb2Iudm1zW2ldXG4gICAgICAgIHZtLl9wcm94eShrZXkpXG4gICAgICAgIC8vIHZtLl9kaWdlc3QoKSAvLyB0b2RvXG4gICAgICB9XG4gICAgfVxuICB9XG4pXG5cbi8qKlxuICogU2V0IGEgcHJvcGVydHkgb24gYW4gb2JzZXJ2ZWQgb2JqZWN0LCBjYWxsaW5nIGFkZCB0b1xuICogZW5zdXJlIHRoZSBwcm9wZXJ0eSBpcyBvYnNlcnZlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHB1YmxpY1xuICovXG5cbl8uZGVmaW5lKFxuICBvYmpQcm90byxcbiAgJyRzZXQnLFxuICBmdW5jdGlvbiAkc2V0IChrZXksIHZhbCkge1xuICAgIHRoaXMuJGFkZChrZXksIHZhbClcbiAgICB0aGlzW2tleV0gPSB2YWxcbiAgfVxuKVxuXG4vKipcbiAqIERlbGV0ZXMgYSBwcm9wZXJ0eSBmcm9tIGFuIG9ic2VydmVkIG9iamVjdFxuICogYW5kIGVtaXRzIGNvcnJlc3BvbmRpbmcgZXZlbnRcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcHVibGljXG4gKi9cblxuXy5kZWZpbmUoXG4gIG9ialByb3RvLFxuICAnJGRlbGV0ZScsXG4gIGZ1bmN0aW9uICRkZWxldGUgKGtleSkge1xuICAgIGlmICghdGhpcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSByZXR1cm5cbiAgICBkZWxldGUgdGhpc1trZXldXG4gICAgdmFyIG9iID0gdGhpcy5fX29iX19cbiAgICBpZiAoIW9iIHx8IF8uaXNSZXNlcnZlZChrZXkpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgb2Iubm90aWZ5KClcbiAgICBpZiAob2Iudm1zKSB7XG4gICAgICB2YXIgaSA9IG9iLnZtcy5sZW5ndGhcbiAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgdmFyIHZtID0gb2Iudm1zW2ldXG4gICAgICAgIHZtLl91bnByb3h5KGtleSlcbiAgICAgICAgLy8gdm0uX2RpZ2VzdCgpIC8vIHRvZG9cbiAgICAgIH1cbiAgICB9XG4gIH1cbilcblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3ZtL29ic2VydmVyL29iamVjdC5qc1xuICoqLyIsIiAvKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIFZpZXdNb2RlbCB0ZW1wbGF0ZSBwYXJzZXIgJiBkYXRhLWJpbmRpbmcgcHJvY2Vzc1xuICpcbiAqIHJlcXVpcmVkOlxuICogaW5kZXguanM6IFZtXG4gKiBkb20taGVscGVyLmpzOiBfY3JlYXRlRWxlbWVudCwgX2NyZWF0ZUJsb2NrXG4gKiBkb20taGVscGVyLmpzOiBfYXR0YWNoVGFyZ2V0LCBfbW92ZVRhcmdldCwgX3JlbW92ZVRhcmdldFxuICogZGlyZWN0aXZlLmpzOiBfYmluZEVsZW1lbnQsIF9iaW5kU3ViVm0sIF93YXRjaFxuICogZXZlbnRzLmpzOiAkb25cbiAqL1xuXG4vKipcbiAqIGJ1aWxkKGV4dGVybmFsRGlycylcbiAqICAgY3JlYXRlVm0oKVxuICogICBtZXJnZShleHRlcm5hbERpcnMsIGRpcnMpXG4gKiAgIGdlbmVyYXRlKHRlbXBsYXRlLCBwYXJlbnROb2RlKVxuICogICAgIGlmICh0eXBlIGlzIGNvbnRlbnQpIGNyZWF0ZSBjb250ZW50Tm9kZVxuICogICAgIGVsc2UgaWYgKGRpcnMgaGF2ZSB2LWZvcikgZm9yZWFjaCAtPiBjcmVhdGUgY29udGV4dFxuICogICAgICAgLT4gZ2VuZXJhdGUodGVtcGxhdGVXaXRob3V0Rm9yLCBwYXJlbnROb2RlKTogZGlmZihsaXN0KSBvbmNoYW5nZVxuICogICAgIGVsc2UgaWYgKGRpcnMgaGF2ZSB2LWlmKSBhc3NlcnRcbiAqICAgICAgIC0+IGdlbmVyYXRlKHRlbXBsYXRlV2l0aG91dElmLCBwYXJlbnROb2RlKTogdG9nZ2xlKHNob3duKSBvbmNoYW5nZVxuICogICAgIGVsc2UgaWYgKHR5cGUgaXMgbmF0aXZlKVxuICogICAgICAgc2V0KGRpcnMpOiB1cGRhdGUoaWQvYXR0ci9zdHlsZS9jbGFzcykgb25jaGFuZ2VcbiAqICAgICAgIGFwcGVuZCh0ZW1wbGF0ZSwgcGFyZW50Tm9kZSlcbiAqICAgICAgIGZvcmVhY2ggY2hpbGROb2RlcyAtPiBnZW5lcmF0ZShjaGlsZE5vZGUsIHRlbXBsYXRlKVxuICogICAgIGVsc2UgaWYgKHR5cGUgaXMgY3VzdG9tKVxuICogICAgICAgYWRkQ2hpbGRWbSh2bSwgcGFyZW50Vm0pXG4gKiAgICAgICBidWlsZChleHRlcm5hbERpcnMpXG4gKiAgICAgICBmb3JlYWNoIGNoaWxkTm9kZXMgLT4gZ2VuZXJhdGUoY2hpbGROb2RlLCB0ZW1wbGF0ZSlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9idWlsZCgpIHtcbiAgY29uc3Qgb3B0ID0gdGhpcy5fb3B0aW9ucyB8fCB7fVxuICBjb25zdCB0ZW1wbGF0ZSA9IG9wdC50ZW1wbGF0ZSB8fCB7fVxuXG4gIGlmIChvcHQucmVwbGFjZSkge1xuICAgIGlmICh0ZW1wbGF0ZS5jaGlsZHJlbiAmJiB0ZW1wbGF0ZS5jaGlsZHJlbi5sZW5ndGggPT09IDEpIHtcbiAgICAgIHRoaXMuX2dlbmVyYXRlKHRlbXBsYXRlLmNoaWxkcmVuWzBdLCB0aGlzLl9wYXJlbnRFbClcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLl9nZW5lcmF0ZSh0ZW1wbGF0ZS5jaGlsZHJlbiwgdGhpcy5fcGFyZW50RWwpXG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMuX2dlbmVyYXRlKHRlbXBsYXRlLCB0aGlzLl9wYXJlbnRFbClcbiAgfVxuXG4gIHRoaXMuJGVtaXQoJ2hvb2s6cmVhZHknKVxuICB0aGlzLl9yZWFkeSA9IHRydWVcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBlbGVtZW50cyBieSBjaGlsZCBvciBjaGlsZHJlbiBhbmQgYXBwZW5kIHRvIHBhcmVudCBlbGVtZW50cy5cbiAqIFJvb3QgZWxlbWVudCBpbmZvIHdvdWxkIGJlIG1lcmdlZCBpZiBoYXMuIFRoZSBmaXJzdCBhcmd1bWVudCBtYXkgYmUgYW4gYXJyYXlcbiAqIGlmIHRoZSByb290IGVsZW1lbnQgd2l0aCBvcHRpb25zLnJlcGxhY2UgaGFzIG5vdCBvbmx5IG9uZSBjaGlsZC5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R8YXJyYXl9IHRhcmdldFxuICogQHBhcmFtICB7b2JqZWN0fSBwYXJlbnRFbFxuICogQHBhcmFtICB7b2JqZWN0fSBjb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfZ2VuZXJhdGUodGFyZ2V0LCBwYXJlbnRFbCwgY29udGV4dCkge1xuXG4gIGlmIChBcnJheS5pc0FycmF5KHRhcmdldCkpIHtcbiAgICBjb25zdCBmcmFnQmxvY2sgPSB0aGlzLl9jcmVhdGVCbG9jayhwYXJlbnRFbClcbiAgICB0YXJnZXQuZm9yRWFjaCgoY2hpbGQpID0+IHtcbiAgICAgIHRoaXMuX2dlbmVyYXRlKGNoaWxkLCBmcmFnQmxvY2ssIGNvbnRleHQpXG4gICAgfSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIGNvbnRleHQgPSBjb250ZXh0IHx8IHt9XG5cbiAgaWYgKHRhcmdldC50eXBlID09PSAnY29udGVudCcgfHwgdGFyZ2V0LnR5cGUgPT09ICdzbG90Jykge1xuICAgIHRoaXMuX2NvbnRlbnQgPSB0aGlzLl9jcmVhdGVCbG9jayhwYXJlbnRFbClcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmICghY29udGV4dC5oYXNPd25Qcm9wZXJ0eSgncmVwZWF0JykgJiYgdGFyZ2V0LnJlcGVhdCkge1xuICAgIGNvbnN0IGxpc3QgPSB0YXJnZXQucmVwZWF0LmNhbGwodGhpcylcbiAgICBjb25zdCByZXBlYXRJZCA9IGxhdGVzdFJlcGVhdElkKytcbiAgICBjb25zdCBsYXRlc3RJdGVtSWQgPSBtYXJrTGlzdChsaXN0LCByZXBlYXRJZClcblxuICAgIGNvbnN0IGZyYWdCbG9jayA9IHRoaXMuX2NyZWF0ZUJsb2NrKHBhcmVudEVsKVxuICAgIGZyYWdCbG9jay5jaGlsZHJlbiA9IFtdXG4gICAgZnJhZ0Jsb2NrLmRhdGEgPSBsaXN0LnNsaWNlKDApXG5cbiAgICB0aGlzLl9jaGVja1JlcGVhdCh0YXJnZXQsIGZyYWdCbG9jaywgcmVwZWF0SWQsIGxhdGVzdEl0ZW1JZClcblxuICAgIGxpc3QuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgaXRlbS5JTkRFWCA9IGluZGV4XG4gICAgICB9XG4gICAgICB0aGlzLl9nZW5lcmF0ZSh0YXJnZXQsIGZyYWdCbG9jaywge3JlcGVhdDogaXRlbX0pXG4gICAgfSlcblxuICAgIHJldHVyblxuICB9XG5cbiAgbGV0IHN1YkNvbnRleHQgPSB0aGlzXG4gIGlmIChjb250ZXh0LnJlcGVhdCAmJiAhY29udGV4dC5zaG93bikge1xuICAgIHN1YkNvbnRleHQgPSB0aGlzLl9tZXJnZUNvbnRleHQoY29udGV4dC5yZXBlYXQpXG4gIH1cblxuICBpZiAoIWNvbnRleHQuaGFzT3duUHJvcGVydHkoJ3Nob3duJykgJiYgdGFyZ2V0LnNob3duKSB7XG4gICAgY29uc3QgZGlzcGxheSA9IHRhcmdldC5zaG93bi5jYWxsKHN1YkNvbnRleHQpXG4gICAgY29uc3QgbmV3Q29udGV4dCA9IHtzaG93bjogdHJ1ZX1cbiAgICBjb25zdCBmcmFnQmxvY2sgPSBzdWJDb250ZXh0Ll9jcmVhdGVCbG9jayhwYXJlbnRFbClcblxuICAgIGlmIChwYXJlbnRFbC5lbGVtZW50ICYmIHBhcmVudEVsLmNoaWxkcmVuKSB7XG4gICAgICBwYXJlbnRFbC5jaGlsZHJlbi5wdXNoKGZyYWdCbG9jaylcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dC5yZXBlYXQpIHtcbiAgICAgIG5ld0NvbnRleHQucmVwZWF0ID0gY29udGV4dC5yZXBlYXRcbiAgICB9XG5cbiAgICBmcmFnQmxvY2suZGlzcGxheSA9ICEhZGlzcGxheVxuICAgIHN1YkNvbnRleHQuX2NoZWNrRGlzcGxheSh0YXJnZXQsIGZyYWdCbG9jaywgbmV3Q29udGV4dClcblxuICAgIGlmIChkaXNwbGF5KSB7XG4gICAgICBzdWJDb250ZXh0Ll9nZW5lcmF0ZSh0YXJnZXQsIGZyYWdCbG9jaywgbmV3Q29udGV4dClcbiAgICB9XG5cbiAgICByZXR1cm5cbiAgfVxuXG4gIGxldCB0eXBlR2V0dGVyID0gdGFyZ2V0LnR5cGVcbiAgbGV0IHR5cGUgPSB0eXBlR2V0dGVyXG5cbiAgaWYgKHR5cGVvZiB0eXBlR2V0dGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdHlwZSA9IHR5cGVHZXR0ZXIuY2FsbChzdWJDb250ZXh0KVxuXG4gICAgaWYgKCFjb250ZXh0Lmhhc093blByb3BlcnR5KCd0eXBlJykpIHtcbiAgICAgIGNvbnN0IG5ld0NvbnRleHQgPSB7dHlwZTogdHlwZX1cbiAgICAgIGNvbnN0IGZyYWdCbG9jayA9IHN1YkNvbnRleHQuX2NyZWF0ZUJsb2NrKHBhcmVudEVsKVxuXG4gICAgICBpZiAocGFyZW50RWwuZWxlbWVudCAmJiBwYXJlbnRFbC5jaGlsZHJlbikge1xuICAgICAgICBwYXJlbnRFbC5jaGlsZHJlbi5wdXNoKGZyYWdCbG9jaylcbiAgICAgIH1cblxuICAgICAgc3ViQ29udGV4dC5fd2F0Y2godHlwZUdldHRlciwgKHZhbHVlKSA9PiB7XG4gICAgICAgIHN1YkNvbnRleHQuX3JlbW92ZUJsb2NrKGZyYWdCbG9jaywgdHJ1ZSlcbiAgICAgICAgc3ViQ29udGV4dC5fZ2VuZXJhdGUodGFyZ2V0LCBmcmFnQmxvY2ssIHt0eXBlOiB2YWx1ZX0pXG4gICAgICB9KVxuXG4gICAgICBzdWJDb250ZXh0Ll9nZW5lcmF0ZSh0YXJnZXQsIGZyYWdCbG9jaywgbmV3Q29udGV4dClcblxuICAgICAgcmV0dXJuXG4gICAgfVxuICB9XG5cbiAgbGV0IGlzQ29tcG9uZW50XG4gIGlmICh0aGlzLl9hcHAgJiYgdGhpcy5fYXBwLmN1c3RvbUNvbXBvbmVudE1hcCAmJiB0eXBlKSB7XG4gICAgaXNDb21wb25lbnQgPSB0aGlzLl9hcHAuY3VzdG9tQ29tcG9uZW50TWFwW3R5cGVdXG4gIH1cbiAgZWxzZSB7XG4gICAgaXNDb21wb25lbnQgPSB0YXJnZXQuY29tcG9uZW50XG4gIH1cblxuICBpZiAoaXNDb21wb25lbnQpIHtcbiAgICBjb25zdCBWbSA9IHRoaXMuY29uc3RydWN0b3JcbiAgICBjb25zdCBzdWJWbSA9IG5ldyBWbSh0eXBlLCBzdWJDb250ZXh0LCBwYXJlbnRFbCwgdW5kZWZpbmVkLCB7XG4gICAgICAnaG9vazppbml0JzogZnVuY3Rpb24gKCkge1xuICAgICAgICBzdWJDb250ZXh0Ll9zZXRJZCh0YXJnZXQuaWQsIG51bGwsIHRoaXMpXG4gICAgICB9LFxuICAgICAgJ2hvb2s6Y3JlYXRlZCc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc3ViQ29udGV4dC5fYmluZFN1YlZtKHRoaXMsIHRhcmdldCwgY29udGV4dC5yZXBlYXQpXG4gICAgICB9LFxuICAgICAgJ2hvb2s6cmVhZHknOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9jb250ZW50KSB7XG4gICAgICAgICAgc3ViQ29udGV4dC5fc2V0Q2hpbGRyZW4odGFyZ2V0LCB0aGlzLl9jb250ZW50KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgICBzdWJDb250ZXh0Ll9iaW5kU3ViVm1BZnRlckluaXRpYWxpemVkKHN1YlZtLCB0YXJnZXQpXG4gICAgcmV0dXJuXG4gIH1cblxuICBjb25zdCBlbGVtZW50ID0gc3ViQ29udGV4dC5fZ2VuZXJhdGVFbGVtZW50KHR5cGUsIHRhcmdldCwgcGFyZW50RWwpXG4gIGNvbnN0IHRyZWVNb2RlID0gdGFyZ2V0LmFwcGVuZCA9PT0gJ3RyZWUnXG4gIGlmICghdHJlZU1vZGUpIHtcbiAgICBzdWJDb250ZXh0Ll9hdHRhY2hUYXJnZXQoZWxlbWVudCwgcGFyZW50RWwpXG4gIH1cbiAgc3ViQ29udGV4dC5fc2V0Q2hpbGRyZW4odGFyZ2V0LCBlbGVtZW50KVxuICBpZiAodHJlZU1vZGUpIHtcbiAgICBzdWJDb250ZXh0Ll9hdHRhY2hUYXJnZXQoZWxlbWVudCwgcGFyZW50RWwpXG4gIH1cbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBlbGVtZW50IGZyb20gdGVtcGxhdGUgYW5kIGF0dGFjaCB0byB0aGUgZGVzdCBpZiBuZWVkZWQuXG4gKiBUaGUgdGltZSB0byBhdHRhY2ggZGVwZW5kcyBvbiB3aGV0aGVyIHRoZSBtb2RlIHN0YXR1cyBpcyBub2RlIG9yIHRyZWUuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSB0ZW1wbGF0ZVxuICogQHBhcmFtICB7b2JqZWN0fSBkZXN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfZ2VuZXJhdGVFbGVtZW50KHR5cGUsIHRlbXBsYXRlLCBkZXN0KSB7XG5cbiAgdGhpcy5fYXBwbHlOYWl0dmVDb21wb25lbnRPcHRpb25zKHRlbXBsYXRlKVxuXG4gIGxldCBlbGVtZW50XG4gIGlmIChkZXN0LnJlZiA9PT0gJ19kb2N1bWVudEVsZW1lbnQnKSB7XG4gICAgLy8gaWYgaXRzIHBhcmVudCBpcyBkb2N1bWVudEVsZW1lbnQgdGhlbiBpdCdzIGEgYm9keVxuICAgIGVsZW1lbnQgPSB0aGlzLl9jcmVhdGVCb2R5KHR5cGUpXG4gIH0gZWxzZSB7XG4gICAgZWxlbWVudCA9IHRoaXMuX2NyZWF0ZUVsZW1lbnQodHlwZSlcbiAgfVxuICAvLyBUT0RPIGl0IHdhcyBhIHJvb3QgZWxlbWVudCB3aGVuIG5vdCBpbiBhIGZyYWdtZW50XG4gIGlmICghdGhpcy5fcm9vdEVsKSB7XG4gICAgdGhpcy5fcm9vdEVsID0gZWxlbWVudFxuICB9XG5cbiAgdGhpcy5fYmluZEVsZW1lbnQoZWxlbWVudCwgdGVtcGxhdGUpXG5cbiAgaWYgKHRlbXBsYXRlLmF0dHIgJiYgdGVtcGxhdGUuYXR0ci5hcHBlbmQpIHsgLy8gYmFja3dhcmQsIGFwcGVuZCBwcm9wIGluIGF0dHJcbiAgICBlbGVtZW50LmFwcGVuZCA9IHRlbXBsYXRlLmF0dHIuYXBwZW5kXG4gIH1cblxuICByZXR1cm4gZWxlbWVudFxufVxuXG4vKipcbiAqIFNldCBhbGwgY2hpbGRyZW4gdG8gYSBjZXJ0YWluIHBhcmVudCBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSB0ZW1wbGF0ZVxuICogQHBhcmFtIHtvYmplY3R9IHBhcmVudEVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc2V0Q2hpbGRyZW4odGVtcGxhdGUsIHBhcmVudEVsKSB7XG4gIGNvbnN0IGNoaWxkcmVuID0gdGVtcGxhdGUuY2hpbGRyZW5cbiAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgIGNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgICB0aGlzLl9nZW5lcmF0ZShjaGlsZCwgcGFyZW50RWwpXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIFdhdGNoIHRoZSBsaXN0IHVwZGF0ZSBhbmQgcmVmcmVzaCB0aGUgY2hhbmdlcy5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IHRhcmdldFxuICogQHBhcmFtICB7b2JqZWN0fSBmcmFnQmxvY2tcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jaGVja1JlcGVhdCh0YXJnZXQsIGZyYWdCbG9jaywgcmVwZWF0SWQsIGxhdGVzdEl0ZW1JZCkge1xuICBjb25zdCBjaGlsZHJlbiA9IGZyYWdCbG9jay5jaGlsZHJlblxuXG4gIHRoaXMuX3dhdGNoQmxvY2soZnJhZ0Jsb2NrLCB0YXJnZXQucmVwZWF0LCAncmVwZWF0JywgKHZhbHVlKSA9PiB7XG4gICAgaWYgKCFmcmFnQmxvY2spIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IG9sZENoaWxkcmVuID0gY2hpbGRyZW4uc2xpY2UoKVxuICAgIGNvbnN0IG9sZFZhbHVlID0gZnJhZ0Jsb2NrLmRhdGEuc2xpY2UoKVxuICAgIC8vIDEuIGNvbGxlY3QgYWxsIG5ldyByZWZzIHRyYWNrIGJ5XG4gICAgY29uc3QgdHJhY2tNYXAgPSB7fVxuICAgIGNvbnN0IHJldXNlZE1hcCA9IHt9XG4gICAgdmFsdWUuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgIGxldCBrZXkgPSBpdGVtW2BfX3d4X3JlcGVhdF8ke3JlcGVhdElkfV9fYF1cbiAgICAgIGlmICgha2V5KSB7XG4gICAgICAgIGtleSA9IGxhdGVzdEl0ZW1JZCsrXG4gICAgICAgIHNldFJlcGVhdEl0ZW1JZChpdGVtLCByZXBlYXRJZCwga2V5KVxuICAgICAgfVxuICAgICAgdHJhY2tNYXBba2V5XSA9IGl0ZW1cbiAgICB9KVxuXG4gICAgLy8gMi4gcmVtb3ZlIHVudXNlZCBlbGVtZW50IGZvcmVhY2ggb2xkIGl0ZW1cbiAgICBjb25zdCByZXVzZWRMaXN0ID0gW11cbiAgICBvbGRWYWx1ZS5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3Qga2V5ID0gaXRlbVtgX193eF9yZXBlYXRfJHtyZXBlYXRJZH1fX2BdXG4gICAgICBpZiAodHJhY2tNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICByZXVzZWRNYXBba2V5XSA9IHtpdGVtLCBpbmRleCwgdGFyZ2V0OiBvbGRDaGlsZHJlbltpbmRleF19XG4gICAgICAgIHJldXNlZExpc3QucHVzaChpdGVtKVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHRoaXMuX3JlbW92ZVRhcmdldChvbGRDaGlsZHJlbltpbmRleF0pXG4gICAgICB9XG4gICAgfSlcblxuICAgIC8vIDMuIGNyZWF0ZSBuZXcgZWxlbWVudCBmb3JlYWNoIG5ldyBpdGVtXG4gICAgY2hpbGRyZW4ubGVuZ3RoID0gMFxuICAgIGZyYWdCbG9jay5kYXRhID0gdmFsdWUuc2xpY2UoKVxuICAgIGZyYWdCbG9jay51cGRhdGVNYXJrID0gZnJhZ0Jsb2NrLnN0YXJ0XG5cbiAgICB2YWx1ZS5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3Qga2V5ID0gaXRlbVtgX193eF9yZXBlYXRfJHtyZXBlYXRJZH1fX2BdXG4gICAgICBjb25zdCByZXVzZWQgPSByZXVzZWRNYXBba2V5XVxuICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuICAgICAgICBpdGVtLklOREVYID0gaW5kZXhcbiAgICAgIH1cbiAgICAgIGlmIChyZXVzZWQpIHtcbiAgICAgICAgaWYgKHJldXNlZC5pdGVtID09PSByZXVzZWRMaXN0WzBdKSB7XG4gICAgICAgICAgcmV1c2VkTGlzdC5zaGlmdCgpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV1c2VkTGlzdC4kcmVtb3ZlKHJldXNlZC5pdGVtKVxuICAgICAgICAgIHRoaXMuX21vdmVUYXJnZXQocmV1c2VkLnRhcmdldCwgZnJhZ0Jsb2NrLnVwZGF0ZU1hcmssIHRydWUpXG4gICAgICAgIH1cbiAgICAgICAgY2hpbGRyZW4ucHVzaChyZXVzZWQudGFyZ2V0KVxuICAgICAgICBmcmFnQmxvY2sudXBkYXRlTWFyayA9IHJldXNlZC50YXJnZXRcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLl9nZW5lcmF0ZSh0YXJnZXQsIGZyYWdCbG9jaywge3JlcGVhdDogaXRlbX0pXG4gICAgICB9XG4gICAgfSlcblxuICAgIGRlbGV0ZSBmcmFnQmxvY2sudXBkYXRlTWFya1xuICB9KVxufVxuXG5sZXQgbGF0ZXN0UmVwZWF0SWQgPSAxXG5cbmZ1bmN0aW9uIG1hcmtMaXN0KGxpc3QsIHJlcGVhdElkKSB7XG4gIGxldCBsYXRlc3RJdGVtSWQgPSAxXG4gIGxpc3QuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgIHNldFJlcGVhdEl0ZW1JZChpdGVtLCByZXBlYXRJZCwgbGF0ZXN0SXRlbUlkKyspXG4gIH0pXG4gIHJldHVybiBsYXRlc3RJdGVtSWRcbn1cblxuZnVuY3Rpb24gc2V0UmVwZWF0SXRlbUlkKGl0ZW0sIHJlcGVhdElkLCBpdGVtSWQpIHtcbiAgY29uc3Qga2V5ID0gYF9fd3hfcmVwZWF0XyR7cmVwZWF0SWR9X19gXG4gIGlmICh0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoaXRlbSwga2V5LCB7XG4gICAgICB2YWx1ZTogaXRlbUlkXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIFdhdGNoIHRoZSBkaXNwbGF5IHVwZGF0ZSBhbmQgYWRkL3JlbW92ZSB0aGUgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IHRhcmdldFxuICogQHBhcmFtICB7b2JqZWN0fSBmcmFnQmxvY2tcbiAqIEBwYXJhbSAge29iamVjdH0gY29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2NoZWNrRGlzcGxheSh0YXJnZXQsIGZyYWdCbG9jaywgY29udGV4dCkge1xuXG4gIHRoaXMuX3dhdGNoQmxvY2soZnJhZ0Jsb2NrLCB0YXJnZXQuc2hvd24sICdzaG93bicsICh2YWx1ZSkgPT4ge1xuICAgIGlmICghZnJhZ0Jsb2NrIHx8ICEhZnJhZ0Jsb2NrLmRpc3BsYXkgPT09ICEhdmFsdWUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBmcmFnQmxvY2suZGlzcGxheSA9IHZhbHVlXG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLl9nZW5lcmF0ZSh0YXJnZXQsIGZyYWdCbG9jaywgY29udGV4dClcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLl9yZW1vdmVCbG9jayhmcmFnQmxvY2ssIHRydWUpXG4gICAgfVxuICB9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX3dhdGNoQmxvY2soZnJhZ0Jsb2NrLCBjYWxjLCB0eXBlLCBoYW5kbGVyKSB7XG4gIGNvbnN0IGRpZmZlciA9IHRoaXMgJiYgdGhpcy5fYXBwICYmIHRoaXMuX2FwcC5kaWZmZXJcbiAgY29uc3QgY29uZmlnID0ge31cbiAgY29uc3QgZGVwdGggPSAoZnJhZ0Jsb2NrLmVsZW1lbnQuZGVwdGggfHwgMCkgKyAxXG5cbiAgdGhpcy5fd2F0Y2goY2FsYywgKHZhbHVlKSA9PiB7XG4gICAgY29uZmlnLmxhdGVzdFZhbHVlID0gdmFsdWVcbiAgICBpZiAoZGlmZmVyICYmICFjb25maWcucmVjb3JkZWQpIHtcbiAgICAgIGRpZmZlci5hcHBlbmQodHlwZSwgZGVwdGgsIGZyYWdCbG9jay5ibG9ja0lkLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGxhdGVzdFZhbHVlID0gY29uZmlnLmxhdGVzdFZhbHVlXG4gICAgICAgIGhhbmRsZXIobGF0ZXN0VmFsdWUpXG4gICAgICAgIGNvbmZpZy5yZWNvcmRlZCA9IGZhbHNlXG4gICAgICAgIGNvbmZpZy5sYXRlc3RWYWx1ZSA9IHVuZGVmaW5lZFxuICAgICAgfSlcbiAgICB9XG4gICAgY29uZmlnLnJlY29yZGVkID0gdHJ1ZVxuICB9KVxufVxuXG4vKipcbiAqIENsb25lIGEgY29udGV4dCBhbmQgbWVyZ2UgY2VydGFpbiBkYXRhLlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gbWVyZ2VkRGF0YVxuICogQHJldHVybiB7b2JqZWN0fVxuICovXG5leHBvcnQgZnVuY3Rpb24gX21lcmdlQ29udGV4dChtZXJnZWREYXRhKSB7XG4gIGNvbnN0IGNvbnRleHQgPSBPYmplY3QuY3JlYXRlKHRoaXMpXG4gIGNvbnRleHQuX2RhdGEgPSBtZXJnZWREYXRhXG4gIGNvbnRleHQuX2luaXREYXRhKClcbiAgY29udGV4dC5fcmVhbFBhcmVudCA9IHRoaXNcbiAgcmV0dXJuIGNvbnRleHRcbn1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3ZtL2NvbXBpbGVyLmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBEaXJlY3RpdmUgUGFyc2VyXG4gKi9cblxuaW1wb3J0IHtiaW5kLCBleHRlbmR9IGZyb20gJy4uL3V0aWwnXG5cbmltcG9ydCBXYXRjaGVyIGZyb20gJy4vd2F0Y2hlcidcbmltcG9ydCB7bmF0aXZlQ29tcG9uZW50TWFwfSBmcm9tICcuLi9jb25maWcnXG5cbmNvbnN0IFNFVFRFUlMgPSB7XG4gIGF0dHI6ICdzZXRBdHRyJyxcbiAgc3R5bGU6ICdzZXRTdHlsZScsXG4gIGV2ZW50OiAnYWRkRXZlbnQnXG59XG5cbi8qKlxuICogYXBwbHkgdGhlIG5hdGl2ZSBjb21wb25lbnQncyBvcHRpb25zKHNwZWNpZmllZCBieSB0ZW1wbGF0ZS50eXBlKVxuICogdG8gdGhlIHRlbXBsYXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYXBwbHlOYWl0dmVDb21wb25lbnRPcHRpb25zKHRlbXBsYXRlKSB7XG4gIGNvbnN0IHt0eXBlfSA9IHRlbXBsYXRlXG4gIGNvbnN0IG9wdGlvbnMgPSBuYXRpdmVDb21wb25lbnRNYXBbdHlwZV1cblxuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnKSB7XG4gICAgZXh0ZW5kKHRlbXBsYXRlLCBvcHRpb25zKVxuICB9XG59XG5cbi8qKlxuICogYmluZCBhbGwgaWQsIGF0dHIsIGNsYXNzbmFtZXMsIHN0eWxlLCBldmVudHMgdG8gYW4gZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2JpbmRFbGVtZW50KGVsLCB0ZW1wbGF0ZSkge1xuICB0aGlzLl9zZXRJZCh0ZW1wbGF0ZS5pZCwgZWwsIHRoaXMpXG4gIHRoaXMuX3NldEF0dHIoZWwsIHRlbXBsYXRlLmF0dHIpXG4gIHRoaXMuX3NldENsYXNzKGVsLCB0ZW1wbGF0ZS5jbGFzc0xpc3QpXG4gIHRoaXMuX3NldFN0eWxlKGVsLCB0ZW1wbGF0ZS5zdHlsZSlcbiAgdGhpcy5fYmluZEV2ZW50cyhlbCwgdGVtcGxhdGUuZXZlbnRzKVxufVxuXG4vKipcbiAqIGJpbmQgYWxsIHByb3BzIHRvIHN1YiB2bSBhbmQgYmluZCBhbGwgc3R5bGUsIGV2ZW50cyB0byB0aGUgcm9vdCBlbGVtZW50XG4gKiBvZiB0aGUgc3ViIHZtIGlmIGl0IGRvZXNuJ3QgaGF2ZSBhIHJlcGxhY2VkIG11bHRpLW5vZGUgZnJhZ21lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9iaW5kU3ViVm0oc3ViVm0sIHRlbXBsYXRlLCByZXBlYXRJdGVtKSB7XG4gIHN1YlZtID0gc3ViVm0gfHwge31cbiAgdGVtcGxhdGUgPSB0ZW1wbGF0ZSB8fCB7fVxuXG4gIGNvbnN0IG9wdGlvbnMgPSBzdWJWbS5fb3B0aW9ucyB8fCB7fVxuXG4gIC8vIGJpbmQgcHJvcHNcbiAgbGV0IHByb3BzID0gb3B0aW9ucy5wcm9wc1xuXG4gIGlmIChBcnJheS5pc0FycmF5KHByb3BzKSkge1xuICAgIHByb3BzID0gcHJvcHMucmVkdWNlKChyZXN1bHQsIHZhbHVlKSA9PiB7XG4gICAgICByZXN1bHRbdmFsdWVdID0gdHJ1ZVxuICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH0sIHt9KVxuICB9XG5cbiAgbWVyZ2VQcm9wcyhyZXBlYXRJdGVtLCBwcm9wcywgdGhpcywgc3ViVm0pXG4gIG1lcmdlUHJvcHModGVtcGxhdGUuYXR0ciwgcHJvcHMsIHRoaXMsIHN1YlZtKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX2JpbmRTdWJWbUFmdGVySW5pdGlhbGl6ZWQoc3ViVm0sIHRlbXBsYXRlKSB7XG4gIG1lcmdlQ2xhc3NTdHlsZSh0ZW1wbGF0ZS5jbGFzc0xpc3QsIHRoaXMsIHN1YlZtKVxuICBtZXJnZVN0eWxlKHRlbXBsYXRlLnN0eWxlLCB0aGlzLCBzdWJWbSlcbiAgbWVyZ2VFdmVudCh0ZW1wbGF0ZS5ldmVudHMsIHRoaXMsIHN1YlZtKVxufVxuXG5mdW5jdGlvbiBtZXJnZVByb3BzKHRhcmdldCwgcHJvcHMsIHZtLCBzdWJWbSkge1xuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVyblxuICB9XG4gIGZvciAoY29uc3Qga2V5IGluIHRhcmdldCkge1xuICAgIGlmICghcHJvcHMgfHwgcHJvcHNba2V5XSkge1xuICAgICAgY29uc3QgdmFsdWUgPSB0YXJnZXRba2V5XVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHZtLl93YXRjaCh2YWx1ZSwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICBzdWJWbVtrZXldID0gdlxuICAgICAgICB9KVxuICAgICAgICBzdWJWbVtrZXldID0gcmV0dXJuVmFsdWVcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBzdWJWbVtrZXldID0gdmFsdWVcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbWVyZ2VTdHlsZSh0YXJnZXQsIHZtLCBzdWJWbSkge1xuICBmb3IgKGNvbnN0IGtleSBpbiB0YXJnZXQpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRhcmdldFtrZXldXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgcmV0dXJuVmFsdWUgPSB2bS5fd2F0Y2godmFsdWUsIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgIGlmIChzdWJWbS5fcm9vdEVsKSB7XG4gICAgICAgICAgc3ViVm0uX3Jvb3RFbC5zZXRTdHlsZShrZXksIHYpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBzdWJWbS5fcm9vdEVsLnNldFN0eWxlKGtleSwgcmV0dXJuVmFsdWUpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaWYgKHN1YlZtLl9yb290RWwpIHtcbiAgICAgICAgc3ViVm0uX3Jvb3RFbC5zZXRTdHlsZShrZXksIHZhbHVlKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtZXJnZUNsYXNzU3R5bGUodGFyZ2V0LCB2bSwgc3ViVm0pIHtcbiAgdmFyIGNzcyA9IHZtLl9vcHRpb25zICYmIHZtLl9vcHRpb25zLnN0eWxlIHx8IHt9XG5cbiAgaWYgKCFzdWJWbS5fcm9vdEVsKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBpZiAodHlwZW9mIHRhcmdldCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IHZhbHVlID0gdm0uX3dhdGNoKHRhcmdldCwgIHYgPT4ge1xuICAgICAgc2V0Q2xhc3NTdHlsZShzdWJWbS5fcm9vdEVsLCBjc3MsIHYpXG4gICAgfSlcbiAgICBzZXRDbGFzc1N0eWxlKHN1YlZtLl9yb290RWwsIGNzcywgdmFsdWUpXG4gIH0gZWxzZSBpZiAodGFyZ2V0KSB7XG4gICAgc2V0Q2xhc3NTdHlsZShzdWJWbS5fcm9vdEVsLCBjc3MsIHRhcmdldClcbiAgfVxufVxuXG5mdW5jdGlvbiBtZXJnZUV2ZW50KHRhcmdldCwgdm0sIHN1YlZtKSB7XG4gIGlmICh0YXJnZXQgJiYgc3ViVm0uX3Jvb3RFbCkge1xuICAgIGZvciAoY29uc3QgdHlwZSBpbiB0YXJnZXQpIHtcbiAgICAgIGNvbnN0IGhhbmRsZXIgPSB2bVt0YXJnZXRbdHlwZV1dXG4gICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICBzdWJWbS5fcm9vdEVsLmFkZEV2ZW50KHR5cGUsIGJpbmQoaGFuZGxlciwgdm0pKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIGJpbmQgaWQgdG8gYW4gZWxlbWVudFxuICogZWFjaCBpZCBpcyB1bmlxdWUgaW4gYSB3aG9sZSB2bVxuICovXG5leHBvcnQgZnVuY3Rpb24gX3NldElkKGlkLCBlbCwgdm0pIHtcbiAgY29uc3QgbWFwID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKG1hcCwge1xuICAgIHZtOiB7XG4gICAgICB2YWx1ZTogdm0sXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlXG4gICAgfSxcbiAgICBlbDoge1xuICAgICAgZ2V0OiAoKSA9PiBlbCB8fCB2bS5fcm9vdEVsLFxuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZVxuICAgIH1cbiAgfSlcblxuICBpZiAodHlwZW9mIGlkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3QgaGFuZGxlciA9IGlkXG4gICAgaWQgPSBoYW5kbGVyLmNhbGwodGhpcylcbiAgICBpZiAoaWQpIHtcbiAgICAgIHRoaXMuX2lkc1tpZF0gPSBtYXBcbiAgICB9XG4gICAgdGhpcy5fd2F0Y2goaGFuZGxlciwgKG5ld0lkKSA9PiB7XG4gICAgICBpZiAobmV3SWQpIHtcbiAgICAgICAgdGhpcy5faWRzW25ld0lkXSA9IG1hcFxuICAgICAgfVxuICAgIH0pXG4gIH1cbiAgZWxzZSBpZiAoaWQgJiYgdHlwZW9mIGlkID09PSAnc3RyaW5nJykge1xuICAgIHRoaXMuX2lkc1tpZF0gPSBtYXBcbiAgfVxufVxuXG4vKipcbiAqIGJpbmQgYXR0ciB0byBhbiBlbGVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc2V0QXR0cihlbCwgYXR0cikge1xuICB0aGlzLl9iaW5kRGlyKGVsLCAnYXR0cicsIGF0dHIpXG59XG5cbmZ1bmN0aW9uIHNldENsYXNzU3R5bGUoZWwsIGNzcywgY2xhc3NMaXN0KSB7XG4gIGNvbnN0IGNsYXNzU3R5bGUgPSB7fVxuICBjb25zdCBsZW5ndGggPSBjbGFzc0xpc3QubGVuZ3RoXG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHN0eWxlID0gY3NzW2NsYXNzTGlzdFtpXV1cbiAgICBpZiAoc3R5bGUpIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHN0eWxlKSB7XG4gICAgICAgIGNsYXNzU3R5bGVba2V5XSA9IHN0eWxlW2tleV1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWwuc2V0Q2xhc3NTdHlsZShjbGFzc1N0eWxlKVxufVxuXG4vKipcbiAqIGJpbmQgY2xhc3NuYW1lcyB0byBhbiBlbGVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc2V0Q2xhc3MoZWwsIGNsYXNzTGlzdCkge1xuXG4gIGlmICh0eXBlb2YgY2xhc3NMaXN0ICE9PSAnZnVuY3Rpb24nICYmICFBcnJheS5pc0FycmF5KGNsYXNzTGlzdCkpIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShjbGFzc0xpc3QpICYmICFjbGFzc0xpc3QubGVuZ3RoKSB7XG4gICAgZWwuc2V0Q2xhc3NTdHlsZSh7fSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIGNvbnN0IHN0eWxlID0gdGhpcy5fb3B0aW9ucyAmJiB0aGlzLl9vcHRpb25zLnN0eWxlIHx8IHt9XG4gIGlmICh0eXBlb2YgY2xhc3NMaXN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLl93YXRjaChjbGFzc0xpc3QsICB2ID0+IHtcbiAgICAgIHNldENsYXNzU3R5bGUoZWwsIHN0eWxlLCB2KVxuICAgIH0pXG4gICAgc2V0Q2xhc3NTdHlsZShlbCwgc3R5bGUsIHZhbHVlKVxuICB9XG4gIGVsc2Uge1xuICAgIHNldENsYXNzU3R5bGUoZWwsIHN0eWxlLCBjbGFzc0xpc3QpXG4gIH1cbn1cblxuLyoqXG4gKiBiaW5kIHN0eWxlIHRvIGFuIGVsZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9zZXRTdHlsZShlbCwgc3R5bGUpIHtcbiAgdGhpcy5fYmluZERpcihlbCwgJ3N0eWxlJywgc3R5bGUpXG59XG5cbi8qKlxuICogYWRkIGFuIGV2ZW50IHR5cGUgYW5kIGhhbmRsZXIgdG8gYW4gZWxlbWVudCBhbmQgZ2VuZXJhdGUgYSBkb20gdXBkYXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc2V0RXZlbnQoZWwsIHR5cGUsIGhhbmRsZXIpIHtcbiAgZWwuYWRkRXZlbnQodHlwZSwgYmluZChoYW5kbGVyLCB0aGlzKSlcbn1cblxuLyoqXG4gKiBhZGQgYWxsIGV2ZW50cyBvZiBhbiBlbGVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYmluZEV2ZW50cyhlbCwgZXZlbnRzKSB7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGV2ZW50cylcbiAgbGV0IGkgPSBrZXlzLmxlbmd0aFxuICB3aGlsZSAoaS0tKSB7XG4gICAgY29uc3Qga2V5ID0ga2V5c1tpXVxuICAgIGxldCBoYW5kbGVyID0gZXZlbnRzW2tleV1cbiAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBoYW5kbGVyID0gdGhpc1toYW5kbGVyXVxuICAgIH1cbiAgICB0aGlzLl9zZXRFdmVudChlbCwga2V5LCBoYW5kbGVyKVxuICB9XG59XG5cbi8qKlxuICogc2V0IGEgc2VyaWVzIG9mIG1lbWJlcnMgYXMgYSBraW5kIG9mIGFuIGVsZW1lbnRcbiAqIGZvciBleGFtcGxlOiBzdHlsZSwgYXR0ciwgLi4uXG4gKiBpZiB0aGUgdmFsdWUgaXMgYSBmdW5jdGlvbiB0aGVuIGJpbmQgdGhlIGRhdGEgY2hhbmdlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gX2JpbmREaXIoZWwsIG5hbWUsIGRhdGEpIHtcbiAgaWYgKCFkYXRhKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGRhdGEpXG4gIGxldCBpID0ga2V5cy5sZW5ndGhcbiAgd2hpbGUgKGktLSkge1xuICAgIGNvbnN0IGtleSA9IGtleXNbaV1cbiAgICBjb25zdCB2YWx1ZSA9IGRhdGFba2V5XVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IHVwZGF0ZSA9IHZhbHVlXG4gICAgICB0aGlzLl9iaW5kS2V5KGVsLCBuYW1lLCBrZXksIHVwZGF0ZSlcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBlbFtTRVRURVJTW25hbWVdXShrZXksIHZhbHVlKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIGJpbmQgZGF0YSBjaGFuZ2VzIHRvIGEgY2VydGFpbiBrZXkgdG8gYSBuYW1lIHNlcmllcyBpbiBhbiBlbGVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYmluZEtleShlbCwgbmFtZSwga2V5LCBjYWxjKSB7XG4gIGNvbnN0IG1ldGhvZE5hbWUgPSBTRVRURVJTW25hbWVdXG4gIGNvbnN0IG9iaiA9IGVsW25hbWVdXG4gIC8vIHdhdGNoIHRoZSBjYWxjLCBhbmQgcmV0dXJucyBhIHZhbHVlIGJ5IGNhbGMuY2FsbCgpXG4gIGNvbnN0IHZhbHVlID0gdGhpcy5fd2F0Y2goY2FsYywgKHZhbHVlKSA9PiB7XG4gICAgZnVuY3Rpb24gaGFuZGxlcigpIHtcbiAgICAgIGVsW21ldGhvZE5hbWVdKGtleSwgdmFsdWUpXG4gICAgfVxuICAgIGNvbnN0IGRpZmZlciA9IHRoaXMgJiYgdGhpcy5fYXBwICYmIHRoaXMuX2FwcC5kaWZmZXJcbiAgICBpZiAoZGlmZmVyKSB7XG4gICAgICBkaWZmZXIuYXBwZW5kKCdlbGVtZW50JywgZWwuZGVwdGgsIGVsLnJlZiwgaGFuZGxlcilcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBoYW5kbGVyKClcbiAgICB9XG4gIH0pXG5cbiAgZWxbbWV0aG9kTmFtZV0oa2V5LCB2YWx1ZSlcbn1cblxuLyoqXG4gKiB3YXRjaCBhIGNhbGMgZnVuY3Rpb24gYW5kIGNhbGxiYWNrIGlmIHRoZSBjYWxjIHZhbHVlIGNoYW5nZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF93YXRjaChjYWxjLCBjYWxsYmFjaykge1xuICBjb25zdCB3YXRjaGVyID0gbmV3IFdhdGNoZXIodGhpcywgY2FsYywgZnVuY3Rpb24gKHZhbHVlLCBvbGRWYWx1ZSkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnICYmIHZhbHVlID09PSBvbGRWYWx1ZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGNhbGxiYWNrKHZhbHVlKVxuICB9KVxuXG4gIHJldHVybiB3YXRjaGVyLnZhbHVlXG59XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi92bS9kaXJlY3RpdmUuanNcbiAqKi8iLCIvKipcbiAqIFRoZSBNSVQgTGljZW5zZSAoTUlUKVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE1IFl1eGkgRXZhbiBZb3VcbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuICogVEhFIFNPRlRXQVJFLlxuICovXG5cbnZhciBfID0gcmVxdWlyZSgnLi91dGlsJylcbi8vIHZhciBjb25maWcgPSByZXF1aXJlKCcuL2NvbmZpZycpXG52YXIgT2JzZXJ2ZXIgPSByZXF1aXJlKCcuL29ic2VydmVyJylcbi8vIHZhciBleHBQYXJzZXIgPSByZXF1aXJlKCcuL3BhcnNlcnMvZXhwcmVzc2lvbicpXG4vLyB2YXIgYmF0Y2hlciA9IHJlcXVpcmUoJy4vYmF0Y2hlcicpXG52YXIgdWlkID0gMFxuXG4vKipcbiAqIEEgd2F0Y2hlciBwYXJzZXMgYW4gZXhwcmVzc2lvbiwgY29sbGVjdHMgZGVwZW5kZW5jaWVzLFxuICogYW5kIGZpcmVzIGNhbGxiYWNrIHdoZW4gdGhlIGV4cHJlc3Npb24gdmFsdWUgY2hhbmdlcy5cbiAqIFRoaXMgaXMgdXNlZCBmb3IgYm90aCB0aGUgJHdhdGNoKCkgYXBpIGFuZCBkaXJlY3RpdmVzLlxuICpcbiAqIEBwYXJhbSB7VnVlfSB2bVxuICogQHBhcmFtIHtTdHJpbmd9IGV4cHJlc3Npb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNiXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogICAgICAgICAgICAgICAgIC0ge0FycmF5fSBmaWx0ZXJzXG4gKiAgICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gdHdvV2F5XG4gKiAgICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gZGVlcFxuICogICAgICAgICAgICAgICAgIC0ge0Jvb2xlYW59IHVzZXJcbiAqICAgICAgICAgICAgICAgICAtIHtGdW5jdGlvbn0gW3ByZVByb2Nlc3NdXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuXG4vLyBmdW5jdGlvbiBXYXRjaGVyICh2bSwgZXhwcmVzc2lvbiwgY2IsIG9wdGlvbnMpIHtcbmZ1bmN0aW9uIFdhdGNoZXIgKHZtLCB1cGRhdGUsIGNiKSB7XG4gIHRoaXMudm0gPSB2bVxuICB2bS5fd2F0Y2hlcnMucHVzaCh0aGlzKVxuICAvLyB0aGlzLmV4cHJlc3Npb24gPSBleHByZXNzaW9uXG4gIHRoaXMuY2IgPSBjYlxuICB0aGlzLmlkID0gKyt1aWQgLy8gdWlkIGZvciBiYXRjaGluZ1xuICB0aGlzLmFjdGl2ZSA9IHRydWVcbiAgLy8gb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgLy8gdGhpcy5kZWVwID0gISFvcHRpb25zLmRlZXBcbiAgLy8gdGhpcy51c2VyID0gISFvcHRpb25zLnVzZXJcbiAgLy8gdGhpcy50d29XYXkgPSAhIW9wdGlvbnMudHdvV2F5XG4gIC8vIHRoaXMuZmlsdGVycyA9IG9wdGlvbnMuZmlsdGVyc1xuICAvLyB0aGlzLnByZVByb2Nlc3MgPSBvcHRpb25zLnByZVByb2Nlc3NcbiAgdGhpcy5kZXBzID0gW11cbiAgdGhpcy5uZXdEZXBzID0gW11cbiAgLy8gcGFyc2UgZXhwcmVzc2lvbiBmb3IgZ2V0dGVyL3NldHRlclxuICAvLyB2YXIgcmVzID0gZXhwUGFyc2VyLnBhcnNlKGV4cHJlc3Npb24sIG9wdGlvbnMudHdvV2F5KVxuICAvLyB0aGlzLmdldHRlciA9IHJlcy5nZXRcbiAgLy8gdGhpcy5zZXR0ZXIgPSByZXMuc2V0XG4gIHRoaXMuZ2V0dGVyID0gdXBkYXRlXG4gIHRoaXMudmFsdWUgPSB0aGlzLmdldCgpXG59XG5cbnZhciBwID0gV2F0Y2hlci5wcm90b3R5cGVcblxuLyoqXG4gKiBBZGQgYSBkZXBlbmRlbmN5IHRvIHRoaXMgZGlyZWN0aXZlLlxuICpcbiAqIEBwYXJhbSB7RGVwfSBkZXBcbiAqL1xuXG5wLmFkZERlcCA9IGZ1bmN0aW9uIChkZXApIHtcbiAgdmFyIG5ld0RlcHMgPSB0aGlzLm5ld0RlcHNcbiAgdmFyIG9sZCA9IHRoaXMuZGVwc1xuICBpZiAoXy5pbmRleE9mKG5ld0RlcHMsIGRlcCkgPCAwKSB7XG4gICAgbmV3RGVwcy5wdXNoKGRlcClcbiAgICB2YXIgaSA9IF8uaW5kZXhPZihvbGQsIGRlcClcbiAgICBpZiAoaSA8IDApIHtcbiAgICAgIGRlcC5hZGRTdWIodGhpcylcbiAgICB9IGVsc2Uge1xuICAgICAgb2xkW2ldID0gbnVsbFxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEV2YWx1YXRlIHRoZSBnZXR0ZXIsIGFuZCByZS1jb2xsZWN0IGRlcGVuZGVuY2llcy5cbiAqL1xuXG5wLmdldCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5iZWZvcmVHZXQoKVxuICB2YXIgdm0gPSB0aGlzLnZtXG4gIHZhciB2YWx1ZVxuICB0cnkge1xuICAgIHZhbHVlID0gdGhpcy5nZXR0ZXIuY2FsbCh2bSwgdm0pXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpZiAoY29uZmlnLndhcm5FeHByZXNzaW9uRXJyb3JzKSB7XG4gICAgLy8gICBfLndhcm4oXG4gICAgLy8gICAgICdFcnJvciB3aGVuIGV2YWx1YXRpbmcgZXhwcmVzc2lvbiBcIicgK1xuICAgIC8vICAgICB0aGlzLmV4cHJlc3Npb24gKyAnXCI6XFxuICAgJyArIGVcbiAgICAvLyAgIClcbiAgICAvLyB9XG4gICAgXy53YXJuKCdFcnJvciB3aGVuIHVwZGF0ZVwiJylcbiAgfVxuICAvLyBcInRvdWNoXCIgZXZlcnkgcHJvcGVydHkgc28gdGhleSBhcmUgYWxsIHRyYWNrZWQgYXNcbiAgLy8gZGVwZW5kZW5jaWVzIGZvciBkZWVwIHdhdGNoaW5nXG4gIGlmICh0aGlzLmRlZXApIHtcbiAgICB0cmF2ZXJzZSh2YWx1ZSlcbiAgfVxuICBpZiAodGhpcy5wcmVQcm9jZXNzKSB7XG4gICAgdmFsdWUgPSB0aGlzLnByZVByb2Nlc3ModmFsdWUpXG4gIH1cbiAgaWYgKHRoaXMuZmlsdGVycykge1xuICAgIHZhbHVlID0gdm0uX2FwcGx5RmlsdGVycyh2YWx1ZSwgbnVsbCwgdGhpcy5maWx0ZXJzLCBmYWxzZSlcbiAgfVxuICB0aGlzLmFmdGVyR2V0KClcbiAgcmV0dXJuIHZhbHVlXG59XG5cbi8vIC8qKlxuLy8gICogU2V0IHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlIHdpdGggdGhlIHNldHRlci5cbi8vICAqXG4vLyAgKiBAcGFyYW0geyp9IHZhbHVlXG4vLyAgKi9cblxuLy8gcC5zZXQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbi8vICAgdmFyIHZtID0gdGhpcy52bVxuLy8gICBpZiAodGhpcy5maWx0ZXJzKSB7XG4vLyAgICAgdmFsdWUgPSB2bS5fYXBwbHlGaWx0ZXJzKFxuLy8gICAgICAgdmFsdWUsIHRoaXMudmFsdWUsIHRoaXMuZmlsdGVycywgdHJ1ZSlcbi8vICAgfVxuLy8gICB0cnkge1xuLy8gICAgIHRoaXMuc2V0dGVyLmNhbGwodm0sIHZtLCB2YWx1ZSlcbi8vICAgfSBjYXRjaCAoZSkge1xuLy8gICAgIC8vIGlmIChjb25maWcud2FybkV4cHJlc3Npb25FcnJvcnMpIHtcbi8vICAgICAgIF8ud2Fybihcbi8vICAgICAgICAgJ0Vycm9yIHdoZW4gZXZhbHVhdGluZyBzZXR0ZXIgXCInICtcbi8vICAgICAgICAgdGhpcy5leHByZXNzaW9uICsgJ1wiOlxcbiAgICcgKyBlXG4vLyAgICAgICApXG4vLyAgICAgLy8gfVxuLy8gICB9XG4vLyB9XG5cbi8qKlxuICogUHJlcGFyZSBmb3IgZGVwZW5kZW5jeSBjb2xsZWN0aW9uLlxuICovXG5cbnAuYmVmb3JlR2V0ID0gZnVuY3Rpb24gKCkge1xuICBPYnNlcnZlci50YXJnZXQgPSB0aGlzXG59XG5cbi8qKlxuICogQ2xlYW4gdXAgZm9yIGRlcGVuZGVuY3kgY29sbGVjdGlvbi5cbiAqL1xuXG5wLmFmdGVyR2V0ID0gZnVuY3Rpb24gKCkge1xuICBPYnNlcnZlci50YXJnZXQgPSBudWxsXG4gIHZhciBpID0gdGhpcy5kZXBzLmxlbmd0aFxuICB3aGlsZSAoaS0tKSB7XG4gICAgdmFyIGRlcCA9IHRoaXMuZGVwc1tpXVxuICAgIGlmIChkZXApIHtcbiAgICAgIGRlcC5yZW1vdmVTdWIodGhpcylcbiAgICB9XG4gIH1cbiAgdGhpcy5kZXBzID0gdGhpcy5uZXdEZXBzXG4gIHRoaXMubmV3RGVwcyA9IFtdXG59XG5cbi8qKlxuICogU3Vic2NyaWJlciBpbnRlcmZhY2UuXG4gKiBXaWxsIGJlIGNhbGxlZCB3aGVuIGEgZGVwZW5kZW5jeSBjaGFuZ2VzLlxuICovXG5cbi8vIHAudXBkYXRlID0gZnVuY3Rpb24gKCkge1xuLy8gICBpZiAoIWNvbmZpZy5hc3luYyB8fCBjb25maWcuZGVidWcpIHtcbi8vICAgICB0aGlzLnJ1bigpXG4vLyAgIH0gZWxzZSB7XG4vLyAgICAgYmF0Y2hlci5wdXNoKHRoaXMpXG4vLyAgIH1cbi8vIH1cblxuLy8gLyoqXG4vLyAgKiBCYXRjaGVyIGpvYiBpbnRlcmZhY2UuXG4vLyAgKiBXaWxsIGJlIGNhbGxlZCBieSB0aGUgYmF0Y2hlci5cbi8vICAqL1xuXG4vLyBwLnJ1biA9IGZ1bmN0aW9uICgpIHtcbnAudXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLmdldCgpXG4gICAgaWYgKFxuICAgICAgdmFsdWUgIT09IHRoaXMudmFsdWUgfHxcbiAgICAgIEFycmF5LmlzQXJyYXkodmFsdWUpIHx8XG4gICAgICB0aGlzLmRlZXBcbiAgICApIHtcbiAgICAgIHZhciBvbGRWYWx1ZSA9IHRoaXMudmFsdWVcbiAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZVxuICAgICAgdGhpcy5jYih2YWx1ZSwgb2xkVmFsdWUpXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlIHNlbGYgZnJvbSBhbGwgZGVwZW5kZW5jaWVzJyBzdWJjcmliZXIgbGlzdC5cbiAqL1xuXG5wLnRlYXJkb3duID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAvLyByZW1vdmUgc2VsZiBmcm9tIHZtJ3Mgd2F0Y2hlciBsaXN0XG4gICAgLy8gd2UgY2FuIHNraXAgdGhpcyBpZiB0aGUgdm0gaWYgYmVpbmcgZGVzdHJveWVkXG4gICAgLy8gd2hpY2ggY2FuIGltcHJvdmUgdGVhcmRvd24gcGVyZm9ybWFuY2UuXG4gICAgaWYgKCF0aGlzLnZtLl9pc0JlaW5nRGVzdHJveWVkKSB7XG4gICAgICB0aGlzLnZtLl93YXRjaGVycy4kcmVtb3ZlKHRoaXMpXG4gICAgfVxuICAgIHZhciBpID0gdGhpcy5kZXBzLmxlbmd0aFxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHRoaXMuZGVwc1tpXS5yZW1vdmVTdWIodGhpcylcbiAgICB9XG4gICAgdGhpcy5hY3RpdmUgPSBmYWxzZVxuICAgIHRoaXMudm0gPSB0aGlzLmNiID0gdGhpcy52YWx1ZSA9IG51bGxcbiAgfVxufVxuXG5cbi8qKlxuICogUmVjcnVzaXZlbHkgdHJhdmVyc2UgYW4gb2JqZWN0IHRvIGV2b2tlIGFsbCBjb252ZXJ0ZWRcbiAqIGdldHRlcnMsIHNvIHRoYXQgZXZlcnkgbmVzdGVkIHByb3BlcnR5IGluc2lkZSB0aGUgb2JqZWN0XG4gKiBpcyBjb2xsZWN0ZWQgYXMgYSBcImRlZXBcIiBkZXBlbmRlbmN5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqL1xuXG5mdW5jdGlvbiB0cmF2ZXJzZSAob2JqKSB7XG4gIHZhciBrZXksIHZhbCwgaVxuICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICB2YWwgPSBvYmpba2V5XVxuICAgIGlmIChfLmlzQXJyYXkodmFsKSkge1xuICAgICAgaSA9IHZhbC5sZW5ndGhcbiAgICAgIHdoaWxlIChpLS0pIHt0cmF2ZXJzZSh2YWxbaV0pfVxuICAgIH0gZWxzZSBpZiAoXy5pc09iamVjdCh2YWwpKSB7XG4gICAgICB0cmF2ZXJzZSh2YWwpXG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gV2F0Y2hlclxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdm0vd2F0Y2hlci5qc1xuICoqLyIsIi8qKlxuICogQGZpbGVPdmVydmlldyBEb2N1bWVudCAmIEVsZW1lbnQgSGVscGVycy5cbiAqXG4gKiByZXF1aXJlZDpcbiAqIERvY3VtZW50IzogY3JlYXRlRWxlbWVudCwgY3JlYXRlQ29tbWVudCwgZ2V0UmVmXG4gKiBFbGVtZW50IzogYXBwZW5kQ2hpbGQsIGluc2VydEJlZm9yZSwgcmVtb3ZlQ2hpbGQsIG5leHRTaWJsaW5nXG4gKi9cblxuLyoqXG4gKiBDcmVhdGUgYSBib2R5IGJ5IHR5cGVcbiAqIFVzaW5nIHRoaXMuX2FwcC5kb2NcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHR5cGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jcmVhdGVCb2R5KHR5cGUpIHtcbiAgY29uc3QgZG9jID0gdGhpcy5fYXBwLmRvY1xuICByZXR1cm4gZG9jLmNyZWF0ZUJvZHkodHlwZSlcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW4gZWxlbWVudCBieSB0eXBlXG4gKiBVc2luZyB0aGlzLl9hcHAuZG9jXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSB0eXBlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfY3JlYXRlRWxlbWVudCh0eXBlKSB7XG4gIGNvbnN0IGRvYyA9IHRoaXMuX2FwcC5kb2NcbiAgcmV0dXJuIGRvYy5jcmVhdGVFbGVtZW50KHR5cGUpXG59XG5cbi8qKlxuICogQ3JlYXRlIGFuZCByZXR1cm4gYSBmcmFnIGJsb2NrIGZvciBhbiBlbGVtZW50LlxuICogVGhlIGZyYWcgYmxvY2sgaGFzIGEgc3RhcnRlciwgZW5kZXIgYW5kIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IGVsZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jcmVhdGVCbG9jayhlbGVtZW50KSB7XG4gIGNvbnN0IHN0YXJ0ID0gdGhpcy5fY3JlYXRlQmxvY2tTdGFydCgpXG4gIGNvbnN0IGVuZCA9IHRoaXMuX2NyZWF0ZUJsb2NrRW5kKClcbiAgY29uc3QgYmxvY2tJZCA9IGxhc3Rlc3RCbG9ja0lkKytcbiAgaWYgKGVsZW1lbnQuZWxlbWVudCkge1xuICAgIGVsZW1lbnQuZWxlbWVudC5pbnNlcnRCZWZvcmUoc3RhcnQsIGVsZW1lbnQuZW5kKVxuICAgIGVsZW1lbnQuZWxlbWVudC5pbnNlcnRCZWZvcmUoZW5kLCBlbGVtZW50LmVuZClcbiAgICBlbGVtZW50ID0gZWxlbWVudC5lbGVtZW50XG4gIH1cbiAgZWxzZSB7XG4gICAgZWxlbWVudC5hcHBlbmRDaGlsZChzdGFydClcbiAgICBlbGVtZW50LmFwcGVuZENoaWxkKGVuZClcbiAgfVxuICByZXR1cm4ge3N0YXJ0LCBlbmQsIGVsZW1lbnQsIGJsb2NrSWR9XG59XG5cbmxldCBsYXN0ZXN0QmxvY2tJZCA9IDFcblxuLyoqXG4gKiBDcmVhdGUgYW5kIHJldHVybiBhIGJsb2NrIHN0YXJ0ZXIuXG4gKiBVc2luZyB0aGlzLl9hcHAuZG9jXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfY3JlYXRlQmxvY2tTdGFydCgpIHtcbiAgY29uc3QgZG9jID0gdGhpcy5fYXBwLmRvY1xuICBjb25zdCBhbmNob3IgPSBkb2MuY3JlYXRlQ29tbWVudCgnc3RhcnQnKVxuICByZXR1cm4gYW5jaG9yXG59XG5cbi8qKlxuICogQ3JlYXRlIGFuZCByZXR1cm4gYSBibG9jayBlbmRlci5cbiAqIFVzaW5nIHRoaXMuX2FwcC5kb2NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jcmVhdGVCbG9ja0VuZCgpIHtcbiAgY29uc3QgZG9jID0gdGhpcy5fYXBwLmRvY1xuICBjb25zdCBhbmNob3IgPSBkb2MuY3JlYXRlQ29tbWVudCgnZW5kJylcbiAgcmV0dXJuIGFuY2hvclxufVxuXG4vKipcbiAqIEF0dGFjaCB0YXJnZXQgdG8gYSBjZXJ0YWluIGRlc3QgdXNpbmcgYXBwZW5kQ2hpbGQgYnkgZGVmYXVsdC5cbiAqIElmIHRoZSBkZXN0IGlzIGEgZnJhZyBibG9jayB0aGVuIGluc2VydCBiZWZvcmUgdGhlIGVuZGVyLlxuICogSWYgdGhlIHRhcmdldCBpcyBhIGZyYWcgYmxvY2sgdGhlbiBhdHRhY2ggdGhlIHN0YXJ0ZXIgYW5kIGVuZGVyIGluIG9yZGVyLlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0gIHtvYmplY3R9IGRlc3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9hdHRhY2hUYXJnZXQodGFyZ2V0LCBkZXN0KSB7XG5cbiAgaWYgKGRlc3QuZWxlbWVudCkge1xuICAgIGNvbnN0IGJlZm9yZSA9IGRlc3QuZW5kXG4gICAgY29uc3QgYWZ0ZXIgPSBkZXN0LnVwZGF0ZU1hcmtcbiAgICAvLyBwdXNoIG5ldyB0YXJnZXQgZm9yIHdhdGNoIGxpc3QgdXBkYXRlIGxhdGVyXG4gICAgaWYgKGRlc3QuY2hpbGRyZW4pIHtcbiAgICAgIGRlc3QuY2hpbGRyZW4ucHVzaCh0YXJnZXQpXG4gICAgfVxuICAgIC8vIGZvciBjaGVjayByZXBlYXQgY2FzZVxuICAgIGlmIChhZnRlcikge1xuICAgICAgdGhpcy5fbW92ZVRhcmdldCh0YXJnZXQsIGFmdGVyKVxuICAgICAgZGVzdC51cGRhdGVNYXJrID0gdGFyZ2V0LmVsZW1lbnQgPyB0YXJnZXQuZW5kIDogdGFyZ2V0XG4gICAgfVxuICAgIGVsc2UgaWYgKHRhcmdldC5lbGVtZW50KSB7XG4gICAgICBkZXN0LmVsZW1lbnQuaW5zZXJ0QmVmb3JlKHRhcmdldC5zdGFydCwgYmVmb3JlKVxuICAgICAgZGVzdC5lbGVtZW50Lmluc2VydEJlZm9yZSh0YXJnZXQuZW5kLCBiZWZvcmUpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgZGVzdC5lbGVtZW50Lmluc2VydEJlZm9yZSh0YXJnZXQsIGJlZm9yZSlcbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYgKHRhcmdldC5lbGVtZW50KSB7XG4gICAgICBkZXN0LmFwcGVuZENoaWxkKHRhcmdldC5zdGFydClcbiAgICAgIGRlc3QuYXBwZW5kQ2hpbGQodGFyZ2V0LmVuZClcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBkZXN0LmFwcGVuZENoaWxkKHRhcmdldClcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNb3ZlIHRhcmdldCBiZWZvcmUgYSBjZXJ0YWluIGVsZW1lbnQuIFRoZSB0YXJnZXQgbWF5YmUgYmxvY2sgb3IgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IHRhcmdldFxuICogQHBhcmFtICB7b2JqZWN0fSBiZWZvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9tb3ZlVGFyZ2V0KHRhcmdldCwgYWZ0ZXIpIHtcbiAgaWYgKHRhcmdldC5lbGVtZW50KSB7XG4gICAgdGhpcy5fbW92ZUJsb2NrKHRhcmdldCwgYWZ0ZXIpXG4gIH1cbiAgZWxzZSB7XG4gICAgdGhpcy5fbW92ZUVsZW1lbnQodGFyZ2V0LCBhZnRlcilcbiAgfVxufVxuXG4vKipcbiAqIE1vdmUgZWxlbWVudCBiZWZvcmUgYSBjZXJ0YWluIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSBlbGVtZW50XG4gKiBAcGFyYW0gIHtvYmplY3R9IGJlZm9yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX21vdmVFbGVtZW50KGVsZW1lbnQsIGFmdGVyKSB7XG4gIGNvbnN0IGRvYyA9IHRoaXMuX2FwcC5kb2NcbiAgY29uc3QgcGFyZW50ID0gZG9jLmdldFJlZihhZnRlci5wYXJlbnRSZWYpXG5cbiAgaWYgKHBhcmVudCkge1xuICAgIHBhcmVudC5pbnNlcnRBZnRlcihlbGVtZW50LCBhZnRlcilcbiAgfVxufVxuXG4vKipcbiAqIE1vdmUgYWxsIGVsZW1lbnRzIG9mIHRoZSBibG9jayBiZWZvcmUgYSBjZXJ0YWluIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSBmcmFnQmxvY2tcbiAqIEBwYXJhbSAge29iamVjdH0gYmVmb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfbW92ZUJsb2NrKGZyYWdCbG9jaywgYWZ0ZXIpIHtcbiAgY29uc3QgZG9jID0gdGhpcy5fYXBwLmRvY1xuICBjb25zdCBwYXJlbnQgPSBkb2MuZ2V0UmVmKGFmdGVyLnBhcmVudFJlZilcblxuICBpZiAocGFyZW50KSB7XG4gICAgbGV0IGVsID0gZnJhZ0Jsb2NrLnN0YXJ0XG4gICAgY29uc3QgZ3JvdXAgPSBbZWxdXG5cbiAgICB3aGlsZSAoZWwgJiYgZWwgIT09IGZyYWdCbG9jay5lbmQpIHtcbiAgICAgIGVsID0gZWwubmV4dCgpXG4gICAgICBncm91cC5wdXNoKGVsKVxuICAgIH1cblxuICAgIGxldCB0ZW1wID0gYWZ0ZXJcbiAgICBncm91cC5mb3JFYWNoKChlbCkgPT4ge1xuICAgICAgcGFyZW50Lmluc2VydEFmdGVyKGVsLCB0ZW1wKVxuICAgICAgdGVtcCA9IGVsXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIFJlbW92ZSB0YXJnZXQgZnJvbSBET00gdHJlZS5cbiAqIElmIHRoZSB0YXJnZXQgaXMgYSBmcmFnIGJsb2NrIHRoZW4gY2FsbCBfcmVtb3ZlQmxvY2tcbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IHRhcmdldFxuICovXG5leHBvcnQgZnVuY3Rpb24gX3JlbW92ZVRhcmdldCh0YXJnZXQpIHtcblxuICBpZiAodGFyZ2V0LmVsZW1lbnQpIHtcbiAgICB0aGlzLl9yZW1vdmVCbG9jayh0YXJnZXQpXG4gIH1cbiAgZWxzZSB7XG4gICAgdGhpcy5fcmVtb3ZlRWxlbWVudCh0YXJnZXQpXG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgYSBjZXJ0YWluIGVsZW1lbnQuXG4gKiBVc2luZyB0aGlzLl9hcHAuZG9jXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSB0YXJnZXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9yZW1vdmVFbGVtZW50KHRhcmdldCkge1xuICBjb25zdCBkb2MgPSB0aGlzLl9hcHAuZG9jXG4gIGNvbnN0IHBhcmVudCA9IGRvYy5nZXRSZWYodGFyZ2V0LnBhcmVudFJlZilcblxuICBpZiAocGFyZW50KSB7XG4gICAgcGFyZW50LnJlbW92ZUNoaWxkKHRhcmdldClcbiAgfVxufVxuXG4vKipcbiAqIFJlbW92ZSBhIGZyYWcgYmxvY2suXG4gKiBUaGUgc2Vjb25kIHBhcmFtIGRlY2lkZXMgd2hldGhlciB0aGUgYmxvY2sgc2VsZiBzaG91bGQgYmUgcmVtb3ZlZCB0b28uXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSAgZnJhZ0Jsb2NrXG4gKiBAcGFyYW0gIHtCb29sZWFufSBwcmVzZXJ2ZUJsb2NrPWZhbHNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfcmVtb3ZlQmxvY2soZnJhZ0Jsb2NrLCBwcmVzZXJ2ZUJsb2NrID0gZmFsc2UpIHtcbiAgY29uc3QgcmVzdWx0ID0gW11cbiAgbGV0IGVsID0gZnJhZ0Jsb2NrLnN0YXJ0Lm5leHQoKVxuXG4gIHdoaWxlIChlbCAmJiBlbCAhPT0gZnJhZ0Jsb2NrLmVuZCkge1xuICAgIHJlc3VsdC5wdXNoKGVsKVxuICAgIGVsID0gZWwubmV4dCgpXG4gIH1cblxuICBpZiAoIXByZXNlcnZlQmxvY2spIHtcbiAgICB0aGlzLl9yZW1vdmVFbGVtZW50KGZyYWdCbG9jay5zdGFydClcbiAgfVxuICByZXN1bHQuZm9yRWFjaCgoZWwpID0+IHtcbiAgICB0aGlzLl9yZW1vdmVFbGVtZW50KGVsKVxuICB9KVxuICBpZiAoIXByZXNlcnZlQmxvY2spIHtcbiAgICB0aGlzLl9yZW1vdmVFbGVtZW50KGZyYWdCbG9jay5lbmQpXG4gIH1cbn1cblxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvdm0vZG9tLWhlbHBlci5qc1xuICoqLyIsImZ1bmN0aW9uIEV2dCh0eXBlLCBkZXRhaWwpIHtcbiAgaWYgKGRldGFpbCBpbnN0YW5jZW9mIEV2dCkge1xuICAgIHJldHVybiBkZXRhaWxcbiAgfVxuXG4gIHRoaXMudGltZXN0YW1wID0gRGF0ZS5ub3coKVxuICB0aGlzLmRldGFpbCA9IGRldGFpbFxuICB0aGlzLnR5cGUgPSB0eXBlXG5cbiAgbGV0IHNob3VsZFN0b3AgPSBmYWxzZVxuICB0aGlzLnN0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgc2hvdWxkU3RvcCA9IHRydWVcbiAgfVxuICB0aGlzLmhhc1N0b3BwZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHNob3VsZFN0b3BcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gJGVtaXQodHlwZSwgZGV0YWlsKSB7XG4gIGNvbnN0IGV2ZW50cyA9IHRoaXMuX3ZtRXZlbnRzXG4gIGNvbnN0IGhhbmRsZXJMaXN0ID0gZXZlbnRzW3R5cGVdXG4gIGlmIChoYW5kbGVyTGlzdCkge1xuICAgIGxldCBldnQgPSBuZXcgRXZ0KHR5cGUsIGRldGFpbClcbiAgICBoYW5kbGVyTGlzdC5mb3JFYWNoKChoYW5kbGVyKSA9PiB7XG4gICAgICBoYW5kbGVyLmNhbGwodGhpcywgZXZ0KVxuICAgIH0pXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uICRkaXNwYXRjaCh0eXBlLCBkZXRhaWwpIHtcbiAgY29uc3QgZXZ0ID0gbmV3IEV2dCh0eXBlLCBkZXRhaWwpXG4gIHRoaXMuJGVtaXQodHlwZSwgZXZ0KVxuXG4gIGlmICghZXZ0Lmhhc1N0b3BwZWQoKSAmJiB0aGlzLl9wYXJlbnQgJiYgdGhpcy5fcGFyZW50LiRkaXNwYXRjaCkge1xuICAgIHRoaXMuX3BhcmVudC4kZGlzcGF0Y2godHlwZSwgZXZ0KVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiAkYnJvYWRjYXN0KHR5cGUsIGRldGFpbCkge1xuICBjb25zdCBldnQgPSBuZXcgRXZ0KHR5cGUsIGRldGFpbClcbiAgdGhpcy4kZW1pdCh0eXBlLCBldnQpXG5cbiAgaWYgKCFldnQuaGFzU3RvcHBlZCgpICYmIHRoaXMuX2NoaWxkcmVuVm1zKSB7XG4gICAgdGhpcy5fY2hpbGRyZW5WbXMuZm9yRWFjaCgoc3ViVm0pID0+IHtcbiAgICAgIHN1YlZtLiRicm9hZGNhc3QodHlwZSwgZXZ0KVxuICAgIH0pXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uICRvbih0eXBlLCBoYW5kbGVyKSB7XG4gIGlmICghdHlwZSB8fCB0eXBlb2YgaGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IGV2ZW50cyA9IHRoaXMuX3ZtRXZlbnRzXG4gIGNvbnN0IGhhbmRsZXJMaXN0ID0gZXZlbnRzW3R5cGVdIHx8IFtdXG4gIGhhbmRsZXJMaXN0LnB1c2goaGFuZGxlcilcbiAgZXZlbnRzW3R5cGVdID0gaGFuZGxlckxpc3RcblxuICAvLyBmaXhlZCBvbGQgdmVyc2lvbiBsaWZlY3ljbGUgZGVzaWduXG4gIGlmICh0eXBlID09PSAnaG9vazpyZWFkeScgJiYgdGhpcy5fcmVhZHkpIHtcbiAgICB0aGlzLiRlbWl0KCdob29rOnJlYWR5JylcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gJG9mZih0eXBlLCBoYW5kbGVyKSB7XG4gIGlmICghdHlwZSkge1xuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IGV2ZW50cyA9IHRoaXMuX3ZtRXZlbnRzXG4gIGlmICghaGFuZGxlcikge1xuICAgIGRlbGV0ZSBldmVudHNbdHlwZV1cbiAgICByZXR1cm5cbiAgfVxuICBjb25zdCBoYW5kbGVyTGlzdCA9IGV2ZW50c1t0eXBlXVxuICBpZiAoIWhhbmRsZXJMaXN0KSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgaGFuZGxlckxpc3QuJHJlbW92ZShoYW5kbGVyKVxufVxuXG5jb25zdCBMSUZFX0NZQ0xFX1RZUEVTID0gWydpbml0JywgJ2NyZWF0ZWQnLCAncmVhZHknXVxuXG5leHBvcnQgZnVuY3Rpb24gX2luaXRFdmVudHMoZXh0ZXJuYWxFdmVudHMpIHtcbiAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuX29wdGlvbnMgfHwge31cbiAgY29uc3QgZXZlbnRzID0gb3B0aW9ucy5ldmVudHMgfHwge31cbiAgZm9yIChjb25zdCB0eXBlMSBpbiBldmVudHMpIHtcbiAgICB0aGlzLiRvbih0eXBlMSwgZXZlbnRzW3R5cGUxXSlcbiAgfVxuICBmb3IgKGNvbnN0IHR5cGUyIGluIGV4dGVybmFsRXZlbnRzKSB7XG4gICAgdGhpcy4kb24odHlwZTIsIGV4dGVybmFsRXZlbnRzW3R5cGUyXSlcbiAgfVxuICBMSUZFX0NZQ0xFX1RZUEVTLmZvckVhY2goKHR5cGUpID0+IHtcbiAgICB0aGlzLiRvbihgaG9vazoke3R5cGV9YCwgb3B0aW9uc1t0eXBlXSlcbiAgfSlcbn1cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL3ZtL2V2ZW50cy5qc1xuICoqLyIsImxldCBuYXRpdmVNb2R1bGVzID0ge31cblxuZnVuY3Rpb24gYXNzaWduTW9kdWxlcyhtb2R1bGVzLCBpZlJlcGxhY2UpIHtcblxuICBmb3IgKGNvbnN0IG1vZHVsZU5hbWUgaW4gbW9kdWxlcykge1xuXG4gICAgLy8gaW5pdCBgbW9kdWxlc1ttb2R1bGVOYW1lXVtdYFxuICAgIGxldCBtZXRob2RzID0gbmF0aXZlTW9kdWxlc1ttb2R1bGVOYW1lXVxuICAgIGlmICghbWV0aG9kcykge1xuICAgICAgbWV0aG9kcyA9IHt9XG4gICAgICBuYXRpdmVNb2R1bGVzW21vZHVsZU5hbWVdID0gbWV0aG9kc1xuICAgIH1cblxuICAgIC8vIHB1c2ggZWFjaCBub24tZXhpc3RlZCBuZXcgbWV0aG9kXG4gICAgbW9kdWxlc1ttb2R1bGVOYW1lXS5mb3JFYWNoKGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgIGlmICh0eXBlb2YgbWV0aG9kID09PSAnc3RyaW5nJykge1xuICAgICAgICBtZXRob2QgPSB7XG4gICAgICAgICAgbmFtZTogbWV0aG9kXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFtZXRob2RzW21ldGhvZC5uYW1lXSB8fCBpZlJlcGxhY2UpIHtcbiAgICAgICAgbWV0aG9kc1ttZXRob2QubmFtZV0gPSBtZXRob2RcbiAgICAgIH1cbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2lnbkFwaXMoQ3RvciwgYXBpcykge1xuICBjb25zdCBwID0gQ3Rvci5wcm90b3R5cGVcblxuICBmb3IgKGNvbnN0IGFwaU5hbWUgaW4gYXBpcykge1xuICAgIGlmICghcC5oYXNPd25Qcm9wZXJ0eShhcGlOYW1lKSkge1xuICAgICAgcFthcGlOYW1lXSA9IGFwaXNbYXBpTmFtZV1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyTW9kdWxlcygpIHtcbiAgbmF0aXZlTW9kdWxlcyA9IHt9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNb2R1bGUobW9kdWxlTmFtZSkge1xuICByZXR1cm4gbmF0aXZlTW9kdWxlc1ttb2R1bGVOYW1lXVxufVxuXG4vKipcbiAqIEBjb250ZXh0IGEgaW5zdGFuY2Ugb2YgQXBwSW5zdGFuY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVNb2R1bGUobW9kdWxlTmFtZSkge1xuICBjb25zdCBtZXRob2RzID0gbmF0aXZlTW9kdWxlc1ttb2R1bGVOYW1lXVxuICBjb25zdCB0YXJnZXQgPSB7fVxuXG4gIGZvciAoY29uc3QgbWV0aG9kTmFtZSBpbiBtZXRob2RzKSB7XG4gICAgdGFyZ2V0W21ldGhvZE5hbWVdID0gKC4uLmFyZ3MpID0+IHRoaXMuY2FsbFRhc2tzKHtcbiAgICAgIG1vZHVsZTogbW9kdWxlTmFtZSxcbiAgICAgIG1ldGhvZDogbWV0aG9kTmFtZSxcbiAgICAgIGFyZ3M6IGFyZ3NcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldFxufVxuXG4vKipcbiAqIEBjb250ZXh0IFZtXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3Rlck1vZHVsZXMobW9kdWxlcywgaWZSZXBsYWNlKSB7XG4gIGFzc2lnbk1vZHVsZXMobW9kdWxlcywgaWZSZXBsYWNlKVxufVxuXG4vKipcbiAqIEBjb250ZXh0IFZtXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3Rlck1ldGhvZHMoYXBpcykge1xuICBhc3NpZ25BcGlzKHRoaXMsIGFwaXMpXG59XG5cbi8qKlxuICogQGNvbnRleHQgYSBpbnN0YW5jZSBvZiBBcHBJbnN0YW5jZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUNvbXBvbmVudChuYW1lKSB7XG4gIGNvbnN0IHtjdXN0b21Db21wb25lbnRNYXB9ID0gdGhpc1xuICByZXR1cm4gY3VzdG9tQ29tcG9uZW50TWFwW25hbWVdXG59XG5cbi8qKlxuICogQGNvbnRleHQgYSBpbnN0YW5jZSBvZiBBcHBJbnN0YW5jZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJDb21wb25lbnQobmFtZSwgZXhwb3J0cykge1xuICBjb25zdCB7Y3VzdG9tQ29tcG9uZW50TWFwfSA9IHRoaXNcblxuICBpZiAoY3VzdG9tQ29tcG9uZW50TWFwW25hbWVdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBkZWZpbmUgYSBjb21wb25lbnQoJHtuYW1lfSkgdGhhdCBhbHJlYWR5IGV4aXN0c2ApXG4gIH1cblxuICBjdXN0b21Db21wb25lbnRNYXBbbmFtZV0gPSBleHBvcnRzXG59XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL3JlZ2lzdGVyLmpzXG4gKiovIiwiaW1wb3J0IHNlbXZlciBmcm9tICdzZW12ZXInXG5pbXBvcnQge2V4dGVuZCwgaXNQbGFpbk9iamVjdCwgdHlwb2Z9ICBmcm9tICcuLi91dGlsJ1xuXG4vKipcbiAqIFtub3JtYWxpemVWZXJzaW9uIGRlc2NyaXB0aW9uXVxuICogQHBhcmFtICB7U3RyaW5nfSBWZXJzaW9uLiBpZTogMSwgMS4wLCAxLjAuMFxuICogQHJldHVybiB7U3RyaW5nfSBWZXJzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVWZXJzaW9uICh2KSB7XG4gIGNvbnN0IGlzVmFsaWQgPSBzZW12ZXIudmFsaWQodikgPyB0cnVlIDogZmFsc2VcbiAgaWYgKGlzVmFsaWQpIHtcbiAgICByZXR1cm4gdlxuICB9XG5cbiAgdiA9IHR5cGVvZiAodikgPT09ICdzdHJpbmcnID8gdiA6ICcnXG4gIGNvbnN0IHNwbGl0ID0gdi5zcGxpdCgnLicpXG4gIGxldCBpID0gMFxuICBsZXQgcmVzdWx0ID0gW11cblxuICB3aGlsZSAoaSA8IDMpIHtcbiAgICBjb25zdCBzID0gdHlwZW9mIChzcGxpdFtpXSkgPT09ICdzdHJpbmcnICYmIHNwbGl0W2ldID8gc3BsaXRbaV0gOiAnMCdcbiAgICByZXN1bHQucHVzaChzKVxuICAgIGkrK1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdC5qb2luKCcuJylcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEVycm9yIChrZXksIHZhbCwgY3JpdGVyaWEpIHtcbiAgbGV0IHJlc3VsdCA9IHtcbiAgICBpc0Rvd25ncmFkZTogdHJ1ZSxcbiAgICBlcnJvclR5cGU6IDEsXG4gICAgY29kZTogMTAwMFxuICB9XG4gIGxldCBnZXRNc2cgPSBmdW5jdGlvbiAoa2V5LCB2YWwsIGNyaXRlcmlhKSB7XG4gICAgcmV0dXJuICdEb3duZ3JhZGVbJyArIGtleSArICddIDo6IGRldmljZUluZm8gJ1xuICAgICAgKyB2YWwgKyAnIG1hdGNoZWQgY3JpdGVyaWEgJyArIGNyaXRlcmlhXG4gIH1cbiAgY29uc3QgX2tleSA9IGtleS50b0xvd2VyQ2FzZSgpXG5cbiAgcmVzdWx0LmVycm9yTWVzc2FnZSA9IGdldE1zZyhrZXksIHZhbCwgY3JpdGVyaWEpXG5cbiAgaWYgKF9rZXkuaW5kZXhPZignb3N2ZXJzaW9uJykgPj0gMCkge1xuICAgIHJlc3VsdC5jb2RlID0gMTAwMVxuICB9ZWxzZSBpZiAoX2tleS5pbmRleE9mKCdhcHB2ZXJzaW9uJykgPj0gMCkge1xuICAgIHJlc3VsdC5jb2RlID0gMTAwMlxuICB9ZWxzZSBpZiAoX2tleS5pbmRleE9mKCd3ZWV4dmVyc2lvbicpID49IDApIHtcbiAgICByZXN1bHQuY29kZSA9IDEwMDNcbiAgfWVsc2UgaWYgKF9rZXkuaW5kZXhPZignZGV2aWNlbW9kZWwnKSA+PSAwKSB7XG4gICAgcmVzdWx0LmNvZGUgPSAxMDA0XG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8qKlxuICogV0VFWCBmcmFtZXdvcmsgaW5wdXQoZGV2aWNlSW5mbylcbiAqIHtcbiAqICAgcGxhdGZvcm06ICdpT1MnIG9yICdhbmRyb2lkJ1xuICogICBvc1ZlcnNpb246ICcxLjAuMCcgb3IgJzEuMCcgb3IgJzEnXG4gKiAgIGFwcFZlcnNpb246ICcxLjAuMCcgb3IgJzEuMCcgb3IgJzEnXG4gKiAgIHdlZXhWZXJzaW9uOiAnMS4wLjAnIG9yICcxLjAnIG9yICcxJ1xuICogICBkRGV2aWNlTW9kZWw6ICdNT0RFTF9OQU1FJ1xuICogfVxuICpcbiAqIGRvd25ncmFkZSBjb25maWcoY29uZmlnKVxuICoge1xuICogICBpb3M6IHtcbiAqICAgICBvc1ZlcnNpb246ICc+MS4wLjAnIG9yICc+PTEuMC4wJyBvciAnPDEuMC4wJyBvciAnPD0xLjAuMCcgb3IgJzEuMC4wJ1xuICogICAgIGFwcFZlcnNpb246ICc+MS4wLjAnIG9yICc+PTEuMC4wJyBvciAnPDEuMC4wJyBvciAnPD0xLjAuMCcgb3IgJzEuMC4wJ1xuICogICAgIHdlZXhWZXJzaW9uOiAnPjEuMC4wJyBvciAnPj0xLjAuMCcgb3IgJzwxLjAuMCcgb3IgJzw9MS4wLjAnIG9yICcxLjAuMCdcbiAqICAgICBkZXZpY2VNb2RlbDogWydtb2RlbEEnLCAnbW9kZWxCJywgLi4uXVxuICogICB9LFxuICogICBhbmRyb2lkOiB7XG4gKiAgICAgb3NWZXJzaW9uOiAnPjEuMC4wJyBvciAnPj0xLjAuMCcgb3IgJzwxLjAuMCcgb3IgJzw9MS4wLjAnIG9yICcxLjAuMCdcbiAqICAgICBhcHBWZXJzaW9uOiAnPjEuMC4wJyBvciAnPj0xLjAuMCcgb3IgJzwxLjAuMCcgb3IgJzw9MS4wLjAnIG9yICcxLjAuMCdcbiAqICAgICB3ZWV4VmVyc2lvbjogJz4xLjAuMCcgb3IgJz49MS4wLjAnIG9yICc8MS4wLjAnIG9yICc8PTEuMC4wJyBvciAnMS4wLjAnXG4gKiAgICAgZGV2aWNlTW9kZWw6IFsnbW9kZWxBJywgJ21vZGVsQicsIC4uLl1cbiAqICAgfVxuICogfVxuICpcbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IGRldmljZUluZm8gV2VleCBTREsgZnJhbWV3b3JrIGlucHV0XG4gKiBAcGFyYW0gIHtvYmplY3R9IGNvbmZpZyAgICAgdXNlciBpbnB1dFxuICogQHJldHVybiB7T2JqZWN0fSAgICAgICAgICAgIHsgaXNEb3duZ3JhZGU6IHRydWUvZmFsc2UsIGVycm9yTWVzc2FnZS4uLiB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGVjayAoY29uZmlnLCBkZXZpY2VJbmZvKSB7XG4gIGRldmljZUluZm8gPSBkZXZpY2VJbmZvIHx8IGdsb2JhbC5XWEVudmlyb25tZW50XG4gIGRldmljZUluZm8gPSBpc1BsYWluT2JqZWN0KGRldmljZUluZm8pID8gZGV2aWNlSW5mbyA6IHt9XG4gIGNvbmZpZyA9IGlzUGxhaW5PYmplY3QoY29uZmlnKSA/IGNvbmZpZyA6IHt9XG4gIGNvbnN0IHBsYXRmb3JtID0gZGV2aWNlSW5mby5wbGF0Zm9ybSB8fCAndW5rbm93J1xuICBjb25zdCBkUGxhdGZvcm0gPSBwbGF0Zm9ybS50b0xvd2VyQ2FzZSgpXG4gIGNvbnN0IGNPYmogPSBjb25maWdbZFBsYXRmb3JtXSB8fCB7fVxuXG4gIGxldCByZXN1bHQgPSB7XG4gICAgaXNEb3duZ3JhZGU6IGZhbHNlIC8vIGRlZmF1dGwgaXMgcGFzc1xuICB9XG5cbiAgZm9yIChsZXQgaSBpbiBkZXZpY2VJbmZvKSB7XG4gICAgY29uc3Qga2V5ID0gaVxuICAgIGNvbnN0IGtleUxvd2VyID0ga2V5LnRvTG93ZXJDYXNlKClcbiAgICBjb25zdCB2YWwgPSBkZXZpY2VJbmZvW2ldXG4gICAgY29uc3QgaXNWZXJzaW9uID0ga2V5TG93ZXIuaW5kZXhPZigndmVyc2lvbicpID49IDAgPyB0cnVlIDogZmFsc2VcbiAgICBjb25zdCBpc0RldmljZU1vZGVsID0ga2V5TG93ZXIuaW5kZXhPZignZGV2aWNlbW9kZWwnKSA+PSAwID8gdHJ1ZSA6IGZhbHNlXG4gICAgY29uc3QgY3JpdGVyaWEgPSBjT2JqW2ldXG5cbiAgICBpZiAoY3JpdGVyaWEgJiYgaXNWZXJzaW9uKSB7XG4gICAgICBjb25zdCBjID0gdGhpcy5ub3JtYWxpemVWZXJzaW9uKGNyaXRlcmlhKVxuICAgICAgY29uc3QgZCA9IHRoaXMubm9ybWFsaXplVmVyc2lvbihkZXZpY2VJbmZvW2ldKVxuXG4gICAgICBpZiAoc2VtdmVyLnNhdGlzZmllcyhkLCBjKSkge1xuICAgICAgICByZXN1bHQgPSBleHRlbmQodGhpcy5nZXRFcnJvcihrZXksIHZhbCwgY3JpdGVyaWEpKVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1lbHNlIGlmIChpc0RldmljZU1vZGVsKSB7XG4gICAgICBjb25zdCBfY3JpdGVyaWEgPSB0eXBvZihjcml0ZXJpYSkgPT09ICdhcnJheScgPyBjcml0ZXJpYSA6IFtjcml0ZXJpYV1cbiAgICAgIGlmIChfY3JpdGVyaWEuaW5kZXhPZih2YWwpID49IDApIHtcbiAgICAgICAgcmVzdWx0ID0gZXh0ZW5kKHRoaXMuZ2V0RXJyb3Ioa2V5LCB2YWwsIGNyaXRlcmlhKSlcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL2Rvd25ncmFkZS5qc1xuICoqLyIsIi8qKlxuICogQGZpbGVPdmVydmlld1xuICogaW5zdGFuY2UgY29udHJvbHMgZnJvbSBuYXRpdmVcbiAqXG4gKiAtIGluaXQgYnVuZGxlXG4gKiAtIGZpcmUgZXZlbnRcbiAqIC0gY2FsbGJhY2tcbiAqIC0gZGVzdHJveVxuICpcbiAqIGNvcnJlc3BvbmRlZCB3aXRoIHRoZSBBUEkgb2YgaW5zdGFuY2UgbWFuYWdlciAoZnJhbWV3b3JrLmpzKVxuICovXG5cbmltcG9ydCB7XG4gIGJpbmQsIGV4dGVuZFxufVxuZnJvbSAnLi4vdXRpbCdcbmltcG9ydCAqIGFzIHBlcmYgZnJvbSAnLi4vcGVyZidcbmltcG9ydCBMaXN0ZW5lciwge2NyZWF0ZUFjdGlvbn0gZnJvbSAnLi9kb20tbGlzdGVuZXInXG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0KGNvZGUsIGRhdGEpIHtcbiAgdmFyIHJlc3VsdFxuICAvLyBAc2VlOiBsaWIvYXBwL2J1bmRsZS5qc1xuICBjb25zdCBkZWZpbmUgPSBiaW5kKHRoaXMuZGVmaW5lLCB0aGlzKVxuICBjb25zdCBib290c3RyYXAgPSAobmFtZSwgY29uZmlnLCBfZGF0YSkgPT4ge1xuICAgIHJlc3VsdCA9IHRoaXMuYm9vdHN0cmFwKG5hbWUsIGNvbmZpZywgX2RhdGEgfHwgZGF0YSlcbiAgICB0aGlzLmRvYy5saXN0ZW5lci5jcmVhdGVGaW5pc2goKVxuICAgIHRoaXMuZG9jLmNsb3NlKClcbiAgfVxuXG4gIC8vIGJhY2t3YXJkKHJlZ2lzdGVyL3JlbmRlcilcbiAgY29uc3QgcmVnaXN0ZXIgPSBiaW5kKHRoaXMucmVnaXN0ZXIsIHRoaXMpXG4gIGNvbnN0IHJlbmRlciA9IChuYW1lLCBfZGF0YSkgPT4ge1xuICAgIHJlc3VsdCA9IHRoaXMuYm9vdHN0cmFwKG5hbWUsIHt9LCBfZGF0YSlcbiAgfVxuXG4gIGNvbnN0IHJlcXVpcmUgPSBuYW1lID0+IF9kYXRhID0+IHtcbiAgICByZXN1bHQgPSB0aGlzLmJvb3RzdHJhcChuYW1lLCB7fSwgX2RhdGEpXG4gIH1cblxuICBjb25zdCBkb2N1bWVudCA9IHRoaXMuZG9jXG5cbiAgcGVyZi5zdGFydCgncnVuIGJ1bmRsZScsIHRoaXMuaWQpXG5cbiAgbGV0IGZ1bmN0aW9uQm9keVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKHR5cGVvZiBjb2RlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgLy8gYGZ1bmN0aW9uICgpIHsuLi59YCAtPiBgey4uLn1gXG4gICAgLy8gbm90IHZlcnkgc3RyaWN0XG4gICAgZnVuY3Rpb25Cb2R5ID0gY29kZS50b1N0cmluZygpLnN1YnN0cigxMilcbiAgfSBlbHNlIGlmIChjb2RlKSB7XG4gICAgZnVuY3Rpb25Cb2R5ID0gY29kZS50b1N0cmluZygpXG4gIH1cblxuICBsZXQgZm4gPSBuZXcgRnVuY3Rpb24oXG4gICAgJ2RlZmluZScsXG4gICAgJ3JlcXVpcmUnLFxuICAgICdkb2N1bWVudCcsXG4gICAgJ2Jvb3RzdHJhcCcsXG4gICAgJ3JlZ2lzdGVyJyxcbiAgICAncmVuZGVyJyxcbiAgICBmdW5jdGlvbkJvZHlcbiAgKVxuXG4gIGZuKGRlZmluZSwgcmVxdWlyZSwgZG9jdW1lbnQsIGJvb3RzdHJhcCwgcmVnaXN0ZXIsIHJlbmRlcilcblxuICBwZXJmLmVuZCgncnVuIGJ1bmRsZScsIHRoaXMuaWQpXG4gIHJldHVybiByZXN1bHRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gIHRoaXMuaWQgPSAnJ1xuICB0aGlzLmV2ZW50TWFuYWdlciA9IG51bGxcbiAgdGhpcy5vcHRpb25zID0gbnVsbFxuICB0aGlzLmJsb2NrcyA9IG51bGxcbiAgdGhpcy52bSA9IG51bGxcbiAgdGhpcy5kb2MgPSBudWxsXG4gIHRoaXMuY3VzdG9tQ29tcG9uZW50TWFwID0gbnVsbFxuICB0aGlzLmNhbGxiYWNrcyA9IG51bGxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvb3RFbGVtZW50KCkge1xuICBjb25zdCBkb2MgPSB0aGlzLmRvYyB8fCB7fVxuICBjb25zdCBib2R5ID0gZG9jLmJvZHkgfHwge31cbiAgcmV0dXJuIGJvZHkudG9KU09OID8gYm9keS50b0pTT04oKSA6IHt9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVBY3Rpb25zKGFkZG9uVGFza3MpIHtcbiAgdGhpcy5kaWZmZXIuZmx1c2goKVxuICBjb25zdCB0YXNrcyA9IFtdXG4gIGlmICh0aGlzLmxpc3RlbmVyICYmIHRoaXMubGlzdGVuZXIudXBkYXRlcy5sZW5ndGgpIHtcbiAgICB0YXNrcy5wdXNoKC4uLnRoaXMubGlzdGVuZXIudXBkYXRlcylcbiAgICB0aGlzLmxpc3RlbmVyLnVwZGF0ZXMgPSBbXVxuICB9XG4gIGlmIChhZGRvblRhc2tzICYmIGFkZG9uVGFza3MubGVuZ3RoKSB7XG4gICAgdGFza3MucHVzaCguLi5hZGRvblRhc2tzKVxuICB9XG4gIGlmICh0YXNrcy5sZW5ndGgpIHtcbiAgICB0aGlzLmNhbGxUYXNrcyh0YXNrcylcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlyZUV2ZW50KHJlZiwgdHlwZSwgZSwgZG9tQ2hhbmdlcykge1xuICBpZiAoQXJyYXkuaXNBcnJheShyZWYpKSB7XG4gICAgcmVmLnNvbWUoKHJlZikgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZmlyZUV2ZW50KHJlZiwgdHlwZSwgZSkgIT09IGZhbHNlXG4gICAgfSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIGNvbnN0IGVsID0gdGhpcy5kb2MuZ2V0UmVmKHJlZilcblxuICBpZiAoZWwpIHtcbiAgICBwZXJmLnN0YXJ0KCdtYW5hZ2UgZXZlbnQnLCByZWYgKyAnLScgKyB0eXBlKVxuICAgIGUgPSBlIHx8IHt9XG4gICAgZS50eXBlID0gdHlwZVxuICAgIGUudGFyZ2V0ID0gZWxcbiAgICBlLnRpbWVzdGFtcCA9IERhdGUubm93KClcbiAgICBpZiAoZG9tQ2hhbmdlcykge1xuICAgICAgdXBkYXRlRWxlbWVudChlbCwgZG9tQ2hhbmdlcylcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5ldmVudE1hbmFnZXIuZmlyZShlbCwgdHlwZSwgZSlcbiAgICBwZXJmLmVuZCgnbWFuYWdlIGV2ZW50JywgcmVmICsgJy0nICsgdHlwZSlcbiAgICB0aGlzLnVwZGF0ZUFjdGlvbnMoKVxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIHJldHVybiBuZXcgRXJyb3IoYGludmFsaWQgZWxlbWVudCByZWZlcmVuY2UgXCIke3JlZn1cImApXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxsYmFjayhjYWxsYmFja0lkLCBkYXRhLCBpZktlZXBBbGl2ZSkge1xuICBjb25zdCBjYWxsYmFjayA9IHRoaXMuY2FsbGJhY2tzW2NhbGxiYWNrSWRdXG5cbiAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrKGRhdGEpIC8vIGRhdGEgaXMgYWxyZWFkeSBhIG9iamVjdCwgQHNlZTogbGliL2ZyYW1ld29yay5qc1xuXG4gICAgaWYgKHR5cGVvZiBpZktlZXBBbGl2ZSA9PT0gJ3VuZGVmaW5lZCcgfHwgaWZLZWVwQWxpdmUgPT09IGZhbHNlKSB7XG4gICAgICB0aGlzLmNhbGxiYWNrc1tjYWxsYmFja0lkXSA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIHRoaXMudXBkYXRlQWN0aW9ucygpXG4gICAgcmV0dXJuXG4gIH1cblxuICByZXR1cm4gbmV3IEVycm9yKGBpbnZhbGlkIGNhbGxiYWNrIGlkIFwiJHtjYWxsYmFja0lkfVwiYClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlZnJlc2hEYXRhKGRhdGEpIHtcbiAgY29uc3Qgdm0gPSB0aGlzLnZtXG5cbiAgaWYgKHZtICYmIGRhdGEpIHtcbiAgICBpZiAodHlwZW9mIHZtLnJlZnJlc2hEYXRhID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2bS5yZWZyZXNoRGF0YShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICBleHRlbmQodm0sIGRhdGEpXG4gICAgfVxuICAgIHRoaXMudXBkYXRlQWN0aW9ucyhbY3JlYXRlQWN0aW9uKCdyZWZyZXNoRmluaXNoJywgW10pXSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIHJldHVybiBuZXcgRXJyb3IoYGludmFsaWQgZGF0YSBcIiR7ZGF0YX1cImApXG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUVsZW1lbnQoZWwsIGNoYW5nZXMpIHtcbiAgY29uc3QgYXR0cnMgPSBjaGFuZ2VzLmF0dHJzIHx8IHt9XG4gIGZvciAoY29uc3QgbmFtZSBpbiBhdHRycykge1xuICAgIGVsLnNldEF0dHIobmFtZSwgYXR0cnMpXG4gIH1cbiAgY29uc3Qgc3R5bGUgPSBjaGFuZ2VzLnN0eWxlIHx8IHt9XG4gIGZvciAoY29uc3QgbmFtZSBpbiBzdHlsZSkge1xuICAgIGVsLnNldFN0eWxlKG5hbWUsIHN0eWxlW25hbWVdKVxuICB9XG59XG5cblxuXG5cbi8qKiBXRUJQQUNLIEZPT1RFUiAqKlxuICoqIC4vbGliL2FwcC9jdHJsLmpzXG4gKiovIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGlzdGVuZXIoaWQsIGhhbmRsZXIpIHtcbiAgdGhpcy5pZCA9IGlkXG4gIHRoaXMuYmF0Y2hlZCA9IGZhbHNlXG4gIHRoaXMudXBkYXRlcyA9IFtdXG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXJcbiAgfVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUuY3JlYXRlRmluaXNoID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmhhbmRsZXJcbiAgaGFuZGxlcihbY3JlYXRlQWN0aW9uKCdjcmVhdGVGaW5pc2gnLCBbXSldLCBjYWxsYmFjaylcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLmNyZWF0ZUJvZHkgPSBmdW5jdGlvbiAoZWxlbWVudCwgcmVmKSB7XG4gIGNvbnN0IGFjdGlvbnMgPSBbY3JlYXRlQWN0aW9uKCdjcmVhdGVCb2R5JywgW2VsZW1lbnQudG9KU09OKCldKV1cbiAgdGhpcy5hZGRBY3Rpb25zKGFjdGlvbnMpXG59XG5cbkxpc3RlbmVyLnByb3RvdHlwZS5hZGRFbGVtZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQsIHJlZiwgaW5kZXgpIHtcbiAgaWYgKCEoaW5kZXggPj0gMCkpIHtcbiAgICBpbmRleCA9IC0xXG4gIH1cbiAgdGhpcy5hZGRBY3Rpb25zKGNyZWF0ZUFjdGlvbignYWRkRWxlbWVudCcsIFtyZWYsIGVsZW1lbnQudG9KU09OKCksIGluZGV4XSkpXG59XG5cbkxpc3RlbmVyLnByb3RvdHlwZS5yZW1vdmVFbGVtZW50ID0gZnVuY3Rpb24gKHJlZikge1xuICBpZiAoQXJyYXkuaXNBcnJheShyZWYpKSB7XG4gICAgY29uc3QgYWN0aW9ucyA9IHJlZi5tYXAoKHIpID0+IGNyZWF0ZUFjdGlvbigncmVtb3ZlRWxlbWVudCcsIFtyXSkpXG4gICAgdGhpcy5hZGRBY3Rpb25zKGFjdGlvbnMpXG4gIH1cbiAgZWxzZSB7XG4gICAgdGhpcy5hZGRBY3Rpb25zKGNyZWF0ZUFjdGlvbigncmVtb3ZlRWxlbWVudCcsIFtyZWZdKSlcbiAgfVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUubW92ZUVsZW1lbnQgPSBmdW5jdGlvbiAodGFyZ2V0UmVmLCBwYXJlbnRSZWYsIGluZGV4KSB7XG4gIHRoaXMuYWRkQWN0aW9ucyhjcmVhdGVBY3Rpb24oJ21vdmVFbGVtZW50JywgW3RhcmdldFJlZiwgcGFyZW50UmVmLCBpbmRleF0pKVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUuc2V0QXR0ciA9IGZ1bmN0aW9uIChyZWYsIGtleSwgdmFsdWUpIHtcbiAgY29uc3QgcmVzdWx0ID0ge31cbiAgcmVzdWx0W2tleV0gPSB2YWx1ZVxuICB0aGlzLmFkZEFjdGlvbnMoY3JlYXRlQWN0aW9uKCd1cGRhdGVBdHRycycsIFtyZWYsIHJlc3VsdF0pKVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUuc2V0U3R5bGUgPSBmdW5jdGlvbiAocmVmLCBrZXksIHZhbHVlKSB7XG4gIGNvbnN0IHJlc3VsdCA9IHt9XG4gIHJlc3VsdFtrZXldID0gdmFsdWVcbiAgdGhpcy5hZGRBY3Rpb25zKGNyZWF0ZUFjdGlvbigndXBkYXRlU3R5bGUnLCBbcmVmLCByZXN1bHRdKSlcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLnNldFN0eWxlcyA9IGZ1bmN0aW9uIChyZWYsIHN0eWxlKSB7XG4gIHRoaXMuYWRkQWN0aW9ucyhjcmVhdGVBY3Rpb24oJ3VwZGF0ZVN0eWxlJywgW3JlZiwgc3R5bGVdKSlcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLmFkZEV2ZW50ID0gZnVuY3Rpb24gKHJlZiwgdHlwZSkge1xuICB0aGlzLmFkZEFjdGlvbnMoY3JlYXRlQWN0aW9uKCdhZGRFdmVudCcsIFtyZWYsIHR5cGVdKSlcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24gKHJlZiwgdHlwZSkge1xuICB0aGlzLmFkZEFjdGlvbnMoY3JlYXRlQWN0aW9uKCdyZW1vdmVFdmVudCcsIFtyZWYsIHR5cGVdKSlcbn1cblxuTGlzdGVuZXIucHJvdG90eXBlLmhhbmRsZXIgPSBmdW5jdGlvbiAoYWN0aW9ucywgY2IpIHtcbiAgY2IgJiYgY2IoKVxufVxuXG5MaXN0ZW5lci5wcm90b3R5cGUuYWRkQWN0aW9ucyA9IGZ1bmN0aW9uIChhY3Rpb25zKSB7XG4gIGNvbnN0IHVwZGF0ZXMgPSB0aGlzLnVwZGF0ZXNcbiAgY29uc3QgaGFuZGxlciA9IHRoaXMuaGFuZGxlclxuXG4gIGlmICghQXJyYXkuaXNBcnJheShhY3Rpb25zKSkge1xuICAgIGFjdGlvbnMgPSBbYWN0aW9uc11cbiAgfVxuXG4gIGlmICh0aGlzLmJhdGNoZWQpIHtcbiAgICB1cGRhdGVzLnB1c2guYXBwbHkodXBkYXRlcywgYWN0aW9ucylcbiAgfVxuICBlbHNlIHtcbiAgICBoYW5kbGVyKGFjdGlvbnMpXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFjdGlvbihuYW1lLCBhcmdzKSB7XG4gIHJldHVybiB7bW9kdWxlOiAnZG9tJywgbWV0aG9kOiBuYW1lLCBhcmdzOiBhcmdzfVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL2RvbS1saXN0ZW5lci5qc1xuICoqLyIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIERpZmZlciB7XG4gIGNvbnN0cnVjdG9yIChpZCkge1xuICAgIHRoaXMuaWQgPSBpZFxuICAgIHRoaXMubWFwID0gW11cbiAgICB0aGlzLmhvb2tzID0gW11cbiAgfVxuICBpc0VtcHR5ICgpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAubGVuZ3RoID09PSAwXG4gIH1cbiAgYXBwZW5kICh0eXBlLCBkZXB0aCwgcmVmLCBoYW5kbGVyKSB7XG4gICAgY29uc3QgbWFwID0gdGhpcy5tYXBcbiAgICBpZiAoIW1hcFtkZXB0aF0pIHtcbiAgICAgIG1hcFtkZXB0aF0gPSB7fVxuICAgIH1cbiAgICBjb25zdCBncm91cCA9IG1hcFtkZXB0aF1cbiAgICBpZiAoIWdyb3VwW3R5cGVdKSB7XG4gICAgICBncm91cFt0eXBlXSA9IHt9XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnZWxlbWVudCcpIHtcbiAgICAgIGlmICghZ3JvdXBbdHlwZV1bcmVmXSkge1xuICAgICAgICBncm91cFt0eXBlXVtyZWZdID0gW11cbiAgICAgIH1cbiAgICAgIGdyb3VwW3R5cGVdW3JlZl0ucHVzaChoYW5kbGVyKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGdyb3VwW3R5cGVdW3JlZl0gPSBoYW5kbGVyXG4gICAgfVxuICB9XG4gIGZsdXNoICgpIHtcbiAgICBjb25zdCBtYXAgPSB0aGlzLm1hcC5zbGljZSgpXG4gICAgdGhpcy5tYXAubGVuZ3RoID0gMFxuICAgIG1hcC5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgY2FsbFR5cGVNYXAoZ3JvdXAsICdyZXBlYXQnKVxuICAgICAgY2FsbFR5cGVNYXAoZ3JvdXAsICdzaG93bicpXG4gICAgICBjYWxsVHlwZUxpc3QoZ3JvdXAsICdlbGVtZW50JylcbiAgICB9KVxuXG4gICAgY29uc3QgaG9va3MgPSB0aGlzLmhvb2tzLnNsaWNlKClcbiAgICB0aGlzLmhvb2tzLmxlbmd0aCA9IDBcbiAgICBob29rcy5mb3JFYWNoKChmbikgPT4ge1xuICAgICAgZm4oKVxuICAgIH0pXG5cbiAgICBpZiAoIXRoaXMuaXNFbXB0eSgpKSB7XG4gICAgICB0aGlzLmZsdXNoKClcbiAgICB9XG4gIH1cbiAgdGhlbiAoZm4pIHtcbiAgICB0aGlzLmhvb2tzLnB1c2goZm4pXG4gIH1cbn1cblxuZnVuY3Rpb24gY2FsbFR5cGVNYXAoZ3JvdXAsIHR5cGUpIHtcbiAgY29uc3QgbWFwID0gZ3JvdXBbdHlwZV1cbiAgZm9yIChjb25zdCByZWYgaW4gbWFwKSB7XG4gICAgbWFwW3JlZl0oKVxuICB9XG59XG5cbmZ1bmN0aW9uIGNhbGxUeXBlTGlzdChncm91cCwgdHlwZSkge1xuICBjb25zdCBtYXAgPSBncm91cFt0eXBlXVxuICBmb3IgKGNvbnN0IHJlZiBpbiBtYXApIHtcbiAgICBjb25zdCBsaXN0ID0gbWFwW3JlZl1cbiAgICBsaXN0LmZvckVhY2goKGhhbmRsZXIpID0+IHtoYW5kbGVyKCl9KVxuICB9XG59XG5cblxuXG4vKiogV0VCUEFDSyBGT09URVIgKipcbiAqKiAuL2xpYi9hcHAvZGlmZmVyLmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3IGV2ZW50IG1hbmFnZXJcbiAqL1xuXG5pbXBvcnQgKiBhcyBfIGZyb20gJy4uL3V0aWwnXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEV2ZW50TWFuYWdlcigpIHtcbiAgdGhpcy5lbHMgPSBbXVxuICB0aGlzLnRhcmdldHMgPSBbXVxufVxuXG5FdmVudE1hbmFnZXIucHJvdG90eXBlLl9nZXQgPSBmdW5jdGlvbiAoZWwsIGZvcmNlKSB7XG4gIHZhciBpbmRleCA9IF8uaW5kZXhPZih0aGlzLmVscywgZWwpXG4gIHZhciB0YXJnZXRcbiAgaWYgKGluZGV4ID49IDApIHtcbiAgICB0YXJnZXQgPSB0aGlzLnRhcmdldHNbaW5kZXhdXG4gIH1cbiAgZWxzZSBpZiAoZm9yY2UpIHtcbiAgICB0YXJnZXQgPSB7ZWw6IGVsLCBldmVudHM6IHt9fVxuICAgIHRoaXMuZWxzLnB1c2goZWwpXG4gICAgdGhpcy50YXJnZXRzLnB1c2godGFyZ2V0KVxuICB9XG4gIHJldHVybiB0YXJnZXRcbn1cblxuRXZlbnRNYW5hZ2VyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoZWwsIHR5cGUsIGhhbmRsZXIpIHtcbiAgaWYgKHR5cGVvZiBlbCAhPT0gJ29iamVjdCcgfHwgIWVsIHx8XG4gICAgdHlwZW9mIHR5cGUgIT09ICdzdHJpbmcnIHx8ICF0eXBlIHx8XG4gICAgdHlwZW9mIGhhbmRsZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgdGFyZ2V0ID0gdGhpcy5fZ2V0KGVsLCB0cnVlKVxuICB0YXJnZXQuZXZlbnRzW3R5cGVdID0gaGFuZGxlclxufVxuXG5FdmVudE1hbmFnZXIucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIChlbCwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVsICE9PSAnb2JqZWN0JyB8fCAhZWwgfHxcbiAgICB0eXBlb2YgdHlwZSAhPT0gJ3N0cmluZycgfHwgIXR5cGUpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgdGFyZ2V0ID0gdGhpcy5fZ2V0KGVsKVxuICBpZiAodGFyZ2V0KSB7XG4gICAgZGVsZXRlIHRhcmdldC5ldmVudHNbdHlwZV1cbiAgfVxufVxuXG5FdmVudE1hbmFnZXIucHJvdG90eXBlLmZpcmUgPSBmdW5jdGlvbiAoZWwsIHR5cGUsIGUpIHtcbiAgdmFyIHRhcmdldCA9IHRoaXMuX2dldChlbClcbiAgdmFyIGhhbmRsZXIsIGVsXG4gIGlmICh0YXJnZXQpIHtcbiAgICBlbCA9IHRhcmdldC5lbFxuICAgIGhhbmRsZXIgPSB0YXJnZXQuZXZlbnRzW3R5cGVdXG4gICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gaGFuZGxlci5jYWxsKGVsLCBlKVxuICAgIH1cbiAgfVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL2V2ZW50LmpzXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBBIHNpbXBsZSB2aXJ0dWFsIGRvbSBpbXBsZW1lbnRhdGlvblxuICovXG5cbmNvbnN0IERFRkFVTFRfVEFHX05BTUUgPSAnZGl2J1xuXG5leHBvcnQgY29uc3QgaW5zdGFuY2VNYXAgPSB7fVxuXG5leHBvcnQgZnVuY3Rpb24gRG9jdW1lbnQoaWQpIHtcbiAgaWQgPSBpZCA/IGlkLnRvU3RyaW5nKCkgOiAnJ1xuICB0aGlzLmlkID0gaWRcbiAgdGhpcy5uZXh0UmVmID0gMVxuICB0aGlzLm5vZGVNYXAgPSB7fVxuICB0aGlzLmxpc3RlbmVyID0gbnVsbFxuICB0aGlzLmV2ZW50TWFuYWdlciA9IG51bGxcbiAgdGhpcy5jbG9zZWQgPSBmYWxzZVxuICBpbnN0YW5jZU1hcFtpZF0gPSB0aGlzXG5cbiAgdGhpcy5jcmVhdGVEb2N1bWVudEVsZW1lbnQoKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzdHJveURvY3VtZW50KGlkKSB7XG4gIGRlbGV0ZSBpbnN0YW5jZU1hcFtpZF1cbn1cblxuRG9jdW1lbnQucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuY2xvc2VkID0gZmFsc2VcbiAgaWYgKHRoaXMubGlzdGVuZXIpIHtcbiAgICB0aGlzLmxpc3RlbmVyLmJhdGNoZWQgPSBmYWxzZVxuICB9XG59XG5Eb2N1bWVudC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuY2xvc2VkID0gdHJ1ZVxuICBpZiAodGhpcy5saXN0ZW5lcikge1xuICAgIHRoaXMubGlzdGVuZXIuYmF0Y2hlZCA9IHRydWVcbiAgfVxufVxuXG5Eb2N1bWVudC5wcm90b3R5cGUuc2V0RXZlbnRNYW5hZ2VyID0gZnVuY3Rpb24gKGV2ZW50TWFuYWdlcikge1xuICB0aGlzLmV2ZW50TWFuYWdlciA9IGV2ZW50TWFuYWdlclxufVxuXG5Eb2N1bWVudC5wcm90b3R5cGUuc2V0TGlzdGVuZXIgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHtcbiAgdGhpcy5saXN0ZW5lciA9IGxpc3RlbmVyXG4gIGxpc3RlbmVyLmJhdGNoZWQgPSAhIXRoaXMuY2xvc2VkXG59XG5cbkRvY3VtZW50LnByb3RvdHlwZS5hZGRSZWYgPSBmdW5jdGlvbiAoZWwpIHtcbiAgZWwucmVmID0gdGhpcy5uZXh0UmVmLnRvU3RyaW5nKClcbiAgdGhpcy5ub2RlTWFwW2VsLnJlZl0gPSBlbFxuICB0aGlzLm5leHRSZWYrK1xufVxuXG5Eb2N1bWVudC5wcm90b3R5cGUuZ2V0UmVmID0gZnVuY3Rpb24gKHJlZikge1xuICByZXR1cm4gdGhpcy5ub2RlTWFwW3JlZl1cbn1cblxuRG9jdW1lbnQucHJvdG90eXBlLnJlbW92ZVJlZiA9IGZ1bmN0aW9uIChyZWYpIHtcbiAgZGVsZXRlIHRoaXMubm9kZU1hcFtyZWZdXG59XG5cbkRvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVEb2N1bWVudEVsZW1lbnQgPSBmdW5jdGlvbiAodHlwZSwgcHJvcHMpIHtcbiAgaWYgKCF0aGlzLmRvY3VtZW50RWxlbWVudCkge1xuICAgIHRoaXMuZG9jdW1lbnRFbGVtZW50ID0gbmV3IEVsZW1lbnQodHlwZSwgcHJvcHMsIHRoaXMpXG4gICAgdGhpcy5ub2RlTWFwLl9kb2N1bWVudEVsZW1lbnQgPSB0aGlzLmRvY3VtZW50RWxlbWVudFxuICAgIHRoaXMuZG9jdW1lbnRFbGVtZW50LnJlZiA9ICdfZG9jdW1lbnRFbGVtZW50J1xuICAgIHRoaXMuZG9jdW1lbnRFbGVtZW50LmF0dGFjaGVkID0gdHJ1ZVxuICB9XG5cbiAgcmV0dXJuIHRoaXMuZG9jdW1lbnRFbGVtZW50XG59XG5cbkRvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVCb2R5ID0gZnVuY3Rpb24gKHR5cGUsIHByb3BzKSB7XG4gIGlmICghdGhpcy5ib2R5KSB7XG4gICAgdGhpcy5ib2R5ID0gbmV3IEVsZW1lbnQodHlwZSwgcHJvcHMsIHRoaXMpXG4gICAgdGhpcy5ub2RlTWFwLl9yb290ID0gdGhpcy5ib2R5XG4gICAgdGhpcy5ib2R5LnJlZiA9ICdfcm9vdCdcbiAgICB0aGlzLmJvZHkuZGVwdGggPSAxXG4gIH1cblxuICByZXR1cm4gdGhpcy5ib2R5XG59XG5cbkRvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVFbGVtZW50ID0gZnVuY3Rpb24gKHRhZ05hbWUsIHByb3BzKSB7XG4gIHJldHVybiBuZXcgRWxlbWVudCh0YWdOYW1lLCBwcm9wcywgdGhpcylcbn1cblxuRG9jdW1lbnQucHJvdG90eXBlLmNyZWF0ZUNvbW1lbnQgPSBmdW5jdGlvbiAodGV4dCkge1xuICByZXR1cm4gbmV3IENvbW1lbnQodGV4dCwgdGhpcylcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIE5vZGUoKSB7XG59XG5cbk5vZGUucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uIChpbnN0YW5jZUlkKSB7XG4gIHRoaXMucGFyZW50UmVmID0gbnVsbFxuICB0aGlzLmF0dGFjaGVkID0gZmFsc2VcbiAgaWYgKGluc3RhbmNlSWQpIHtcbiAgICB0aGlzLmluc3RhbmNlSWQgPSBpbnN0YW5jZUlkXG4gICAgY29uc3QgZG9jID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgICBkb2MuYWRkUmVmKHRoaXMpXG4gIH1cbn1cblxuTm9kZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgcmVmID0gdGhpcy5yZWZcbiAgY29uc3QgaW5zdGFuY2VJZCA9IHRoaXMuaW5zdGFuY2VJZFxuICBpZiAoaW5zdGFuY2VJZCkge1xuICAgIGNvbnN0IGRvYyA9IGluc3RhbmNlTWFwW2luc3RhbmNlSWRdXG4gICAgZG9jLnJlbW92ZVJlZihyZWYpXG4gIH1cblxuICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW4gfHwgW11cbiAgY29uc3QgbGVuZ3RoID0gY2hpbGRyZW4ubGVuZ3RoXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjaGlsZHJlbltpXS5kZXN0cm95KClcbiAgfVxufVxuXG5Ob2RlLnByb3RvdHlwZS5nZXRSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgZG9jID0gaW5zdGFuY2VNYXBbdGhpcy5pbnN0YW5jZUlkXVxuICByZXR1cm4gZG9jLmxpc3RlbmVyXG59XG5cbk5vZGUucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGluc3RhbmNlSWQgPSB0aGlzLmluc3RhbmNlSWRcbiAgY29uc3QgZG9jID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgY29uc3QgcGFyZW50ID0gZG9jLmdldFJlZih0aGlzLnBhcmVudFJlZilcbiAgaWYgKHBhcmVudCkge1xuICAgIHJldHVybiBwYXJlbnQuY2hpbGRyZW5bcGFyZW50LmNoaWxkcmVuLmluZGV4T2YodGhpcykgKyAxXVxuICB9XG59XG5cbk5vZGUucHJvdG90eXBlLnByZXYgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGluc3RhbmNlSWQgPSB0aGlzLmluc3RhbmNlSWRcbiAgY29uc3QgZG9jID0gaW5zdGFuY2VNYXBbaW5zdGFuY2VJZF1cbiAgY29uc3QgcGFyZW50ID0gZG9jLmdldFJlZih0aGlzLnBhcmVudFJlZilcbiAgaWYgKHBhcmVudCkge1xuICAgIHJldHVybiBwYXJlbnQuY2hpbGRyZW5bcGFyZW50LmNoaWxkcmVuLmluZGV4T2YodGhpcykgLSAxXVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBFbGVtZW50KHR5cGU9REVGQVVMVF9UQUdfTkFNRSwgcHJvcHMsIG93bmVyRG9jdW1lbnQpIHtcbiAgcHJvcHMgPSBwcm9wcyB8fCB7fVxuICB0aGlzLmNyZWF0ZShvd25lckRvY3VtZW50LmlkKVxuICB0aGlzLm93bmVyRG9jdW1lbnQgPSBvd25lckRvY3VtZW50XG4gIHRoaXMudHlwZSA9IHR5cGVcbiAgdGhpcy5hdHRyID0gcHJvcHMuYXR0ciB8fCB7fVxuICB0aGlzLmNsYXNzU3R5bGUgPSBwcm9wcy5jbGFzc1N0eWxlIHx8IHt9XG4gIHRoaXMuc3R5bGUgPSBwcm9wcy5zdHlsZSB8fCB7fVxuICB0aGlzLmV2ZW50ID0gW11cbiAgdGhpcy5jaGlsZHJlbiA9IFtdXG4gIHRoaXMucHVyZUNoaWxkcmVuID0gW11cbn1cblxuRWxlbWVudC5wcm90b3R5cGUgPSBuZXcgTm9kZSgpXG5cbkVsZW1lbnQucHJvdG90eXBlLmFwcGVuZENoaWxkID0gZnVuY3Rpb24gKG5vZGUpIHtcblxuICByZW1vdmVJZkV4aXN0ZWQobm9kZSlcbiAgbm9kZS5wYXJlbnRSZWYgPSB0aGlzLnJlZlxuICB0aGlzLmNoaWxkcmVuLnB1c2gobm9kZSlcblxuICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgIHNldEF0dGFjaGVkKG5vZGUsIHRoaXMuZGVwdGgpXG4gIH1cbiAgZWxzZSB7XG4gICAgc2V0RGV0YWNoZWQobm9kZSlcbiAgfVxuXG4gIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgIHRoaXMucHVyZUNoaWxkcmVuLnB1c2gobm9kZSlcblxuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgIGlmICh0aGlzLnJlZiA9PT0gJ19kb2N1bWVudEVsZW1lbnQnKSB7XG4gICAgICAgICAgLy8gaWYgaXRzIHBhcmVudCBpcyBkb2N1bWVudEVsZW1lbnQgdGhlbiBpdCdzIGEgYm9keVxuICAgICAgICAgIHJlbmRlcmVyLmNyZWF0ZUJvZHkobm9kZSwgdGhpcy5yZWYpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgcmVuZGVyZXIuYWRkRWxlbWVudChub2RlLCB0aGlzLnJlZilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5FbGVtZW50LnByb3RvdHlwZS5pbnNlcnRCZWZvcmUgPSBmdW5jdGlvbiAobm9kZSwgYmVmb3JlKSB7XG5cbiAgaWYgKG5vZGUucGFyZW50UmVmID09PSB0aGlzLnJlZikge1xuICAgIG1vdmVCZWZvcmUobm9kZSwgYmVmb3JlLCB0aGlzLmNoaWxkcmVuKVxuICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgY29uc3QgcHVyZUJlZm9yZUluZGV4ID0gbW92ZVB1cmVCZWZvcmUobm9kZSwgYmVmb3JlLCB0aGlzLnB1cmVDaGlsZHJlbilcbiAgICAgIGlmIChwdXJlQmVmb3JlSW5kZXggPj0gMCAmJiB0aGlzLmF0dGFjaGVkKSB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVyID0gdGhpcy5nZXRSZW5kZXJlcigpXG4gICAgICAgIGlmIChyZW5kZXJlcikge1xuICAgICAgICAgIHJlbmRlcmVyLm1vdmVFbGVtZW50KG5vZGUucmVmLCB0aGlzLnJlZiwgcHVyZUJlZm9yZUluZGV4KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVyblxuICB9XG5cbiAgcmVtb3ZlSWZFeGlzdGVkKG5vZGUpXG5cbiAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuXG4gIGNvbnN0IGluZGV4ID0gY2hpbGRyZW4uaW5kZXhPZihiZWZvcmUpXG5cbiAgbm9kZS5wYXJlbnRSZWYgPSB0aGlzLnJlZlxuICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgIHNldEF0dGFjaGVkKG5vZGUsIHRoaXMuZGVwdGgpXG4gIH1cbiAgZWxzZSB7XG4gICAgc2V0RGV0YWNoZWQobm9kZSlcbiAgfVxuICBjaGlsZHJlbi5zcGxpY2UoaW5kZXgsIDAsIG5vZGUpXG5cbiAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgY29uc3QgcHVyZUNoaWxkcmVuID0gdGhpcy5wdXJlQ2hpbGRyZW5cbiAgICBjb25zdCBwdXJlSW5kZXggPSBnZXRQdXJlQWZ0ZXIoYmVmb3JlLCBwdXJlQ2hpbGRyZW4pXG5cbiAgICBwdXJlQ2hpbGRyZW4uc3BsaWNlKHB1cmVJbmRleCwgMCwgbm9kZSlcblxuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgIHJlbmRlcmVyLmFkZEVsZW1lbnQobm9kZSwgdGhpcy5yZWYsIHB1cmVJbmRleClcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUuaW5zZXJ0QWZ0ZXIgPSBmdW5jdGlvbiAobm9kZSwgYWZ0ZXIpIHtcblxuICBpZiAobm9kZS5wYXJlbnRSZWYgPT09IHRoaXMucmVmKSB7XG4gICAgbW92ZUFmdGVyKG5vZGUsIGFmdGVyLCB0aGlzLmNoaWxkcmVuKVxuICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgY29uc3QgcHVyZUFmdGVySW5kZXggPSBtb3ZlUHVyZUFmdGVyKG5vZGUsIGFmdGVyLCB0aGlzLnB1cmVDaGlsZHJlbilcbiAgICAgIGlmIChwdXJlQWZ0ZXJJbmRleCA+PSAwICYmIHRoaXMuYXR0YWNoZWQpIHtcbiAgICAgICAgY29uc3QgcmVuZGVyZXIgPSB0aGlzLmdldFJlbmRlcmVyKClcbiAgICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgICAgcmVuZGVyZXIubW92ZUVsZW1lbnQobm9kZS5yZWYsIHRoaXMucmVmLCBwdXJlQWZ0ZXJJbmRleClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuXG4gIHJlbW92ZUlmRXhpc3RlZChub2RlKVxuXG4gIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlblxuICBjb25zdCBpbmRleCA9IGNoaWxkcmVuLmluZGV4T2YoYWZ0ZXIpXG5cbiAgbm9kZS5wYXJlbnRSZWYgPSB0aGlzLnJlZlxuICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgIHNldEF0dGFjaGVkKG5vZGUsIHRoaXMuZGVwdGgpXG4gIH1cbiAgZWxzZSB7XG4gICAgc2V0RGV0YWNoZWQobm9kZSlcbiAgfVxuICBjaGlsZHJlbi5zcGxpY2UoaW5kZXggKyAxLCAwLCBub2RlKVxuXG4gIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgIGNvbnN0IHB1cmVDaGlsZHJlbiA9IHRoaXMucHVyZUNoaWxkcmVuXG4gICAgY29uc3QgcHVyZUluZGV4ID0gZ2V0UHVyZUJlZm9yZShhZnRlciwgcHVyZUNoaWxkcmVuKVxuXG4gICAgcHVyZUNoaWxkcmVuLnNwbGljZShwdXJlSW5kZXggKyAxLCAwLCBub2RlKVxuXG4gICAgaWYgKHRoaXMuYXR0YWNoZWQpIHtcbiAgICAgIGNvbnN0IHJlbmRlcmVyID0gdGhpcy5nZXRSZW5kZXJlcigpXG4gICAgICBpZiAocmVuZGVyZXIpIHtcbiAgICAgICAgcmVuZGVyZXIuYWRkRWxlbWVudChub2RlLCB0aGlzLnJlZiwgcHVyZUluZGV4ICsgMSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUucmVtb3ZlQ2hpbGQgPSBmdW5jdGlvbiAobm9kZSwgcHJlc2VydmVkKSB7XG4gIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlblxuICBjb25zdCBpbmRleCA9IGNoaWxkcmVuLmluZGV4T2Yobm9kZSlcblxuICBzZXREZXRhY2hlZChub2RlKVxuXG4gIGlmIChpbmRleCA+PSAwKSB7XG4gICAgbm9kZS5wYXJlbnRSZWYgPSBudWxsXG4gICAgY2hpbGRyZW4uc3BsaWNlKGluZGV4LCAxKVxuICAgIGlmICghcHJlc2VydmVkKSB7XG4gICAgICBub2RlLmRlc3Ryb3koKVxuICAgIH1cbiAgfVxuXG4gIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgIHRoaXMucHVyZUNoaWxkcmVuLiRyZW1vdmUobm9kZSlcbiAgICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgICAgY29uc3QgcmVuZGVyZXIgPSB0aGlzLmdldFJlbmRlcmVyKClcbiAgICAgIGlmIChyZW5kZXJlcikge1xuICAgICAgICByZW5kZXJlci5yZW1vdmVFbGVtZW50KG5vZGUucmVmKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5FbGVtZW50LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuXG4gIGNvbnN0IGxlbmd0aCA9IGNoaWxkcmVuLmxlbmd0aFxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbltpXVxuICAgIGNoaWxkLnBhcmVudFJlZiA9IG51bGxcbiAgICBzZXREZXRhY2hlZChjaGlsZClcbiAgICBjaGlsZC5kZXN0cm95KClcbiAgfVxuICBjaGlsZHJlbi5sZW5ndGggPSAwXG5cbiAgaWYgKHRoaXMuYXR0YWNoZWQpIHtcbiAgICBjb25zdCByZWZzID0gdGhpcy5wdXJlQ2hpbGRyZW4ubWFwKChjaGlsZCkgPT4gY2hpbGQucmVmKVxuICAgIHRoaXMucHVyZUNoaWxkcmVuLmxlbmd0aCA9IDBcbiAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgIGlmIChyZW5kZXJlcikge1xuICAgICAgcmVuZGVyZXIucmVtb3ZlRWxlbWVudChyZWZzKVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtb3ZlQmVmb3JlKG5vZGUsIGJlZm9yZSwgY2hpbGRyZW4pIHtcbiAgY29uc3QgdGFyZ2V0SW5kZXggPSBjaGlsZHJlbi5pbmRleE9mKG5vZGUpXG4gIGNvbnN0IGJlZm9yZUluZGV4ID0gY2hpbGRyZW4uaW5kZXhPZihiZWZvcmUpXG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgaWYgKHRhcmdldEluZGV4ID09PSBiZWZvcmVJbmRleCB8fCB0YXJnZXRJbmRleCArIDEgPT09IGJlZm9yZUluZGV4KSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICBjb25zdCBuZXdJbmRleCA9IHRhcmdldEluZGV4IDwgYmVmb3JlSW5kZXggPyBiZWZvcmVJbmRleCAtIDEgOiBiZWZvcmVJbmRleFxuICBjaGlsZHJlbi5zcGxpY2UodGFyZ2V0SW5kZXgsIDEpXG4gIGNoaWxkcmVuLnNwbGljZShuZXdJbmRleCwgMCwgbm9kZSlcblxuICByZXR1cm4gYmVmb3JlSW5kZXhcbn1cblxuZnVuY3Rpb24gbW92ZVB1cmVCZWZvcmUobm9kZSwgYmVmb3JlLCBwdXJlQ2hpbGRyZW4pIHtcbiAgY29uc3QgcHVyZVRhcmdldEluZGV4ID0gcHVyZUNoaWxkcmVuLmluZGV4T2Yobm9kZSlcbiAgY29uc3QgcHVyZUJlZm9yZUluZGV4ID0gZ2V0UHVyZUFmdGVyKGJlZm9yZSwgcHVyZUNoaWxkcmVuKVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmIChwdXJlVGFyZ2V0SW5kZXggPT09IHB1cmVCZWZvcmVJbmRleCB8fFxuICAgIHB1cmVUYXJnZXRJbmRleCArIDEgPT09IHB1cmVCZWZvcmVJbmRleCkge1xuICAgIHJldHVybiAtMVxuICB9XG5cbiAgY29uc3QgcHVyZU5ld0luZGV4ID0gcHVyZVRhcmdldEluZGV4IDwgcHVyZUJlZm9yZUluZGV4XG4gICAgPyBwdXJlQmVmb3JlSW5kZXggLSAxXG4gICAgOiBwdXJlQmVmb3JlSW5kZXhcblxuICBwdXJlQ2hpbGRyZW4uc3BsaWNlKHB1cmVUYXJnZXRJbmRleCwgMSlcbiAgcHVyZUNoaWxkcmVuLnNwbGljZShwdXJlTmV3SW5kZXgsIDAsIG5vZGUpXG5cbiAgcmV0dXJuIHB1cmVCZWZvcmVJbmRleFxufVxuXG5mdW5jdGlvbiBnZXRQdXJlQWZ0ZXIobm9kZSwgcHVyZUNoaWxkcmVuKSB7XG4gIGxldCBwdXJlSW5kZXggPSBwdXJlQ2hpbGRyZW4uaW5kZXhPZihub2RlKVxuICB3aGlsZSAobm9kZSAmJiBwdXJlSW5kZXggPCAwKSB7XG4gICAgbm9kZSA9IG5vZGUubmV4dCgpXG4gICAgcHVyZUluZGV4ID0gcHVyZUNoaWxkcmVuLmluZGV4T2Yobm9kZSlcbiAgfVxuICBpZiAocHVyZUluZGV4IDwgMCkge1xuICAgIHB1cmVJbmRleCA9IHB1cmVDaGlsZHJlbi5sZW5ndGhcbiAgfVxuICByZXR1cm4gcHVyZUluZGV4XG59XG5cbmZ1bmN0aW9uIG1vdmVBZnRlcihub2RlLCBhZnRlciwgY2hpbGRyZW4pIHtcbiAgY29uc3QgdGFyZ2V0SW5kZXggPSBjaGlsZHJlbi5pbmRleE9mKG5vZGUpXG4gIGNvbnN0IGFmdGVySW5kZXggPSBjaGlsZHJlbi5pbmRleE9mKGFmdGVyKVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmICh0YXJnZXRJbmRleCA9PT0gYWZ0ZXJJbmRleCB8fCB0YXJnZXRJbmRleCA9PT0gYWZ0ZXJJbmRleCArIDEpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuXG4gIGNvbnN0IG5ld0luZGV4ID0gdGFyZ2V0SW5kZXggPCBhZnRlckluZGV4ID8gYWZ0ZXJJbmRleCA6IGFmdGVySW5kZXggKyAxXG4gIGNoaWxkcmVuLnNwbGljZSh0YXJnZXRJbmRleCwgMSlcbiAgY2hpbGRyZW4uc3BsaWNlKG5ld0luZGV4LCAwLCBub2RlKVxuXG4gIHJldHVybiBhZnRlckluZGV4XG59XG5cbmZ1bmN0aW9uIG1vdmVQdXJlQWZ0ZXIobm9kZSwgYWZ0ZXIsIHB1cmVDaGlsZHJlbikge1xuICBjb25zdCBwdXJlVGFyZ2V0SW5kZXggPSBwdXJlQ2hpbGRyZW4uaW5kZXhPZihub2RlKVxuICBjb25zdCBwdXJlQWZ0ZXJJbmRleCA9IGdldFB1cmVCZWZvcmUoYWZ0ZXIsIHB1cmVDaGlsZHJlbilcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAocHVyZVRhcmdldEluZGV4ID09PSBwdXJlQWZ0ZXJJbmRleCB8fFxuICAgIHB1cmVUYXJnZXRJbmRleCA9PT0gcHVyZUFmdGVySW5kZXggKyAxKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICBjb25zdCBwdXJlTmV3SW5kZXggPSBwdXJlVGFyZ2V0SW5kZXggPCBwdXJlQWZ0ZXJJbmRleFxuICAgID8gcHVyZUFmdGVySW5kZXhcbiAgICA6IHB1cmVBZnRlckluZGV4ICsgMVxuXG4gIHB1cmVDaGlsZHJlbi5zcGxpY2UocHVyZVRhcmdldEluZGV4LCAxKVxuICBwdXJlQ2hpbGRyZW4uc3BsaWNlKHB1cmVOZXdJbmRleCwgMCwgbm9kZSlcblxuICByZXR1cm4gcHVyZUFmdGVySW5kZXggKyAxXG59XG5cbmZ1bmN0aW9uIGdldFB1cmVCZWZvcmUobm9kZSwgcHVyZUNoaWxkcmVuKSB7XG4gIGxldCBwdXJlSW5kZXggPSBwdXJlQ2hpbGRyZW4uaW5kZXhPZihub2RlKVxuICB3aGlsZSAobm9kZSAmJiBwdXJlSW5kZXggPCAwKSB7XG4gICAgbm9kZSA9IG5vZGUucHJldigpXG4gICAgcHVyZUluZGV4ID0gcHVyZUNoaWxkcmVuLmluZGV4T2Yobm9kZSlcbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAocHVyZUluZGV4IDwgMCkge1xuICAgIHB1cmVJbmRleCA9IC0xXG4gIH1cbiAgcmV0dXJuIHB1cmVJbmRleFxufVxuXG5mdW5jdGlvbiBzZXRBdHRhY2hlZChub2RlLCBkZXB0aCkge1xuICBpZiAobm9kZS5yZWYgPT09ICdfcm9vdCcpIHtcbiAgICBkZXB0aCA9IDFcbiAgfVxuICBlbHNlIHtcbiAgICBkZXB0aCA9IGRlcHRoID4gMCA/IGRlcHRoICsgMSA6IDBcbiAgfVxuICBub2RlLmF0dGFjaGVkID0gdHJ1ZVxuICBub2RlLmRlcHRoID0gZGVwdGhcbiAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICBub2RlLmNoaWxkcmVuLmZvckVhY2goKHN1YikgPT4ge1xuICAgICAgc2V0QXR0YWNoZWQoc3ViLCBkZXB0aClcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIHNldERldGFjaGVkKG5vZGUpIHtcbiAgbm9kZS5hdHRhY2hlZCA9IGZhbHNlXG4gIG5vZGUuZGVwdGggPSAwXG4gIGlmIChub2RlLmNoaWxkcmVuKSB7XG4gICAgbm9kZS5jaGlsZHJlbi5mb3JFYWNoKChzdWIpID0+IHtcbiAgICAgIHNldERldGFjaGVkKHN1YilcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUlmRXhpc3RlZChub2RlKSB7XG4gIGNvbnN0IGRvYyA9IGluc3RhbmNlTWFwW25vZGUuaW5zdGFuY2VJZF1cbiAgaWYgKGRvYykge1xuICAgIGNvbnN0IGV4aXN0ZWROb2RlID0gZG9jLmdldFJlZihub2RlLnJlZilcbiAgICBpZiAoZXhpc3RlZE5vZGUpIHtcbiAgICAgIGNvbnN0IGV4aXN0ZWRQYXJlbnQgPSBkb2MuZ2V0UmVmKGV4aXN0ZWROb2RlLnBhcmVudFJlZilcbiAgICAgIGlmIChleGlzdGVkUGFyZW50ICYmIGV4aXN0ZWRQYXJlbnQucmVtb3ZlQ2hpbGQpIHtcbiAgICAgICAgZXhpc3RlZFBhcmVudC5yZW1vdmVDaGlsZChleGlzdGVkTm9kZSwgdHJ1ZSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUuc2V0QXR0ciA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gIGlmICh0aGlzLmF0dHJba2V5XSA9PT0gdmFsdWUpIHtcbiAgICByZXR1cm5cbiAgfVxuICB0aGlzLmF0dHJba2V5XSA9IHZhbHVlXG4gIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgY29uc3QgcmVuZGVyZXIgPSB0aGlzLmdldFJlbmRlcmVyKClcbiAgICBpZiAocmVuZGVyZXIpIHtcbiAgICAgIHJlbmRlcmVyLnNldEF0dHIodGhpcy5yZWYsIGtleSwgdmFsdWUpXG4gICAgfVxuICB9XG59XG5cbkVsZW1lbnQucHJvdG90eXBlLnNldFN0eWxlID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgaWYgKHRoaXMuc3R5bGVba2V5XSA9PT0gdmFsdWUpIHtcbiAgICByZXR1cm5cbiAgfVxuICB0aGlzLnN0eWxlW2tleV0gPSB2YWx1ZVxuICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgIGNvbnN0IHJlbmRlcmVyID0gdGhpcy5nZXRSZW5kZXJlcigpXG4gICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICByZW5kZXJlci5zZXRTdHlsZSh0aGlzLnJlZiwga2V5LCB2YWx1ZSlcbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUuc2V0Q2xhc3NTdHlsZSA9IGZ1bmN0aW9uIChjbGFzc1N0eWxlKSB7XG4gIHRoaXMuY2xhc3NTdHlsZSA9IGNsYXNzU3R5bGVcbiAgaWYgKHRoaXMuYXR0YWNoZWQpIHtcbiAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgIGlmIChyZW5kZXJlcikge1xuICAgICAgcmVuZGVyZXIuc2V0U3R5bGVzKHRoaXMucmVmLCB0aGlzLnRvU3R5bGUoKSlcbiAgICB9XG4gIH1cbn1cblxuRWxlbWVudC5wcm90b3R5cGUuYWRkRXZlbnQgPSBmdW5jdGlvbiAodHlwZSwgaGFuZGxlcikge1xuICBjb25zdCBpbmRleCA9IHRoaXMuZXZlbnQuaW5kZXhPZih0eXBlKVxuXG4gIGlmIChpbmRleCA8IDApIHtcbiAgICB0aGlzLmV2ZW50LnB1c2godHlwZSlcbiAgICBsZXQgZXZlbnRNYW5hZ2VyID0gdGhpcy5vd25lckRvY3VtZW50LmV2ZW50TWFuYWdlclxuICAgIGV2ZW50TWFuYWdlci5hZGQodGhpcywgdHlwZSwgaGFuZGxlcilcblxuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgIHJlbmRlcmVyLmFkZEV2ZW50KHRoaXMucmVmLCB0eXBlKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5FbGVtZW50LnByb3RvdHlwZS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIGNvbnN0IGluZGV4ID0gdGhpcy5ldmVudC5pbmRleE9mKHR5cGUpXG5cbiAgaWYgKGluZGV4ID49IDApIHtcbiAgICB0aGlzLmV2ZW50LnNwbGljZShpbmRleCwgMSlcbiAgICBsZXQgZXZlbnRNYW5hZ2VyID0gdGhpcy5vd25lckRvY3VtZW50LmV2ZW50TWFuYWdlclxuICAgIGV2ZW50TWFuYWdlci5yZW1vdmUodGhpcywgdHlwZSlcblxuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKVxuICAgICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICAgIHJlbmRlcmVyLnJlbW92ZUV2ZW50KHRoaXMucmVmLCB0eXBlKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5FbGVtZW50LnByb3RvdHlwZS50b1N0eWxlID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCByZXN1bHQgPSB7fVxuICBjb25zdCBjbGFzc1N0eWxlID0gdGhpcy5jbGFzc1N0eWxlXG4gIGNvbnN0IHN0eWxlID0gdGhpcy5zdHlsZVxuICBmb3IgKGNvbnN0IG5hbWUgaW4gY2xhc3NTdHlsZSkge1xuICAgIHJlc3VsdFtuYW1lXSA9IGNsYXNzU3R5bGVbbmFtZV1cbiAgfVxuICBmb3IgKGNvbnN0IG5hbWUgaW4gc3R5bGUpIHtcbiAgICByZXN1bHRbbmFtZV0gPSBzdHlsZVtuYW1lXVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuRWxlbWVudC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCByZXN1bHQgPSB7XG4gICAgcmVmOiB0aGlzLnJlZi50b1N0cmluZygpLFxuICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICBhdHRyOiB0aGlzLmF0dHIsXG4gICAgc3R5bGU6IHRoaXMudG9TdHlsZSgpXG4gIH1cblxuICBpZiAodGhpcy5ldmVudCAmJiB0aGlzLmV2ZW50Lmxlbmd0aCkge1xuICAgIHJlc3VsdC5ldmVudCA9IHRoaXMuZXZlbnRcbiAgfVxuICBpZiAodGhpcy5wdXJlQ2hpbGRyZW4gJiYgdGhpcy5wdXJlQ2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgcmVzdWx0LmNoaWxkcmVuID0gdGhpcy5wdXJlQ2hpbGRyZW4ubWFwKChjaGlsZCkgPT4gY2hpbGQudG9KU09OKCkpXG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG5cbkVsZW1lbnQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gJzwnICsgdGhpcy50eXBlICtcbiAgICAnIGF0dHI9JyArIEpTT04uc3RyaW5naWZ5KHRoaXMuYXR0cikgK1xuICAgICcgc3R5bGU9JyArIEpTT04uc3RyaW5naWZ5KHRoaXMudG9TdHlsZSgpKSArICc+JyArXG4gICAgdGhpcy5wdXJlQ2hpbGRyZW4ubWFwKChjaGlsZCkgPT4gY2hpbGQudG9TdHJpbmcoKSkuam9pbignJykgK1xuICAgICc8LycgKyB0aGlzLnR5cGUgKyAnPidcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIENvbW1lbnQodmFsdWUsIG93bmVyRG9jdW1lbnQpIHtcbiAgdGhpcy5jcmVhdGUob3duZXJEb2N1bWVudC5pZClcbiAgdGhpcy50eXBlID0gJ2NvbW1lbnQnXG4gIHRoaXMudmFsdWUgPSB2YWx1ZVxufVxuXG5Db21tZW50LnByb3RvdHlwZSA9IG5ldyBOb2RlKClcblxuQ29tbWVudC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAnPCEtLSAnICsgdGhpcy52YWx1ZSArICcgLS0+J1xufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBwL2RvbS5qc1xuICoqLyIsIm1vZHVsZS5leHBvcnRzID0ge1xuXHRcIm5hbWVcIjogXCJ3ZWV4LWpzZnJhbWV3b3JrXCIsXG5cdFwidmVyc2lvblwiOiBcIjAuMTMuN1wiLFxuXHRcImRlc2NyaXB0aW9uXCI6IFwiSlMgRnJhbWV3b3JrIGZvciBXZWV4IHNvbHV0aW9uIHdoaWNoIGlzIGEgZXh0ZW5kYWJsZSBjcm9zcy1wbGF0Zm9ybSBzb2x1dGlvbiBmb3IgZHluYW1pYyBwcm9ncmFtbWluZyBhbmQgcHVibGlzaGluZyBwcm9qZWN0c1wiLFxuXHRcIm1haW5cIjogXCJpbmRleC5qc1wiLFxuXHRcInNjcmlwdHNcIjoge1xuXHRcdFwiZGV2XCI6IFwid2VicGFjayAtLXdhdGNoIC0tY29uZmlnIC4vd2VicGFjay5jb25maWcuanNcIixcblx0XHRcImJ1aWxkXCI6IFwid2VicGFjayAtLWNvbmZpZyAuL3dlYnBhY2suY29uZmlnLmpzXCIsXG5cdFx0XCJjb21wcmVzc1wiOiBcInVnbGlmeWpzIGRpc3QvaW5kZXguanMgLW8gZGlzdC9pbmRleC5taW4uanNcIixcblx0XHRcImxpbnRcIjogXCJqc2NzIC0tY29uZmlnIC5qc2NzcmMgcG9seWZpbGwvKi5qcyBwb2x5ZmlsbC9fX3Rlc3RfXy8qLmpzIGxpYi8qLmpzIGxpYi9fX3Rlc3RfXy8qLmpzIGxpYi9hcHAvKi5qcyBsaWIvYXBwL19fdGVzdF9fLyouanMgbGliL3ZtLyouanMgbGliL3ZtL19fdGVzdF9fLyouanNcIixcblx0XHRcInRlc3RcIjogXCJtb2NoYSAtLWNvbXBpbGVycyBqczpiYWJlbC1jb3JlL3JlZ2lzdGVyIHBvbHlmaWxsL19fdGVzdF9fLyouanMgbGliL19fdGVzdF9fLyouanMgbGliLyoqL19fdGVzdF9fLyouanNcIixcblx0XHRcImNvdmVyXCI6IFwiYmFiZWwtbm9kZSBub2RlX21vZHVsZXMvaXNwYXJ0YS9iaW4vaXNwYXJ0YSBjb3ZlciAtLXJlcG9ydCB0ZXh0IG5vZGVfbW9kdWxlcy9tb2NoYS9iaW4vX21vY2hhIC0tIC0tcmVwb3J0ZXIgZG90IGxpYi9fX3Rlc3RfXy8qLmpzIGxpYi8qKi9fX3Rlc3RfXy8qLmpzXCIsXG5cdFx0XCJjaVwiOiBcIm5wbSBydW4gbGludCAmJiBucG0gcnVuIGNvdmVyXCJcblx0fSxcblx0XCJyZXBvc2l0b3J5XCI6IHtcblx0XHRcInR5cGVcIjogXCJnaXRcIixcblx0XHRcInVybFwiOiBcImdpdEBnaXRodWIuY29tOmFsaWJhYmEvd2VleC5naXRcIlxuXHR9LFxuXHRcImF1dGhvclwiOiBbXG5cdFx0e1xuXHRcdFx0XCJuYW1lXCI6IFwiamluamlhbmdcIixcblx0XHRcdFwiZW1haWxcIjogXCJ6aGFvamluamlhbmdAbWUuY29tXCJcblx0XHR9LFxuXHRcdHtcblx0XHRcdFwibmFtZVwiOiBcIlRlcnJ5IEtpbmdcIixcblx0XHRcdFwiZW1haWxcIjogXCJ0ZXJyeWtpbmdjaGFAZ21haWwuY29tXCJcblx0XHR9XG5cdF0sXG5cdFwiY29udHJpYnV0b3JzXCI6IFtcblx0XHR7XG5cdFx0XHRcIm5hbWVcIjogXCJwdXNoaW1pbmdcIixcblx0XHRcdFwiZW1haWxcIjogXCJwdXNoaW1pbmdAZ21haWwuY29tXCJcblx0XHR9LFxuXHRcdHtcblx0XHRcdFwibmFtZVwiOiBcImlza2VuaHVhbmdcIixcblx0XHRcdFwiZW1haWxcIjogXCJpc2tlbmh1YW5nQGdtYWlsLmNvbVwiXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRcIm5hbWVcIjogXCJ5dWFueWFuXCIsXG5cdFx0XHRcImVtYWlsXCI6IFwieXVhbnlhbi5jYW9AZ21haWwuY29tXCJcblx0XHR9XG5cdF0sXG5cdFwia2V5d29yZHNcIjogW1xuXHRcdFwid2VleFwiLFxuXHRcdFwibXZ2bVwiLFxuXHRcdFwiYnJvd3NlclwiLFxuXHRcdFwiaHlicmlkXCIsXG5cdFx0XCJmcmFtZXdvcmtcIlxuXHRdLFxuXHRcImxpY2Vuc2VcIjogXCJBcGFjaGUtMi4wXCIsXG5cdFwiZGVwZW5kZW5jaWVzXCI6IHtcblx0XHRcInNlbXZlclwiOiBcIn41LjEuMFwiLFxuXHRcdFwiY29yZS1qc1wiOiBcIn4yLjEuMVwiXG5cdH0sXG5cdFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcblx0XHRcImJhYmVsLWNsaVwiOiBcIn42LjQuNVwiLFxuXHRcdFwiYmFiZWwtY29yZVwiOiBcIn42LjQuNVwiLFxuXHRcdFwiYmFiZWwtbG9hZGVyXCI6IFwifjYuMi4xXCIsXG5cdFx0XCJiYWJlbC1wcmVzZXQtZXMyMDE1XCI6IFwifjYuMy4xM1wiLFxuXHRcdFwiY2hhaVwiOiBcIn4zLjIuMFwiLFxuXHRcdFwiaXNwYXJ0YVwiOiBcIn40LjAuMFwiLFxuXHRcdFwiaXN0YW5idWxcIjogXCJ+MC40LjJcIixcblx0XHRcImpzY3NcIjogXCJ+Mi45LjBcIixcblx0XHRcImpzb24tbG9hZGVyXCI6IFwiXjAuNS40XCIsXG5cdFx0XCJtb2NoYVwiOiBcIn4yLjMuNFwiLFxuXHRcdFwic2lub25cIjogXCJ+MS4xNy4yXCIsXG5cdFx0XCJzaW5vbi1jaGFpXCI6IFwifjIuOC4wXCIsXG5cdFx0XCJ1Z2xpZnktanNcIjogXCJeMi42LjJcIixcblx0XHRcIndhdGNoLWNsaVwiOiBcIn4wLjIuMVwiLFxuXHRcdFwid2VicGFja1wiOiBcIn4xLjEyLjEyXCJcblx0fSxcblx0XCJvcHRpb25hbERlcGVuZGVuY2llc1wiOiB7XG5cdFx0XCJ3ZWV4LXRyYW5zZm9ybWVyXCI6IFwifjAuM1wiXG5cdH1cbn07XG5cblxuLyoqKioqKioqKioqKioqKioqXG4gKiogV0VCUEFDSyBGT09URVJcbiAqKiAuL3BhY2thZ2UuanNvblxuICoqIG1vZHVsZSBpZCA9IDEwNVxuICoqIG1vZHVsZSBjaHVua3MgPSAwXG4gKiovIiwiLyoqXG4gKiBAZmlsZU92ZXJ2aWV3IFRoZSBhcGkgZm9yIGludm9raW5nIHdpdGggXCIkXCIgcHJlZml4XG4gKi9cbmltcG9ydCB7dHlwb2YsIGV4dGVuZH0gZnJvbSAnLi4vdXRpbCdcblxuLyoqXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBjb21tb25cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIEBkZXByZWNhdGVkIHVzZSAkdm0gaW5zdGVhZFxuICogZmluZCB0aGUgdm0gYnkgaWRcbiAqIE5vdGU6IHRoZXJlIGlzIG9ubHkgb25lIGlkIGluIHdob2xlIGNvbXBvbmVudFxuICogQHBhcmFtICB7c3RyaW5nfSBpZFxuICogQHJldHVybiB7Vm19XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkKGlkKSB7XG4gIG5hdGl2ZUxvZygnW1dBUk5JTkddIHRoZSBWbSMkIGFwaSBpcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIFZtIyR2bSBpbnN0ZWFkJylcbiAgY29uc3QgaW5mbyA9IHRoaXMuX2lkc1tpZF1cbiAgaWYgKGluZm8pIHtcbiAgICByZXR1cm4gaW5mby52bVxuICB9XG59XG5cbi8qKlxuICogZmluZCB0aGUgZWxlbWVudCBieSBpZFxuICogTm90ZTogdGhlcmUgaXMgb25seSBvbmUgaWQgaW4gd2hvbGUgY29tcG9uZW50XG4gKiBAcGFyYW0gIHtzdHJpbmd9IGlkXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gJGVsKGlkKSB7XG4gIGNvbnN0IGluZm8gPSB0aGlzLl9pZHNbaWRdXG4gIGlmIChpbmZvKSB7XG4gICAgcmV0dXJuIGluZm8uZWxcbiAgfVxufVxuXG4vKipcbiAqIGZpbmQgdGhlIHZtIG9mIHRoZSBjdXN0b20gY29tcG9uZW50IGJ5IGlkXG4gKiBOb3RlOiB0aGVyZSBpcyBvbmx5IG9uZSBpZCBpbiB3aG9sZSBjb21wb25lbnRcbiAqIEBwYXJhbSAge3N0cmluZ30gaWRcbiAqIEByZXR1cm4ge1ZtfVxuICovXG5leHBvcnQgZnVuY3Rpb24gJHZtKGlkKSB7XG4gIGNvbnN0IGluZm8gPSB0aGlzLl9pZHNbaWRdXG4gIGlmIChpbmZvKSB7XG4gICAgcmV0dXJuIGluZm8udm1cbiAgfVxufVxuXG4vKipcbiAqIEZpcmUgd2hlbiBkaWZmZXIgcmVuZGVyaW5nIGZpbmlzaGVkXG4gKlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkcmVuZGVyVGhlbihmbikge1xuICBjb25zdCBhcHAgPSB0aGlzLl9hcHBcbiAgY29uc3QgZGlmZmVyID0gYXBwLmRpZmZlclxuICByZXR1cm4gZGlmZmVyLnRoZW4oKCkgPT4ge1xuICAgIGZuKClcbiAgfSlcbn1cblxuLyoqXG4gKiBzY3JvbGwgYW4gZWxlbWVudCBzcGVjaWZpZWQgYnkgaWQgaW50byB2aWV3LCBcbiAqIG1vcmVvdmVyIHNwZWNpZnkgYSBudW1iZXIgb2Ygb2Zmc2V0IG9wdGlvbmFsbHlcbiAqIEBwYXJhbSAge3N0cmluZ30gaWRcbiAqIEBwYXJhbSAge251bWJlcn0gb2Zmc2V0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkc2Nyb2xsVG8oaWQsIG9mZnNldCkge1xuICBjb25zdCBlbCA9IHRoaXMuJGVsKGlkKVxuICBpZiAoZWwpIHtcbiAgICBjb25zdCBkb20gPSB0aGlzLl9hcHAucmVxdWlyZU1vZHVsZSgnZG9tJylcbiAgICBkb20uc2Nyb2xsVG9FbGVtZW50KGVsLnJlZiwge29mZnNldDogb2Zmc2V0fSlcbiAgfVxufVxuXG4vKipcbiAqIHBlcmZvcm0gdHJhbnNpdGlvbiBhbmltYXRpb24gb24gYW4gZWxlbWVudCBzcGVjaWZpZWQgYnkgaWRcbiAqIEBwYXJhbSAge3N0cmluZ30gICBpZFxuICogQHBhcmFtICB7b2JqZWN0fSAgIG9wdGlvbnNcbiAqIEBwYXJhbSAge29iamVjdH0gICBvcHRpb25zLnN0eWxlc1xuICogQHBhcmFtICB7b2JqZWN0fSAgIG9wdGlvbnMuZHVyYXRpb24obXMpXG4gKiBAcGFyYW0gIHtvYmplY3R9ICAgW29wdGlvbnMudGltaW5nRnVuY3Rpb25dXG4gKiBAcGFyYW0gIHtvYmplY3R9ICAgW29wdGlvbnMuZGVsYXk9MChtcyldXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICR0cmFuc2l0aW9uKGlkLCBvcHRpb25zLCBjYWxsYmFjaykge1xuICBjb25zdCBlbCA9IHRoaXMuJGVsKGlkKVxuICBpZiAoZWwgJiYgb3B0aW9ucyAmJiBvcHRpb25zLnN0eWxlcykge1xuICAgIGNvbnN0IGFuaW1hdGlvbiA9IHRoaXMuX2FwcC5yZXF1aXJlTW9kdWxlKCdhbmltYXRpb24nKVxuICAgIGFuaW1hdGlvbi50cmFuc2l0aW9uKGVsLnJlZiwgb3B0aW9ucywgKC4uLmFyZ3MpID0+IHtcbiAgICAgIHRoaXMuX3NldFN0eWxlKGVsLCBvcHRpb25zLnN0eWxlcylcbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKC4uLmFyZ3MpXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIGdldCBzb21lIGNvbmZpZ1xuICogQHJldHVybiB7b2JqZWN0fSBzb21lIGNvbmZpZyBmb3IgYXBwIGluc3RhbmNlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gYnVuZGxlVXJsXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGRlYnVnXG4gKiBAcHJvcGVydHkge29iamVjdH0gZW52XG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW52LndlZXhWZXJzaW9uKGV4LiAxLjAuMClcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBlbnYuYXBwTmFtZShleC4gVEIvVE0pXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW52LmFwcFZlcnNpb24oZXguIDUuMC4wKVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGVudi5wbGF0Zm9ybShleC4gaU9TL0FuZHJvaWQpXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW52Lm9zVmVyc2lvbihleC4gNy4wLjApXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW52LmRldmljZU1vZGVsICoqbmF0aXZlIG9ubHkqKlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGVudi5bZGV2aWNlV2lkdGg9NzUwXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IGVudi5kZXZpY2VIZWlnaHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICRnZXRDb25maWcoY2FsbGJhY2spIHtcbiAgY29uc3QgY29uZmlnID0gZXh0ZW5kKHtcbiAgICBlbnY6IGdsb2JhbC5XWEVudmlyb25tZW50IHx8IHt9XG4gIH0sIHRoaXMuX2FwcC5vcHRpb25zKVxuICBpZiAodHlwb2YoY2FsbGJhY2spID09PSAnZnVuY3Rpb24nKSB7XG4gICAgbmF0aXZlTG9nKCdbV0FSTklOR10gdGhlIGNhbGxiYWNrIG9mIFZtIyRnZXRDb25maWcoY2FsbGJhY2spIGlzIGRlcHJlY2F0ZWQsICcgK1xuICAgICAgJ3RoaXMgYXBpIG5vdyBjYW4gZGlyZWN0bHkgUkVUVVJOIGNvbmZpZyBpbmZvLicpXG4gICAgY2FsbGJhY2soY29uZmlnKVxuICB9XG4gIHJldHVybiBjb25maWdcbn1cblxuLyoqXG4gKiByZXF1ZXN0IG5ldHdvcmsgdmlhIGh0dHAgcHJvdG9jb2xcbiAqIEBwYXJhbSAge29iamVjdH0gICBwYXJhbXNcbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBjYWxsYmFja1xuICovXG5leHBvcnQgZnVuY3Rpb24gJHNlbmRIdHRwKHBhcmFtcywgY2FsbGJhY2spIHtcbiAgY29uc3Qgc3RyZWFtID0gdGhpcy5fYXBwLnJlcXVpcmVNb2R1bGUoJ3N0cmVhbScpXG4gIHN0cmVhbS5zZW5kSHR0cChwYXJhbXMsIGNhbGxiYWNrKVxufVxuXG4vKipcbiAqIG9wZW4gYSB1cmxcbiAqIEBwYXJhbSAge3N0cmluZ30gdXJsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkb3BlblVSTCh1cmwpIHtcbiAgY29uc3QgZXZlbnQgPSB0aGlzLl9hcHAucmVxdWlyZU1vZHVsZSgnZXZlbnQnKVxuICBldmVudC5vcGVuVVJMKHVybClcbn1cblxuLyoqXG4gKiBzZXQgYSB0aXRsZSBmb3IgcGFnZVxuICogQHBhcmFtICB7c3RyaW5nfSB0aXRsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gJHNldFRpdGxlKHRpdGxlKSB7XG4gIGNvbnN0IHBhZ2VJbmZvID0gdGhpcy5fYXBwLnJlcXVpcmVNb2R1bGUoJ3BhZ2VJbmZvJylcbiAgcGFnZUluZm8uc2V0VGl0bGUodGl0bGUpXG59XG5cbi8qKlxuICogaW52b2tlIGEgbmF0aXZlIG1ldGhvZCBieSBzcGVjaWZpbmcgdGhlIG5hbWUgb2YgbW9kdWxlIGFuZCBtZXRob2RcbiAqIEBwYXJhbSAge3N0cmluZ30gbW9kdWxlTmFtZVxuICogQHBhcmFtICB7c3RyaW5nfSBtZXRob2ROYW1lXG4gKiBAcGFyYW0gIHsuLi4qfSB0aGUgcmVzdCBhcmd1bWVudHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICRjYWxsKG1vZHVsZU5hbWUsIG1ldGhvZE5hbWUsIC4uLmFyZ3MpIHtcbiAgY29uc3QgbW9kdWxlID0gdGhpcy5fYXBwLnJlcXVpcmVNb2R1bGUobW9kdWxlTmFtZSlcbiAgaWYgKG1vZHVsZSAmJiBtb2R1bGVbbWV0aG9kTmFtZV0pIHtcbiAgICBtb2R1bGVbbWV0aG9kTmFtZV0oLi4uYXJncylcbiAgfVxufVxuXG5cblxuLyoqIFdFQlBBQ0sgRk9PVEVSICoqXG4gKiogLi9saWIvYXBpL21ldGhvZHMuanNcbiAqKi8iXSwic291cmNlUm9vdCI6IiJ9
\ No newline at end of file
diff --git a/weex-loader/test/test.js b/weex-loader/test/test.js
new file mode 100644
index 0000000..861798a
--- /dev/null
+++ b/weex-loader/test/test.js
@@ -0,0 +1,42 @@
+var fs = require('fs');
+var path =require('path');
+
+var chai = require('chai');
+var sinon = require('sinon');
+var sinonChai = require('sinon-chai');
+var expect = chai.expect;
+chai.use(sinonChai);
+
+require('./lib/jsfm');
+var createInstance = global.createInstance;
+var getRoot = global.getRoot;
+
+describe('loader', () => {
+
+  before(function() {
+    global.callNative = sinon.spy();
+  });
+
+  after(function() {
+    global.callNative = undefined;
+  });
+
+  it('simple case', function() {
+    var name = 'a.js';
+
+    var actualCodePath = path.resolve(__dirname, 'actual', name);
+    var actualCodeContent = fs.readFileSync(actualCodePath);
+
+    var expectCodePath = path.resolve(__dirname, 'expect', name);
+    var expectCodeContent = fs.readFileSync(expectCodePath);
+
+
+    var actualResult = createInstance('actual/' + name, actualCodeContent);
+    var actualJson = getRoot('actual/' + name);
+
+    var expectResult = createInstance('expect/' + name, expectCodeContent);
+    var expectJson = getRoot('expect/' + name);
+
+    expect(actualJson).eql(expectJson);
+  });
+})
\ No newline at end of file
diff --git a/weex-loader/webpack.config.js b/weex-loader/webpack.config.js
new file mode 100644
index 0000000..9686f60
--- /dev/null
+++ b/weex-loader/webpack.config.js
@@ -0,0 +1,51 @@
+var path = require('path');
+var webpack = require('webpack');
+var loader = require('./index.js');
+var scripter = require('weex-scripter');
+var styler = require('weex-styler');
+var templater = require('weex-templater');
+
+loader.useScripter(scripter);
+loader.useStyler(styler);
+loader.useTemplater(templater);
+
+var banner = 'var __weex_define__ = define, __weex_bootstrap__ = bootstrap;';
+
+var bannerPlugin = new webpack.BannerPlugin(banner, {
+  raw: true
+});
+
+module.exports = {
+  entry: './test/a.js?entry=true',
+  output: {
+    path: './test/actual',
+    filename: 'a.js'
+  },
+  module: {
+    loaders: [
+      {
+        test: /\.we(\?[^?]+)?$/,
+        loaders: ['index.js']
+      },
+      {
+        test: /\.js(\?[^?]+)?$/,
+        exclude: [
+          path.resolve(__dirname, 'test/lib')
+        ],
+        loaders: ['index.js?type=script', 'babel?presets[]=es2015']
+      },
+      {
+        test: /\.less(\?[^?]+)?$/, 
+        loaders: ['index.js?type=style', 'less']
+      },
+      {
+        test: /\.tpl(\?[^?]+)?$/, 
+        loaders: ['index.js?type=tpl']
+      }
+    ]
+  },
+  resolveLoader: {
+    modulesDirectories: ['./', './node_modules']
+  },
+  plugins: [bannerPlugin]
+}