1 | ;
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.ShaderLibPreprocessor = exports.ShaderLibPlugin = exports.ShaderLib = exports.kDefaultShaderName = exports.kDefaultShaderLibVersion = exports.kDefaultShaderLibPrecision = undefined;
|
7 |
|
8 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
9 |
|
10 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
11 |
|
12 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
13 |
|
14 | 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; }; }();
|
15 |
|
16 | var _dynamic = require('./dynamic');
|
17 |
|
18 | var _glsl = require('./glsl');
|
19 |
|
20 | var libglsl = _interopRequireWildcard(_glsl);
|
21 |
|
22 | var _command = require('./command');
|
23 |
|
24 | var _path = require('path');
|
25 |
|
26 | var _glslTokenDefines = require('glsl-token-defines');
|
27 |
|
28 | var _glslTokenDefines2 = _interopRequireDefault(_glslTokenDefines);
|
29 |
|
30 | var _glslTokenString = require('glsl-token-string');
|
31 |
|
32 | var _glslTokenString2 = _interopRequireDefault(_glslTokenString);
|
33 |
|
34 | var _glslInjectDefines = require('glsl-inject-defines');
|
35 |
|
36 | var _glslInjectDefines2 = _interopRequireDefault(_glslInjectDefines);
|
37 |
|
38 | var _glslTokenizer = require('glsl-tokenizer');
|
39 |
|
40 | var _glslTokenizer2 = _interopRequireDefault(_glslTokenizer);
|
41 |
|
42 | var _prepr = require('prepr');
|
43 |
|
44 | var _prepr2 = _interopRequireDefault(_prepr);
|
45 |
|
46 | var _defined = require('defined');
|
47 |
|
48 | var _defined2 = _interopRequireDefault(_defined);
|
49 |
|
50 | var _stringHash = require('string-hash');
|
51 |
|
52 | var _stringHash2 = _interopRequireDefault(_stringHash);
|
53 |
|
54 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
55 |
|
56 | 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; } }
|
57 |
|
58 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
59 |
|
60 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
61 |
|
62 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
63 |
|
64 | var kGLSLTokenPreprocecsor = 'preprocessor';
|
65 | var kGLSLTokenBlockComment = 'block-comment';
|
66 | var kGLSLTokenLineComment = 'line-comment';
|
67 | var kDefaultShaderLibPrecision = exports.kDefaultShaderLibPrecision = 'mediump float';
|
68 | var kDefaultShaderLibVersion = exports.kDefaultShaderLibVersion = '100';
|
69 | var kDefaultShaderName = exports.kDefaultShaderName = '<anonymous>';
|
70 |
|
71 | var ShaderLib = exports.ShaderLib = function () {
|
72 | _createClass(ShaderLib, null, [{
|
73 | key: 'defaults',
|
74 | value: function defaults() {
|
75 | return {
|
76 | precision: kDefaultShaderLibPrecision,
|
77 | shaderName: kDefaultShaderName,
|
78 | version: kDefaultShaderLibVersion,
|
79 | defines: {},
|
80 | name: kDefaultShaderName
|
81 | };
|
82 | }
|
83 | }]);
|
84 |
|
85 | function ShaderLib() {
|
86 | var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
87 | _ref$preprocessor = _ref.preprocessor,
|
88 | preprocessor = _ref$preprocessor === undefined ? undefined : _ref$preprocessor,
|
89 | _ref$middleware = _ref.middleware,
|
90 | middleware = _ref$middleware === undefined ? [] : _ref$middleware,
|
91 | _ref$precision = _ref.precision,
|
92 | precision = _ref$precision === undefined ? kDefaultShaderLibPrecision : _ref$precision,
|
93 | _ref$version = _ref.version,
|
94 | version = _ref$version === undefined ? kDefaultShaderLibVersion : _ref$version,
|
95 | _ref$defines = _ref.defines,
|
96 | defines = _ref$defines === undefined ? {} : _ref$defines,
|
97 | glsl = _ref.glsl;
|
98 |
|
99 | _classCallCheck(this, ShaderLib);
|
100 |
|
101 | this.cache = new _dynamic.DynamicValue(this);
|
102 | this.store = new _dynamic.DynamicValue(this);
|
103 | this.version = (0, _defined2.default)(version || kDefaultShaderLibVersion);
|
104 | this.precision = (0, _defined2.default)(precision, kDefaultShaderLibPrecision);
|
105 | this.middleware = (0, _defined2.default)(middleware, []);
|
106 | this.preprocessor = (0, _defined2.default)(preprocessor, new ShaderLibPreprocessor(this));
|
107 | this.preprocessor.define(defines);
|
108 | this.add(_extends({}, libglsl, glsl));
|
109 | }
|
110 |
|
111 | _createClass(ShaderLib, [{
|
112 | key: 'define',
|
113 | value: function define(key, value) {
|
114 | return this.preprocessor.define(key, value);
|
115 | }
|
116 | }, {
|
117 | key: 'injectShaderNameDefine',
|
118 | value: function injectShaderNameDefine(name, source) {
|
119 | var regex = /\s?#ifndef SHADER_NAME\s?\n#define SHADER_NAME\s?.*\n#endif\n?$/g;
|
120 | return String(source).replace(regex, '');
|
121 | }
|
122 | }, {
|
123 | key: 'injectShaderPrecision',
|
124 | value: function injectShaderPrecision(source) {
|
125 | var _precision = this.precision,
|
126 | precision = _precision === undefined ? kDefaultShaderLibPrecision : _precision;
|
127 |
|
128 | var header = 'precision ' + precision + ';';
|
129 | var regex = /[\s|\t]?precision\s+([a-z]+)\s+([a-z|A-Z]+)[\s+]?;[\s|\t|\r]?/g;
|
130 | source = source.replace(header, '').replace(regex, '');
|
131 | return header + '\n' + source;
|
132 | }
|
133 | }, {
|
134 | key: 'add',
|
135 | value: function add(name, source) {
|
136 | var _this = this;
|
137 |
|
138 | if ('string' == typeof name && 'string' == typeof source) {
|
139 | name = name.replace(/[\/]+/g, '/');
|
140 | this.store.set(name, source);
|
141 | } else if (name && 'object' == (typeof name === 'undefined' ? 'undefined' : _typeof(name))) {
|
142 | var walk = function walk(stack, scope) {
|
143 | for (var key in scope) {
|
144 | stack.push(key);
|
145 | if ('object' == _typeof(scope[key])) {
|
146 | walk(stack, scope[key]);
|
147 | } else {
|
148 | _this.add(stack.join('/'), scope[key]);
|
149 | }
|
150 | stack.pop();
|
151 | }
|
152 | };
|
153 | walk([], name);
|
154 | }
|
155 | return this;
|
156 | }
|
157 | }, {
|
158 | key: 'get',
|
159 | value: function get(path) {
|
160 | if ('string' == typeof path) {
|
161 | if ('string' == typeof this.store[path]) {
|
162 | return this.compile(path, this.store[path]);
|
163 | }
|
164 | }
|
165 | return null;
|
166 | }
|
167 | }, {
|
168 | key: 'resolve',
|
169 | value: function resolve(path) {
|
170 | var root = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : './';
|
171 |
|
172 | root = (0, _path.resolve)('/', root);
|
173 | path = path.replace((0, _path.extname)(path), '');
|
174 | path = (0, _path.resolve)(root, path).slice(1);
|
175 | return path;
|
176 | }
|
177 | }, {
|
178 | key: 'hash',
|
179 | value: function hash(source) {
|
180 | if ('string' == typeof source) {
|
181 | return (0, _stringHash2.default)(source);
|
182 | }
|
183 | return null;
|
184 | }
|
185 | }, {
|
186 | key: 'isCached',
|
187 | value: function isCached(source) {
|
188 | return 'string' == typeof this.cache[this.hash(source) || ''];
|
189 | }
|
190 | }, {
|
191 | key: 'preprocess',
|
192 | value: function preprocess(source) {
|
193 | var defines = this.defines;
|
194 |
|
195 | source = (0, _prepr2.default)(source, defines);
|
196 | source = source.split('\n').filter(function (line) {
|
197 | return false == /^\s*$/.test(line);
|
198 | }).join('\n');
|
199 | return source;
|
200 | }
|
201 | }, {
|
202 | key: 'compile',
|
203 | value: function compile(name, source) {
|
204 | if (!source && name) {
|
205 | source = name;name = null;
|
206 | }
|
207 | if (!name) {
|
208 | name = kDefaultShaderName;
|
209 | }
|
210 | if (!source) {
|
211 | return null;
|
212 | }
|
213 | var hash = this.hash(source);
|
214 | if (this.cache[hash]) {
|
215 | return this.cache[hash];
|
216 | }
|
217 | source = this.injectShaderNameDefine(name, source);
|
218 | source = this.preprocessor.process(name, source);
|
219 | source = this.injectShaderPrecision(source);
|
220 | source = source.split('\n').filter(function (line) {
|
221 | return line.length;
|
222 | }).map(function (line) {
|
223 | return 1 == line.length ? line + '\n' : line;
|
224 | }).join('\n') + '\n';
|
225 | this.cache.set(hash, source);
|
226 | return source;
|
227 | }
|
228 | }, {
|
229 | key: 'use',
|
230 | value: function use(middleware) {
|
231 | if ('function' == typeof middleware) {
|
232 | this.middleware.push(middleware);
|
233 | }
|
234 | return this;
|
235 | }
|
236 | }, {
|
237 | key: 'defines',
|
238 | get: function get() {
|
239 | var _ref2 = this.preprocessor || {},
|
240 | _ref2$defines = _ref2.defines,
|
241 | defines = _ref2$defines === undefined ? null : _ref2$defines;
|
242 |
|
243 | return defines;
|
244 | }
|
245 | }]);
|
246 |
|
247 | return ShaderLib;
|
248 | }();
|
249 |
|
250 | var ShaderLibPlugin = exports.ShaderLibPlugin = function (_Command) {
|
251 | _inherits(ShaderLibPlugin, _Command);
|
252 |
|
253 | function ShaderLibPlugin() {
|
254 | _classCallCheck(this, ShaderLibPlugin);
|
255 |
|
256 | return _possibleConstructorReturn(this, (ShaderLibPlugin.__proto__ || Object.getPrototypeOf(ShaderLibPlugin)).apply(this, arguments));
|
257 | }
|
258 |
|
259 | return ShaderLibPlugin;
|
260 | }(_command.Command);
|
261 |
|
262 | var ShaderLibPreprocessor = exports.ShaderLibPreprocessor = function () {
|
263 | function ShaderLibPreprocessor(shaderLib) {
|
264 | _classCallCheck(this, ShaderLibPreprocessor);
|
265 |
|
266 | this.defines = new _dynamic.DynamicValue(this);
|
267 | this.shaderLib = shaderLib;
|
268 | this.middleware = [];
|
269 | }
|
270 |
|
271 | _createClass(ShaderLibPreprocessor, [{
|
272 | key: 'define',
|
273 | value: function define(key, value) {
|
274 | var _this3 = this;
|
275 |
|
276 | if ('object' == (typeof key === 'undefined' ? 'undefined' : _typeof(key))) {
|
277 | return Object.keys(key).map(function (k) {
|
278 | return _this3.define(k, key[k]);
|
279 | }).some(function (v) {
|
280 | return true === v;
|
281 | });
|
282 | } else if ('string' == typeof key) {
|
283 | // boolean -> number
|
284 | if (true === value) {
|
285 | value = 1;
|
286 | } else if (false === value) {
|
287 | value = 0;
|
288 | }
|
289 | if (null != value) {
|
290 | // any -> string
|
291 | value = String(value);
|
292 | if (value != this.defines[key]) {
|
293 | this.defines.set(key, value);
|
294 | return true;
|
295 | } else {
|
296 | return false;
|
297 | }
|
298 | }
|
299 | }
|
300 | return false;
|
301 | }
|
302 | }, {
|
303 | key: 'undefine',
|
304 | value: function undefine(key) {
|
305 | this.defines.unset(key);
|
306 | return this;
|
307 | }
|
308 | }, {
|
309 | key: 'process',
|
310 | value: function process(name, source) {
|
311 | var _this4 = this;
|
312 |
|
313 | var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
314 | var shaderLib = this.shaderLib,
|
315 | defines = this.defines;
|
316 | var middleware = shaderLib.middleware,
|
317 | version = shaderLib.version;
|
318 |
|
319 | var includeStack = [];
|
320 | var stack = [];
|
321 | opts = !opts || 'object' != (typeof opts === 'undefined' ? 'undefined' : _typeof(opts)) ? {} : opts;
|
322 | if ('string' == typeof source) {
|
323 | source = (0, _glslInjectDefines2.default)(source, _extends({}, defines, opts.defines));
|
324 | }
|
325 | visit('\n' + source + '\n', stack, name != kDefaultShaderName ? (0, _path.dirname)(name) : '/');
|
326 | source = (0, _glslTokenString2.default)(stack);
|
327 | return middleware.filter(function (ware) {
|
328 | return 'function' == typeof ware;
|
329 | }).reduce(function (src, ware) {
|
330 | return (0, _defined2.default)(ware(shaderLib, _this4, src, opts), src);
|
331 | }, source).replace('#define GLSLIFY 1\n', '');
|
332 |
|
333 | function visit(source, stack, root) {
|
334 | var tokens = (0, _glslTokenizer2.default)(source, { version: version });
|
335 | var _iteratorNormalCompletion = true;
|
336 | var _didIteratorError = false;
|
337 | var _iteratorError = undefined;
|
338 |
|
339 | try {
|
340 | var _loop = function _loop() {
|
341 | var token = _step.value;
|
342 |
|
343 | var push = function push() {
|
344 | return stack.push(token);
|
345 | };
|
346 | switch (token.type) {
|
347 | case kGLSLTokenBlockComment:
|
348 | case kGLSLTokenLineComment:
|
349 | break;
|
350 | case kGLSLTokenPreprocecsor:
|
351 | var includeRegex = RegExp(/[\s|\t]?#include[\s]+([<|"]?.*[>|"]?)$/);
|
352 | var directive = token.data.match(/(#[a-z]+)\s?/)[0].trim();
|
353 | switch (directive) {
|
354 | case '#define':
|
355 | var match = token.data.match(/#define[\s]+(.*)/);
|
356 | if (match) {
|
357 | var kv = match[1].match(/.*[\s]+(.*)/);
|
358 | if (!kv) {
|
359 | token.data = token.data + ' 1';
|
360 | }
|
361 | }
|
362 | push();
|
363 | break;
|
364 |
|
365 | case '#include':
|
366 | var _ref3 = token.data.match(includeRegex) || [],
|
367 | _ref4 = _slicedToArray(_ref3, 2),
|
368 | statement = _ref4[0],
|
369 | arg = _ref4[1];
|
370 |
|
371 | var path = arg.replace(/^["|<](.*)["|>]/, '$1').trim();
|
372 | var left = arg[0].trim();
|
373 | var right = arg[arg.trim().length - 1].trim();
|
374 | var createError = function createError(ErrorType, msg) {
|
375 | return new ErrorType((msg || '') + '\n\tat (glsl) ' + includeStack.join('\n\tat (glsl) '));
|
376 | };
|
377 | if (-1 == ['<', '"'].indexOf(left)) {
|
378 | var msg = 'Unexpected token \'' + left + '\'. Expecting \'<\' or \'"\'.';
|
379 | throw createError(SyntaxError, msg);
|
380 | } else if (-1 == ['>', '"'].indexOf(right)) {
|
381 | var expected = '<' == left ? '\'>\'' : '\'"\'';
|
382 | var _msg = 'Unexpected token \'' + right + '\'. Expecting ' + expected + '.';
|
383 | throw createError(SyntaxError, _msg);
|
384 | }
|
385 |
|
386 | if ('<' == left && '>' != right) {
|
387 | var _msg2 = 'Unexpected token \'' + right + '\'. Expecting \'>\'.';
|
388 | throw createError(SyntaxError, _msg2);
|
389 | } else if ('"' == left && '"' != right) {
|
390 | var _msg3 = 'Unexpected token \'' + right + '\'. Expecting \'"\'.';
|
391 | throw createError(SyntaxError, _msg3);
|
392 | }
|
393 |
|
394 | var nextRoot = '<' == left && '>' == right ? '/' : root;
|
395 | var prefix = '.' != path[0] ? './' : '';
|
396 | var resolvedPath = shaderLib.resolve('' + prefix + path, nextRoot);
|
397 | var shader = shaderLib.get(resolvedPath);
|
398 | if (shader) {
|
399 | includeStack.push(path + ':' + token.line);
|
400 | visit(shader + '\n', stack, nextRoot);
|
401 | } else {
|
402 | throw createError(ReferenceError, 'glsl lib ' + arg + ' not found.');
|
403 | }
|
404 | includeStack.pop();
|
405 | break;
|
406 |
|
407 | default:
|
408 | push();
|
409 | }
|
410 | break;
|
411 |
|
412 | default:
|
413 | push();break;
|
414 | }
|
415 | };
|
416 |
|
417 | for (var _iterator = tokens[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
418 | _loop();
|
419 | }
|
420 | } catch (err) {
|
421 | _didIteratorError = true;
|
422 | _iteratorError = err;
|
423 | } finally {
|
424 | try {
|
425 | if (!_iteratorNormalCompletion && _iterator.return) {
|
426 | _iterator.return();
|
427 | }
|
428 | } finally {
|
429 | if (_didIteratorError) {
|
430 | throw _iteratorError;
|
431 | }
|
432 | }
|
433 | }
|
434 | }
|
435 | }
|
436 | }]);
|
437 |
|
438 | return ShaderLibPreprocessor;
|
439 | }();
|
440 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL3NoYWRlcmxpYi5qcyJdLCJuYW1lcyI6WyJsaWJnbHNsIiwia0dMU0xUb2tlblByZXByb2NlY3NvciIsImtHTFNMVG9rZW5CbG9ja0NvbW1lbnQiLCJrR0xTTFRva2VuTGluZUNvbW1lbnQiLCJrRGVmYXVsdFNoYWRlckxpYlByZWNpc2lvbiIsImtEZWZhdWx0U2hhZGVyTGliVmVyc2lvbiIsImtEZWZhdWx0U2hhZGVyTmFtZSIsIlNoYWRlckxpYiIsInByZWNpc2lvbiIsInNoYWRlck5hbWUiLCJ2ZXJzaW9uIiwiZGVmaW5lcyIsIm5hbWUiLCJwcmVwcm9jZXNzb3IiLCJ1bmRlZmluZWQiLCJtaWRkbGV3YXJlIiwiZ2xzbCIsImNhY2hlIiwic3RvcmUiLCJTaGFkZXJMaWJQcmVwcm9jZXNzb3IiLCJkZWZpbmUiLCJhZGQiLCJrZXkiLCJ2YWx1ZSIsInNvdXJjZSIsInJlZ2V4IiwiU3RyaW5nIiwicmVwbGFjZSIsImhlYWRlciIsInNldCIsIndhbGsiLCJzdGFjayIsInNjb3BlIiwicHVzaCIsImpvaW4iLCJwb3AiLCJwYXRoIiwiY29tcGlsZSIsInJvb3QiLCJzbGljZSIsImhhc2giLCJzcGxpdCIsImZpbHRlciIsImxpbmUiLCJ0ZXN0IiwiaW5qZWN0U2hhZGVyTmFtZURlZmluZSIsInByb2Nlc3MiLCJpbmplY3RTaGFkZXJQcmVjaXNpb24iLCJsZW5ndGgiLCJtYXAiLCJTaGFkZXJMaWJQbHVnaW4iLCJzaGFkZXJMaWIiLCJPYmplY3QiLCJrZXlzIiwiayIsInNvbWUiLCJ2IiwidW5zZXQiLCJvcHRzIiwiaW5jbHVkZVN0YWNrIiwidmlzaXQiLCJ3YXJlIiwicmVkdWNlIiwic3JjIiwidG9rZW5zIiwidG9rZW4iLCJ0eXBlIiwiaW5jbHVkZVJlZ2V4IiwiUmVnRXhwIiwiZGlyZWN0aXZlIiwiZGF0YSIsIm1hdGNoIiwidHJpbSIsImt2Iiwic3RhdGVtZW50IiwiYXJnIiwibGVmdCIsInJpZ2h0IiwiY3JlYXRlRXJyb3IiLCJFcnJvclR5cGUiLCJtc2ciLCJpbmRleE9mIiwiU3ludGF4RXJyb3IiLCJleHBlY3RlZCIsIm5leHRSb290IiwicHJlZml4IiwicmVzb2x2ZWRQYXRoIiwicmVzb2x2ZSIsInNoYWRlciIsImdldCIsIlJlZmVyZW5jZUVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7SUFBWUEsTzs7QUFDWjs7QUFFQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUFFQSxJQUFNQyx5QkFBeUIsY0FBL0I7QUFDQSxJQUFNQyx5QkFBeUIsZUFBL0I7QUFDQSxJQUFNQyx3QkFBd0IsY0FBOUI7QUFVTyxJQUFNQyxrRUFBNkIsZUFBbkM7QUFDQSxJQUFNQyw4REFBMkIsS0FBakM7QUFDQSxJQUFNQyxrREFBcUIsYUFBM0I7O0lBRU1DLFMsV0FBQUEsUzs7OytCQUNPO0FBQ2hCLGFBQU87QUFDTEMsbUJBQVdKLDBCQUROO0FBRUxLLG9CQUFZSCxrQkFGUDtBQUdMSSxpQkFBU0wsd0JBSEo7QUFJTE0saUJBQVMsRUFKSjtBQUtMQyxjQUFNTjtBQUxELE9BQVA7QUFPRDs7O0FBRUQsdUJBT1E7QUFBQSxtRkFBSixFQUFJO0FBQUEsaUNBTk5PLFlBTU07QUFBQSxRQU5OQSxZQU1NLHFDQU5TQyxTQU1UO0FBQUEsK0JBTE5DLFVBS007QUFBQSxRQUxOQSxVQUtNLG1DQUxPLEVBS1A7QUFBQSw4QkFKTlAsU0FJTTtBQUFBLFFBSk5BLFNBSU0sa0NBSk1KLDBCQUlOO0FBQUEsNEJBSE5NLE9BR007QUFBQSxRQUhOQSxPQUdNLGdDQUhJTCx3QkFHSjtBQUFBLDRCQUZOTSxPQUVNO0FBQUEsUUFGTkEsT0FFTSxnQ0FGSSxFQUVKO0FBQUEsUUFETkssSUFDTSxRQUROQSxJQUNNOztBQUFBOztBQUNOLFNBQUtDLEtBQUwsR0FBYSwwQkFBaUIsSUFBakIsQ0FBYjtBQUNBLFNBQUtDLEtBQUwsR0FBYSwwQkFBaUIsSUFBakIsQ0FB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WUFBZCxDQUFmO0FBQ0Esd0JBQUlFLE1BQUosRUFBWTtBQUNWN0IsbUNBQWExQixJQUFiLENBQXFCRyxJQUFyQixTQUE2QjZCLE1BQU10QixJQUFuQztBQUNBaUIsNEJBQU00QixTQUFTLElBQWYsRUFBcUJ6RCxLQUFyQixFQUE0QnFELFFBQTVCO0FBQ0QscUJBSEQsTUFHTztBQUNMLDRCQUFNTixZQUFZWSxjQUFaLGdCQUF3Q2YsR0FBeEMsaUJBQU47QUFDRDtBQUNEaEIsaUNBQWF4QixHQUFiO0FBQ0E7O0FBRUY7QUFBU0Y7QUFoRFg7QUFrREE7O0FBRUY7QUFBU0EsdUJBQVE7QUEzRG5CO0FBSmdDOztBQUVsQywrQkFBb0IrQixNQUFwQiw4SEFBNEI7QUFBQTtBQStEM0I7QUFqRWlDO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFrRW5DO0FBQ0YiLCJmaWxlIjoic2hhZGVybGliLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHluYW1pY1ZhbHVlIH0gZnJvbSAnLi9keW5hbWljJ1xuaW1wb3J0ICogYXMgbGliZ2xzbCBmcm9tICcuL2dsc2wnXG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnLi9jb21tYW5kJ1xuXG5pbXBvcnQgeyBkaXJuYW1lLCBleHRuYW1lLCByZXNvbHZlIH0gZnJvbSAncGF0aCdcbmltcG9ydCBnbHNsVG9rZW5zVG9EZWZpbmVzIGZyb20gJ2dsc2wtdG9rZW4tZGVmaW5lcydcbmltcG9ydCBnbHNsVG9rZW5zVG9TdHJpbmcgZnJvbSAnZ2xzbC10b2tlbi1zdHJpbmcnXG5pbXBvcnQgaW5qZWN0RGVmaW5lcyBmcm9tICdnbHNsLWluamVjdC1kZWZpbmVzJ1xuaW1wb3J0IGdsc2xUb2tlbml6ZSBmcm9tICdnbHNsLXRva2VuaXplcidcbmltcG9ydCBwcmVwcm9jZXNzIGZyb20gJ3ByZXByJ1xuaW1wb3J0IGNvYWxlc2NlIGZyb20gJ2RlZmluZWQnXG5pbXBvcnQgaGFzaCBmcm9tICdzdHJpbmctaGFzaCdcblxuY29uc3Qga0dMU0xUb2tlblByZXByb2NlY3NvciA9ICdwcmVwcm9jZXNzb3InXG5jb25zdCBrR0xTTFRva2VuQmxvY2tDb21tZW50ID0gJ2Jsb2NrLWNvbW1lbnQnXG5jb25zdCBrR0xTTFRva2VuTGluZUNvbW1lbnQgPSAnbGluZS1jb21tZW50J1xuY29uc3Qga0dMU0xUb2tlbldoaXRlc3BhY2UgPSAnd2hpdGVzcGFjZSdcbmNvbnN0IGtHTFNMVG9rZW5JZGVudGlmaWVyID0gJ2lkZW50J1xuY29uc3Qga0dMU0xUb2tlbk9wZXJhdG9yID0gJ29wZXJhdG9yJ1xuY29uc3Qga0dMU0xUb2tlbkJ1aWx0aW4gPSAnYnVpbHRpbidcbmNvbnN0IGtHTFNMVG9rZW5LZXl3b3JkID0gJ2tleXdvcmQnXG5jb25zdCBrR0xTTFRva2VuSW50ZWdlciA9ICdpbnRlZ2VyJ1xuY29uc3Qga0dMU0xUb2tlbkZsb2F0ID0gJ2Zsb2F0J1xuY29uc3Qga0dMU0xUb2tlbkVPRiA9ICdlb2YnXG5cbmV4cG9ydCBjb25zdCBrRGVmYXVsdFNoYWRlckxpYlByZWNpc2lvbiA9ICdtZWRpdW1wIGZsb2F0J1xuZXhwb3J0IGNvbnN0IGtEZWZhdWx0U2hhZGVyTGliVmVyc2lvbiA9ICcxMDAnXG5leHBvcnQgY29uc3Qga0RlZmF1bHRTaGFkZXJOYW1lID0gJzxhbm9ueW1vdXM+J1xuXG5leHBvcnQgY2xhc3MgU2hhZGVyTGliIHtcbiAgc3RhdGljIGRlZmF1bHRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBwcmVjaXNpb246IGtEZWZhdWx0U2hhZGVyTGliUHJlY2lzaW9uLFxuICAgICAgc2hhZGVyTmFtZToga0RlZmF1bHRTaGFkZXJOYW1lLFxuICAgICAgdmVyc2lvbjoga0RlZmF1bHRTaGFkZXJMaWJWZXJzaW9uLFxuICAgICAgZGVmaW5lczoge30sXG4gICAgICBuYW1lOiBrRGVmYXVsdFNoYWRlck5hbWUsXG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHByZXByb2Nlc3NvciA9IHVuZGVmaW5lZCxcbiAgICBtaWRkbGV3YXJlID0gW10sXG4gICAgcHJlY2lzaW9uID0ga0RlZmF1bHRTaGFkZXJMaWJQcmVjaXNpb24sXG4gICAgdmVyc2lvbiA9IGtEZWZhdWx0U2hhZGVyTGliVmVyc2lvbixcbiAgICBkZWZpbmVzID0ge30sXG4gICAgZ2xzbCxcbiAgfSA9IHt9KSB7XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBEeW5hbWljVmFsdWUodGhpcylcbiAgICB0aGlzLnN0b3JlID0gbmV3IER5bmFtaWNWYWx1ZSh0aGlzKVxuICAgIHRoaXMudmVyc2lvbiA9IGNvYWxlc2NlKHZlcnNpb24gfHwga0RlZmF1bHRTaGFkZXJMaWJWZXJzaW9uKVxuICAgIHRoaXMucHJlY2lzaW9uID0gY29hbGVzY2UocHJlY2lzaW9uLCBrRGVmYXVsdFNoYWRlckxpYlByZWNpc2lvbilcbiAgICB0aGlzLm1pZGRsZXdhcmUgPSBjb2FsZXNjZShtaWRkbGV3YXJlLCBbXSlcbiAgICB0aGlzLnByZXByb2Nlc3NvciA9IGNvYWxlc2NlKHByZXByb2Nlc3NvciwgbmV3IFNoYWRlckxpYlByZXByb2Nlc3Nvcih0aGlzKSlcbiAgICB0aGlzLnByZXByb2Nlc3Nvci5kZWZpbmUoZGVmaW5lcylcbiAgICB0aGlzLmFkZCh7IC4uLmxpYmdsc2wsIC4uLmdsc2wgfSlcbiAgfVxuXG4gIGdldCBkZWZpbmVzKCkge1xuICAgIGNvbnN0IHtkZWZpbmVzID0gbnVsbH0gPSB0aGlzLnByZXByb2Nlc3NvciB8fCB7fVxuICAgIHJldHVybiBkZWZpbmVzXG4gIH1cblxuICBkZWZpbmUoa2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLnByZXByb2Nlc3Nvci5kZWZpbmUoa2V5LCB2YWx1ZSlcbiAgfVxuXG4gIGluamVjdFNoYWRlck5hbWVEZWZpbmUobmFtZSwgc291cmNlKSB7XG4gICAgY29uc3QgcmVnZXggPVxuICAgICAgL1xccz8jaWZuZGVmIFNIQURFUl9OQU1FXFxzP1xcbiNkZWZpbmUgU0hBREVSX05BTUVcXHM/LipcXG4jZW5kaWZcXG4/JC9nXG4gICAgcmV0dXJuIFN0cmluZyhzb3VyY2UpLnJlcGxhY2UocmVnZXgsICcnKVxuICB9XG5cbiAgaW5qZWN0U2hhZGVyUHJlY2lzaW9uKHNvdXJjZSkge1xuICAgIGNvbnN0IHtwcmVjaXNpb24gPSBrRGVmYXVsdFNoYWRlckxpYlByZWNpc2lvbn0gPSB0aGlzXG4gICAgY29uc3QgaGVhZGVyID0gYHByZWNpc2lvbiAke3ByZWNpc2lvbn07YFxuICAgIGNvbnN0IHJlZ2V4ID1cbiAgICAgIC9bXFxzfFxcdF0/cHJlY2lzaW9uXFxzKyhbYS16XSspXFxzKyhbYS16fEEtWl0rKVtcXHMrXT87W1xcc3xcXHR8XFxyXT8vZ1xuICAgIHNvdXJjZSA9IHNvdXJjZVxuICAgICAgLnJlcGxhY2UoaGVhZGVyLCAnJylcbiAgICAgIC5yZXBsYWNlKHJlZ2V4LCAnJylcbiAgICByZXR1cm4gYCR7aGVhZGVyfVxcbiR7c291cmNlfWBcbiAgfVxuXG4gIGFkZChuYW1lLCBzb3VyY2UpIHtcbiAgICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIG5hbWUgJiYgJ3N0cmluZycgPT0gdHlwZW9mIHNvdXJjZSkge1xuICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZSgvW1xcL10rL2csICcvJylcbiAgICAgIHRoaXMuc3RvcmUuc2V0KG5hbWUsIHNvdXJjZSlcbiAgICB9IGVsc2UgaWYgKG5hbWUgJiYgJ29iamVjdCcgPT0gdHlwZW9mIG5hbWUpIHtcbiAgICAgIGNvbnN0IHdhbGsgPSAoc3RhY2ssIHNjb3BlKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHNjb3BlKSB7XG4gICAgICAgICAgc3RhY2sucHVzaChrZXkpXG4gICAgICAgICAgaWYgKCdvYmplY3QnID09IHR5cGVvZiBzY29wZVtrZXldKSB7IHdhbGsoc3RhY2ssIHNjb3BlW2tleV0pIH1cbiAgICAgICAgICBlbHNlIHsgdGhpcy5hZGQoc3RhY2suam9pbignLycpLCBzY29wZVtrZXldKSB9XG4gICAgICAgICAgc3RhY2sucG9wKClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgd2FsayhbXSwgbmFtZSlcbiAgICB9XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIGdldChwYXRoKSB7XG4gICAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBwYXRoKSB7XG4gICAgICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIHRoaXMuc3RvcmVbcGF0aF0pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGlsZShwYXRoLCB0aGlzLnN0b3JlW3BhdGhdKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgcmVzb2x2ZShwYXRoLCByb290ID0gJy4vJykge1xuICAgIHJvb3QgPSByZXNvbHZlKCcvJywgcm9vdClcbiAgICBwYXRoID0gcGF0aC5yZXBsYWNlKGV4dG5hbWUocGF0aCksICcnKVxuICAgIHBhdGggPSByZXNvbHZlKHJvb3QsIHBhdGgpLnNsaWNlKDEpXG4gICAgcmV0dXJuIHBhdGhcbiAgfVxuXG4gIGhhc2goc291cmNlKSB7XG4gICAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBzb3VyY2UpIHsgcmV0dXJuIGhhc2goc291cmNlKSB9XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGlzQ2FjaGVkKHNvdXJjZSkge1xuICAgIHJldHVybiAnc3RyaW5nJyA9PSB0eXBlb2YgdGhpcy5jYWNoZVt0aGlzLmhhc2goc291cmNlKSB8fCAnJ11cbiAgfVxuXG4gIHByZXByb2Nlc3Moc291cmNlKSB7XG4gICAgY29uc3Qge2RlZmluZXN9ID0gdGhpc1xuICAgIGxldCB3aGl0ZXNwYWNlID0gMFxuICAgIHNvdXJjZSA9IHByZXByb2Nlc3Moc291cmNlLCBkZWZpbmVzKVxuICAgIHNvdXJjZSA9IHNvdXJjZVxuICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgLmZpbHRlcigobGluZSkgPT4gZmFsc2UgPT0gL15cXHMqJC8udGVzdChsaW5lKSlcbiAgICAgIC5qb2luKCdcXG4nKVxuICAgIHJldHVybiBzb3VyY2VcbiAgfVxuXG4gIGNvbXBpbGUobmFtZSwgc291cmNlKSB7XG4gICAgaWYgKCFzb3VyY2UgJiYgbmFtZSkgeyBzb3VyY2UgPSBuYW1lOyBuYW1lID0gbnVsbCB9XG4gICAgaWYgKCFuYW1lKSB7IG5hbWUgPSBrRGVmYXVsdFNoYWRlck5hbWUgfVxuICAgIGlmICghc291cmNlKSB7IHJldHVybiBudWxsIH1cbiAgICBjb25zdCBoYXNoID0gdGhpcy5oYXNoKHNvdXJjZSlcbiAgICBpZiAodGhpcy5jYWNoZVtoYXNoXSkgeyByZXR1cm4gdGhpcy5jYWNoZVtoYXNoXSB9XG4gICAgc291cmNlID0gdGhpcy5pbmplY3RTaGFkZXJOYW1lRGVmaW5lKG5hbWUsIHNvdXJjZSlcbiAgICBzb3VyY2UgPSB0aGlzLnByZXByb2Nlc3Nvci5wcm9jZXNzKG5hbWUsIHNvdXJjZSlcbiAgICBzb3VyY2UgPSB0aGlzLmluamVjdFNoYWRlclByZWNpc2lvbihzb3VyY2UpXG4gICAgc291cmNlID0gc291cmNlXG4gICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAuZmlsdGVyKChsaW5lKSA9PiBsaW5lLmxlbmd0aClcbiAgICAgIC5tYXAoKGxpbmUpID0+IDEgPT0gbGluZS5sZW5ndGggPyBgJHtsaW5lfVxcbmAgOiBsaW5lKVxuICAgICAgLmpvaW4oJ1xcbicpXG4gICAgICArICdcXG4nXG4gICAgdGhpcy5jYWNoZS5zZXQoaGFzaCwgc291cmNlKVxuICAgIHJldHVybiBzb3VyY2VcbiAgfVxuXG4gIHVzZShtaWRkbGV3YXJlKSB7XG4gICAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIG1pZGRsZXdhcmUpIHtcbiAgICAgIHRoaXMubWlkZGxld2FyZS5wdXNoKG1pZGRsZXdhcmUpXG4gICAgfVxuICAgIHJldHVybiB0aGlzXG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNoYWRlckxpYlBsdWdpbiBleHRlbmRzIENvbW1hbmQgeyB9XG5cbmV4cG9ydCBjbGFzcyBTaGFkZXJMaWJQcmVwcm9jZXNzb3Ige1xuICBjb25zdHJ1Y3RvcihzaGFkZXJMaWIpIHtcbiAgICB0aGlzLmRlZmluZXMgPSBuZXcgRHluYW1pY1ZhbHVlKHRoaXMpXG4gICAgdGhpcy5zaGFkZXJMaWIgPSBzaGFkZXJMaWJcbiAgICB0aGlzLm1pZGRsZXdhcmUgPSBbXVxuICB9XG5cbiAgZGVmaW5lKGtleSwgdmFsdWUpIHtcbiAgICBpZiAoJ29iamVjdCcgPT0gdHlwZW9mIGtleSkge1xuICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGtleSlcbiAgICAgICAgLm1hcCgoaykgPT4gdGhpcy5kZWZpbmUoaywga2V5W2tdKSlcbiAgICAgICAgLnNvbWUoKHYpID0+IHRydWUgPT09IHYpXG4gICAgfSBlbHNlIGlmICgnc3RyaW5nJyA9PSB0eXBlb2Yga2V5KSB7XG4gICAgICAvLyBib29sZWFuIC0+IG51bWJlclxuICAgICAgaWYgKHRydWUgPT09IHZhbHVlKSB7IHZhbHVlID0gMSB9XG4gICAgICBlbHNlIGlmIChmYWxzZSA9PT0gdmFsdWUpIHsgdmFsdWUgPSAwIH1cbiAgICAgIGlmIChudWxsICE9IHZhbHVlKSB7XG4gICAgICAgIC8vIGFueSAtPiBzdHJpbmdcbiAgICAgICAgdmFsdWUgPSBTdHJpbmcodmFsdWUpXG4gICAgICAgIGlmICh2YWx1ZSAhPSB0aGlzLmRlZmluZXNba2V5XSkge1xuICAgICAgICAgIHRoaXMuZGVmaW5lcy5zZXQoa2V5LCB2YWx1ZSlcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgdW5kZWZpbmUoa2V5KSB7XG4gICAgdGhpcy5kZWZpbmVzLnVuc2V0KGtleSlcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgcHJvY2VzcyhuYW1lLCBzb3VyY2UsIG9wdHMgPSB7fSkge1xuICAgIGNvbnN0IHsgc2hhZGVyTGliLCBkZWZpbmVzIH0gPSB0aGlzXG4gICAgY29uc3QgeyBtaWRkbGV3YXJlLCB2ZXJzaW9uIH0gPSBzaGFkZXJMaWJcbiAgICBjb25zdCBpbmNsdWRlU3RhY2sgPSBbXVxuICAgIGNvbnN0IHN0YWNrID0gW11cbiAgICBvcHRzID0gIW9wdHMgfHwgJ29iamVjdCcgIT0gdHlwZW9mIG9wdHMgPyB7fSA6IG9wdHNcbiAgICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIHNvdXJjZSkge1xuICAgICAgc291cmNlID0gaW5qZWN0RGVmaW5lcyhzb3VyY2UsIHsgLi4uZGVmaW5lcywgLi4ub3B0cy5kZWZpbmVzIH0pXG4gICAgfVxuICAgIHZpc2l0KGBcXG4ke3NvdXJjZX1cXG5gLCBzdGFjaywgbmFtZSAhPSBrRGVmYXVsdFNoYWRlck5hbWUgPyBkaXJuYW1lKG5hbWUpIDogJy8nKVxuICAgIHNvdXJjZSA9IGdsc2xUb2tlbnNUb1N0cmluZyhzdGFjaylcbiAgICByZXR1cm4gbWlkZGxld2FyZVxuICAgICAgLmZpbHRlcigod2FyZSkgPT4gJ2Z1bmN0aW9uJyA9PSB0eXBlb2Ygd2FyZSlcbiAgICAgIC5yZWR1Y2UoKHNyYywgd2FyZSkgPT4ge1xuICAgICAgICByZXR1cm4gY29hbGVzY2Uod2FyZShzaGFkZXJMaWIsIHRoaXMsIHNyYywgb3B0cyksIHNyYylcbiAgICAgIH0sIHNvdXJjZSlcbiAgICAgIC5yZXBsYWNlKCcjZGVmaW5lIEdMU0xJRlkgMVxcbicsICcnKVxuXG4gICAgZnVuY3Rpb24gdmlzaXQoc291cmNlLCBzdGFjaywgcm9vdCkge1xuICAgICAgY29uc3QgdG9rZW5zID0gZ2xzbFRva2VuaXplKHNvdXJjZSwge3ZlcnNpb259KVxuICAgICAgZm9yIChjb25zdCB0b2tlbiBvZiB0b2tlbnMpIHtcbiAgICAgICAgY29uc3QgcHVzaCA9ICgpID0+IHN0YWNrLnB1c2godG9rZW4pXG4gICAgICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgICAgIGNhc2Uga0dMU0xUb2tlbkJsb2NrQ29tbWVudDpcbiAgICAgICAgICBjYXNlIGtHTFNMVG9rZW5MaW5lQ29tbWVudDpcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSBrR0xTTFRva2VuUHJlcHJvY2Vjc29yOlxuICAgICAgICAgICAgY29uc3QgaW5jbHVkZVJlZ2V4ID0gUmVnRXhwKC9bXFxzfFxcdF0/I2luY2x1ZGVbXFxzXSsoWzx8XCJdPy4qWz58XCJdPykkLylcbiAgICAgICAgICAgIGNvbnN0IGRpcmVjdGl2ZSA9IHRva2VuLmRhdGEubWF0Y2goLygjW2Etel0rKVxccz8vKVswXS50cmltKClcbiAgICAgICAgICAgIHN3aXRjaCAoZGlyZWN0aXZlKSB7XG4gICAgICAgICAgICAgIGNhc2UgJyNkZWZpbmUnOlxuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4uZGF0YS5tYXRjaCgvI2RlZmluZVtcXHNdKyguKikvKVxuICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgY29uc3Qga3YgPSBtYXRjaFsxXS5tYXRjaCgvLipbXFxzXSsoLiopLylcbiAgICAgICAgICAgICAgICAgIGlmICgha3YpIHsgdG9rZW4uZGF0YSA9IGAke3Rva2VuLmRhdGF9IDFgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcHVzaCgpXG4gICAgICAgICAgICAgICAgYnJlYWtcblxuICAgICAgICAgICAgICBjYXNlICcjaW5jbHVkZSc6XG4gICAgICAgICAgICAgICAgY29uc3QgW3N0YXRlbWVudCwgYXJnXSA9IHRva2VuLmRhdGEubWF0Y2goaW5jbHVkZVJlZ2V4KSB8fCBbXVxuICAgICAgICAgICAgICAgIGNvbnN0IHBhdGggPSBhcmcucmVwbGFjZSgvXltcInw8XSguKilbXCJ8Pl0vLCAnJDEnKS50cmltKClcbiAgICAgICAgICAgICAgICBjb25zdCBsZWZ0ID0gYXJnWzBdLnRyaW0oKVxuICAgICAgICAgICAgICAgIGNvbnN0IHJpZ2h0ID0gYXJnW2FyZy50cmltKCkubGVuZ3RoIC0gMV0udHJpbSgpXG4gICAgICAgICAgICAgICAgY29uc3QgY3JlYXRlRXJyb3IgPSAoRXJyb3JUeXBlLCBtc2cpID0+IG5ldyBFcnJvclR5cGUoXG4gICAgICAgICAgICAgICAgICBgJHttc2cgfHwgJyd9XFxuXFx0YXQgKGdsc2wpICR7aW5jbHVkZVN0YWNrLmpvaW4oJ1xcblxcdGF0IChnbHNsKSAnKX1gXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGlmICgtMSA9PSBbJzwnLCAnXCInXS5pbmRleE9mKGxlZnQpKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBtc2cgPSBgVW5leHBlY3RlZCB0b2tlbiAnJHtsZWZ0fScuIEV4cGVjdGluZyAnPCcgb3IgJ1wiJy5gXG4gICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVFcnJvcihTeW50YXhFcnJvciwgbXNnKVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoLTEgPT0gWyc+JywgJ1wiJ10uaW5kZXhPZihyaWdodCkpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkID0gJzwnID09IGxlZnQgPyBgJz4nYCA6IGAnXCInYFxuICAgICAgICAgICAgICAgICAgY29uc3QgbXNnID0gYFVuZXhwZWN0ZWQgdG9rZW4gJyR7cmlnaHR9Jy4gRXhwZWN0aW5nICR7ZXhwZWN0ZWR9LmBcbiAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUVycm9yKFN5bnRheEVycm9yLCBtc2cpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCc8JyA9PSBsZWZ0ICYmICc+JyAhPSByaWdodCkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgbXNnID0gYFVuZXhwZWN0ZWQgdG9rZW4gJyR7cmlnaHR9Jy4gRXhwZWN0aW5nICc+Jy5gXG4gICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVFcnJvcihTeW50YXhFcnJvciwgbXNnKVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoJ1wiJyA9PSBsZWZ0ICYmICdcIicgIT0gcmlnaHQpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG1zZyA9IGBVbmV4cGVjdGVkIHRva2VuICcke3JpZ2h0fScuIEV4cGVjdGluZyAnXCInLmBcbiAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUVycm9yKFN5bnRheEVycm9yLCBtc2cpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dFJvb3QgPSAnPCcgPT0gbGVmdCAmJiAnPicgPT0gcmlnaHQgPyAnLycgOiByb290XG4gICAgICAgICAgICAgICAgY29uc3QgcHJlZml4ID0gJy4nICE9IHBhdGhbMF0gPyAnLi8nIDogJydcbiAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlZFBhdGggPSBzaGFkZXJMaWIucmVzb2x2ZShgJHtwcmVmaXh9JHtwYXRofWAsIG5leHRSb290KVxuICAgICAgICAgICAgICAgIGNvbnN0IHNoYWRlciA9IHNoYWRlckxpYi5nZXQocmVzb2x2ZWRQYXRoKVxuICAgICAgICAgICAgICAgIGlmIChzaGFkZXIpIHtcbiAgICAgICAgICAgICAgICAgIGluY2x1ZGVTdGFjay5wdXNoKGAke3BhdGh9OiR7dG9rZW4ubGluZX1gKVxuICAgICAgICAgICAgICAgICAgdmlzaXQoc2hhZGVyICsgJ1xcbicsIHN0YWNrLCBuZXh0Um9vdClcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlRXJyb3IoUmVmZXJlbmNlRXJyb3IsIGBnbHNsIGxpYiAke2FyZ30gbm90IGZvdW5kLmApXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGluY2x1ZGVTdGFjay5wb3AoKVxuICAgICAgICAgICAgICAgIGJyZWFrXG5cbiAgICAgICAgICAgICAgZGVmYXVsdDogcHVzaCgpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgZGVmYXVsdDogcHVzaCgpOyBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0= |
\ | No newline at end of file |