source: trip-planner-front/node_modules/postcss-dir-pseudo-class/node_modules/postcss/lib/node.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 45.6 KB
Line 
1"use strict";
2
3exports.__esModule = true;
4exports.default = void 0;
5
6var _cssSyntaxError = _interopRequireDefault(require("./css-syntax-error"));
7
8var _stringifier = _interopRequireDefault(require("./stringifier"));
9
10var _stringify = _interopRequireDefault(require("./stringify"));
11
12function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
14function cloneNode(obj, parent) {
15 var cloned = new obj.constructor();
16
17 for (var i in obj) {
18 if (!obj.hasOwnProperty(i)) continue;
19 var value = obj[i];
20 var type = typeof value;
21
22 if (i === 'parent' && type === 'object') {
23 if (parent) cloned[i] = parent;
24 } else if (i === 'source') {
25 cloned[i] = value;
26 } else if (value instanceof Array) {
27 cloned[i] = value.map(function (j) {
28 return cloneNode(j, cloned);
29 });
30 } else {
31 if (type === 'object' && value !== null) value = cloneNode(value);
32 cloned[i] = value;
33 }
34 }
35
36 return cloned;
37}
38/**
39 * All node classes inherit the following common methods.
40 *
41 * @abstract
42 */
43
44
45var Node = /*#__PURE__*/function () {
46 /**
47 * @param {object} [defaults] Value for node properties.
48 */
49 function Node(defaults) {
50 if (defaults === void 0) {
51 defaults = {};
52 }
53
54 this.raws = {};
55
56 if (process.env.NODE_ENV !== 'production') {
57 if (typeof defaults !== 'object' && typeof defaults !== 'undefined') {
58 throw new Error('PostCSS nodes constructor accepts object, not ' + JSON.stringify(defaults));
59 }
60 }
61
62 for (var name in defaults) {
63 this[name] = defaults[name];
64 }
65 }
66 /**
67 * Returns a `CssSyntaxError` instance containing the original position
68 * of the node in the source, showing line and column numbers and also
69 * a small excerpt to facilitate debugging.
70 *
71 * If present, an input source map will be used to get the original position
72 * of the source, even from a previous compilation step
73 * (e.g., from Sass compilation).
74 *
75 * This method produces very useful error messages.
76 *
77 * @param {string} message Error description.
78 * @param {object} [opts] Options.
79 * @param {string} opts.plugin Plugin name that created this error.
80 * PostCSS will set it automatically.
81 * @param {string} opts.word A word inside a node’s string that should
82 * be highlighted as the source of the error.
83 * @param {number} opts.index An index inside a node’s string that should
84 * be highlighted as the source of the error.
85 *
86 * @return {CssSyntaxError} Error object to throw it.
87 *
88 * @example
89 * if (!variables[name]) {
90 * throw decl.error('Unknown variable ' + name, { word: name })
91 * // CssSyntaxError: postcss-vars:a.sass:4:3: Unknown variable $black
92 * // color: $black
93 * // a
94 * // ^
95 * // background: white
96 * }
97 */
98
99
100 var _proto = Node.prototype;
101
102 _proto.error = function error(message, opts) {
103 if (opts === void 0) {
104 opts = {};
105 }
106
107 if (this.source) {
108 var pos = this.positionBy(opts);
109 return this.source.input.error(message, pos.line, pos.column, opts);
110 }
111
112 return new _cssSyntaxError.default(message);
113 }
114 /**
115 * This method is provided as a convenience wrapper for {@link Result#warn}.
116 *
117 * @param {Result} result The {@link Result} instance
118 * that will receive the warning.
119 * @param {string} text Warning message.
120 * @param {object} [opts] Options
121 * @param {string} opts.plugin Plugin name that created this warning.
122 * PostCSS will set it automatically.
123 * @param {string} opts.word A word inside a node’s string that should
124 * be highlighted as the source of the warning.
125 * @param {number} opts.index An index inside a node’s string that should
126 * be highlighted as the source of the warning.
127 *
128 * @return {Warning} Created warning object.
129 *
130 * @example
131 * const plugin = postcss.plugin('postcss-deprecated', () => {
132 * return (root, result) => {
133 * root.walkDecls('bad', decl => {
134 * decl.warn(result, 'Deprecated property bad')
135 * })
136 * }
137 * })
138 */
139 ;
140
141 _proto.warn = function warn(result, text, opts) {
142 var data = {
143 node: this
144 };
145
146 for (var i in opts) {
147 data[i] = opts[i];
148 }
149
150 return result.warn(text, data);
151 }
152 /**
153 * Removes the node from its parent and cleans the parent properties
154 * from the node and its children.
155 *
156 * @example
157 * if (decl.prop.match(/^-webkit-/)) {
158 * decl.remove()
159 * }
160 *
161 * @return {Node} Node to make calls chain.
162 */
163 ;
164
165 _proto.remove = function remove() {
166 if (this.parent) {
167 this.parent.removeChild(this);
168 }
169
170 this.parent = undefined;
171 return this;
172 }
173 /**
174 * Returns a CSS string representing the node.
175 *
176 * @param {stringifier|syntax} [stringifier] A syntax to use
177 * in string generation.
178 *
179 * @return {string} CSS string of this node.
180 *
181 * @example
182 * postcss.rule({ selector: 'a' }).toString() //=> "a {}"
183 */
184 ;
185
186 _proto.toString = function toString(stringifier) {
187 if (stringifier === void 0) {
188 stringifier = _stringify.default;
189 }
190
191 if (stringifier.stringify) stringifier = stringifier.stringify;
192 var result = '';
193 stringifier(this, function (i) {
194 result += i;
195 });
196 return result;
197 }
198 /**
199 * Returns an exact clone of the node.
200 *
201 * The resulting cloned node and its (cloned) children will retain
202 * code style properties.
203 *
204 * @param {object} [overrides] New properties to override in the clone.
205 *
206 * @example
207 * decl.raws.before //=> "\n "
208 * const cloned = decl.clone({ prop: '-moz-' + decl.prop })
209 * cloned.raws.before //=> "\n "
210 * cloned.toString() //=> -moz-transform: scale(0)
211 *
212 * @return {Node} Clone of the node.
213 */
214 ;
215
216 _proto.clone = function clone(overrides) {
217 if (overrides === void 0) {
218 overrides = {};
219 }
220
221 var cloned = cloneNode(this);
222
223 for (var name in overrides) {
224 cloned[name] = overrides[name];
225 }
226
227 return cloned;
228 }
229 /**
230 * Shortcut to clone the node and insert the resulting cloned node
231 * before the current node.
232 *
233 * @param {object} [overrides] Mew properties to override in the clone.
234 *
235 * @example
236 * decl.cloneBefore({ prop: '-moz-' + decl.prop })
237 *
238 * @return {Node} New node
239 */
240 ;
241
242 _proto.cloneBefore = function cloneBefore(overrides) {
243 if (overrides === void 0) {
244 overrides = {};
245 }
246
247 var cloned = this.clone(overrides);
248 this.parent.insertBefore(this, cloned);
249 return cloned;
250 }
251 /**
252 * Shortcut to clone the node and insert the resulting cloned node
253 * after the current node.
254 *
255 * @param {object} [overrides] New properties to override in the clone.
256 *
257 * @return {Node} New node.
258 */
259 ;
260
261 _proto.cloneAfter = function cloneAfter(overrides) {
262 if (overrides === void 0) {
263 overrides = {};
264 }
265
266 var cloned = this.clone(overrides);
267 this.parent.insertAfter(this, cloned);
268 return cloned;
269 }
270 /**
271 * Inserts node(s) before the current node and removes the current node.
272 *
273 * @param {...Node} nodes Mode(s) to replace current one.
274 *
275 * @example
276 * if (atrule.name === 'mixin') {
277 * atrule.replaceWith(mixinRules[atrule.params])
278 * }
279 *
280 * @return {Node} Current node to methods chain.
281 */
282 ;
283
284 _proto.replaceWith = function replaceWith() {
285 if (this.parent) {
286 for (var _len = arguments.length, nodes = new Array(_len), _key = 0; _key < _len; _key++) {
287 nodes[_key] = arguments[_key];
288 }
289
290 for (var _i = 0, _nodes = nodes; _i < _nodes.length; _i++) {
291 var node = _nodes[_i];
292 this.parent.insertBefore(this, node);
293 }
294
295 this.remove();
296 }
297
298 return this;
299 }
300 /**
301 * Returns the next child of the node’s parent.
302 * Returns `undefined` if the current node is the last child.
303 *
304 * @return {Node|undefined} Next node.
305 *
306 * @example
307 * if (comment.text === 'delete next') {
308 * const next = comment.next()
309 * if (next) {
310 * next.remove()
311 * }
312 * }
313 */
314 ;
315
316 _proto.next = function next() {
317 if (!this.parent) return undefined;
318 var index = this.parent.index(this);
319 return this.parent.nodes[index + 1];
320 }
321 /**
322 * Returns the previous child of the node’s parent.
323 * Returns `undefined` if the current node is the first child.
324 *
325 * @return {Node|undefined} Previous node.
326 *
327 * @example
328 * const annotation = decl.prev()
329 * if (annotation.type === 'comment') {
330 * readAnnotation(annotation.text)
331 * }
332 */
333 ;
334
335 _proto.prev = function prev() {
336 if (!this.parent) return undefined;
337 var index = this.parent.index(this);
338 return this.parent.nodes[index - 1];
339 }
340 /**
341 * Insert new node before current node to current node’s parent.
342 *
343 * Just alias for `node.parent.insertBefore(node, add)`.
344 *
345 * @param {Node|object|string|Node[]} add New node.
346 *
347 * @return {Node} This node for methods chain.
348 *
349 * @example
350 * decl.before('content: ""')
351 */
352 ;
353
354 _proto.before = function before(add) {
355 this.parent.insertBefore(this, add);
356 return this;
357 }
358 /**
359 * Insert new node after current node to current node’s parent.
360 *
361 * Just alias for `node.parent.insertAfter(node, add)`.
362 *
363 * @param {Node|object|string|Node[]} add New node.
364 *
365 * @return {Node} This node for methods chain.
366 *
367 * @example
368 * decl.after('color: black')
369 */
370 ;
371
372 _proto.after = function after(add) {
373 this.parent.insertAfter(this, add);
374 return this;
375 };
376
377 _proto.toJSON = function toJSON() {
378 var fixed = {};
379
380 for (var name in this) {
381 if (!this.hasOwnProperty(name)) continue;
382 if (name === 'parent') continue;
383 var value = this[name];
384
385 if (value instanceof Array) {
386 fixed[name] = value.map(function (i) {
387 if (typeof i === 'object' && i.toJSON) {
388 return i.toJSON();
389 } else {
390 return i;
391 }
392 });
393 } else if (typeof value === 'object' && value.toJSON) {
394 fixed[name] = value.toJSON();
395 } else {
396 fixed[name] = value;
397 }
398 }
399
400 return fixed;
401 }
402 /**
403 * Returns a {@link Node#raws} value. If the node is missing
404 * the code style property (because the node was manually built or cloned),
405 * PostCSS will try to autodetect the code style property by looking
406 * at other nodes in the tree.
407 *
408 * @param {string} prop Name of code style property.
409 * @param {string} [defaultType] Name of default value, it can be missed
410 * if the value is the same as prop.
411 *
412 * @example
413 * const root = postcss.parse('a { background: white }')
414 * root.nodes[0].append({ prop: 'color', value: 'black' })
415 * root.nodes[0].nodes[1].raws.before //=> undefined
416 * root.nodes[0].nodes[1].raw('before') //=> ' '
417 *
418 * @return {string} Code style value.
419 */
420 ;
421
422 _proto.raw = function raw(prop, defaultType) {
423 var str = new _stringifier.default();
424 return str.raw(this, prop, defaultType);
425 }
426 /**
427 * Finds the Root instance of the node’s tree.
428 *
429 * @example
430 * root.nodes[0].nodes[0].root() === root
431 *
432 * @return {Root} Root parent.
433 */
434 ;
435
436 _proto.root = function root() {
437 var result = this;
438
439 while (result.parent) {
440 result = result.parent;
441 }
442
443 return result;
444 }
445 /**
446 * Clear the code style properties for the node and its children.
447 *
448 * @param {boolean} [keepBetween] Keep the raws.between symbols.
449 *
450 * @return {undefined}
451 *
452 * @example
453 * node.raws.before //=> ' '
454 * node.cleanRaws()
455 * node.raws.before //=> undefined
456 */
457 ;
458
459 _proto.cleanRaws = function cleanRaws(keepBetween) {
460 delete this.raws.before;
461 delete this.raws.after;
462 if (!keepBetween) delete this.raws.between;
463 };
464
465 _proto.positionInside = function positionInside(index) {
466 var string = this.toString();
467 var column = this.source.start.column;
468 var line = this.source.start.line;
469
470 for (var i = 0; i < index; i++) {
471 if (string[i] === '\n') {
472 column = 1;
473 line += 1;
474 } else {
475 column += 1;
476 }
477 }
478
479 return {
480 line: line,
481 column: column
482 };
483 };
484
485 _proto.positionBy = function positionBy(opts) {
486 var pos = this.source.start;
487
488 if (opts.index) {
489 pos = this.positionInside(opts.index);
490 } else if (opts.word) {
491 var index = this.toString().indexOf(opts.word);
492 if (index !== -1) pos = this.positionInside(index);
493 }
494
495 return pos;
496 }
497 /**
498 * @memberof Node#
499 * @member {string} type String representing the node’s type.
500 * Possible values are `root`, `atrule`, `rule`,
501 * `decl`, or `comment`.
502 *
503 * @example
504 * postcss.decl({ prop: 'color', value: 'black' }).type //=> 'decl'
505 */
506
507 /**
508 * @memberof Node#
509 * @member {Container} parent The node’s parent node.
510 *
511 * @example
512 * root.nodes[0].parent === root
513 */
514
515 /**
516 * @memberof Node#
517 * @member {source} source The input source of the node.
518 *
519 * The property is used in source map generation.
520 *
521 * If you create a node manually (e.g., with `postcss.decl()`),
522 * that node will not have a `source` property and will be absent
523 * from the source map. For this reason, the plugin developer should
524 * consider cloning nodes to create new ones (in which case the new node’s
525 * source will reference the original, cloned node) or setting
526 * the `source` property manually.
527 *
528 * ```js
529 * // Bad
530 * const prefixed = postcss.decl({
531 * prop: '-moz-' + decl.prop,
532 * value: decl.value
533 * })
534 *
535 * // Good
536 * const prefixed = decl.clone({ prop: '-moz-' + decl.prop })
537 * ```
538 *
539 * ```js
540 * if (atrule.name === 'add-link') {
541 * const rule = postcss.rule({ selector: 'a', source: atrule.source })
542 * atrule.parent.insertBefore(atrule, rule)
543 * }
544 * ```
545 *
546 * @example
547 * decl.source.input.from //=> '/home/ai/a.sass'
548 * decl.source.start //=> { line: 10, column: 2 }
549 * decl.source.end //=> { line: 10, column: 12 }
550 */
551
552 /**
553 * @memberof Node#
554 * @member {object} raws Information to generate byte-to-byte equal
555 * node string as it was in the origin input.
556 *
557 * Every parser saves its own properties,
558 * but the default CSS parser uses:
559 *
560 * * `before`: the space symbols before the node. It also stores `*`
561 * and `_` symbols before the declaration (IE hack).
562 * * `after`: the space symbols after the last child of the node
563 * to the end of the node.
564 * * `between`: the symbols between the property and value
565 * for declarations, selector and `{` for rules, or last parameter
566 * and `{` for at-rules.
567 * * `semicolon`: contains true if the last child has
568 * an (optional) semicolon.
569 * * `afterName`: the space between the at-rule name and its parameters.
570 * * `left`: the space symbols between `/*` and the comment’s text.
571 * * `right`: the space symbols between the comment’s text
572 * and <code>*&#47;</code>.
573 * * `important`: the content of the important statement,
574 * if it is not just `!important`.
575 *
576 * PostCSS cleans selectors, declaration values and at-rule parameters
577 * from comments and extra spaces, but it stores origin content in raws
578 * properties. As such, if you don’t change a declaration’s value,
579 * PostCSS will use the raw value with comments.
580 *
581 * @example
582 * const root = postcss.parse('a {\n color:black\n}')
583 * root.first.first.raws //=> { before: '\n ', between: ':' }
584 */
585 ;
586
587 return Node;
588}();
589
590var _default = Node;
591/**
592 * @typedef {object} position
593 * @property {number} line Source line in file.
594 * @property {number} column Source column in file.
595 */
596
597/**
598 * @typedef {object} source
599 * @property {Input} input {@link Input} with input file
600 * @property {position} start The starting position of the node’s source.
601 * @property {position} end The ending position of the node’s source.
602 */
603
604exports.default = _default;
605module.exports = exports.default;
606//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGUuZXM2Il0sIm5hbWVzIjpbImNsb25lTm9kZSIsIm9iaiIsInBhcmVudCIsImNsb25lZCIsImNvbnN0cnVjdG9yIiwiaSIsImhhc093blByb3BlcnR5IiwidmFsdWUiLCJ0eXBlIiwiQXJyYXkiLCJtYXAiLCJqIiwiTm9kZSIsImRlZmF1bHRzIiwicmF3cyIsInByb2Nlc3MiLCJlbnYiLCJOT0RFX0VOViIsIkVycm9yIiwiSlNPTiIsInN0cmluZ2lmeSIsIm5hbWUiLCJlcnJvciIsIm1lc3NhZ2UiLCJvcHRzIiwic291cmNlIiwicG9zIiwicG9zaXRpb25CeSIsImlucHV0IiwibGluZSIsImNvbHVtbiIsIkNzc1N5bnRheEVycm9yIiwid2FybiIsInJlc3VsdCIsInRleHQiLCJkYXRhIiwibm9kZSIsInJlbW92ZSIsInJlbW92ZUNoaWxkIiwidW5kZWZpbmVkIiwidG9TdHJpbmciLCJzdHJpbmdpZmllciIsImNsb25lIiwib3ZlcnJpZGVzIiwiY2xvbmVCZWZvcmUiLCJpbnNlcnRCZWZvcmUiLCJjbG9uZUFmdGVyIiwiaW5zZXJ0QWZ0ZXIiLCJyZXBsYWNlV2l0aCIsIm5vZGVzIiwibmV4dCIsImluZGV4IiwicHJldiIsImJlZm9yZSIsImFkZCIsImFmdGVyIiwidG9KU09OIiwiZml4ZWQiLCJyYXciLCJwcm9wIiwiZGVmYXVsdFR5cGUiLCJzdHIiLCJTdHJpbmdpZmllciIsInJvb3QiLCJjbGVhblJhd3MiLCJrZWVwQmV0d2VlbiIsImJldHdlZW4iLCJwb3NpdGlvbkluc2lkZSIsInN0cmluZyIsInN0YXJ0Iiwid29yZCIsImluZGV4T2YiXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxTQUFTQSxTQUFULENBQW9CQyxHQUFwQixFQUF5QkMsTUFBekIsRUFBaUM7QUFDL0IsTUFBSUMsTUFBTSxHQUFHLElBQUlGLEdBQUcsQ0FBQ0csV0FBUixFQUFiOztBQUVBLE9BQUssSUFBSUMsQ0FBVCxJQUFjSixHQUFkLEVBQW1C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Y3NzLXN5bnRheC1lcnJvcidcbmltcG9ydCBTdHJpbmdpZmllciBmcm9tICcuL3N0cmluZ2lmaWVyJ1xuaW1wb3J0IHN0cmluZ2lmeSBmcm9tICcuL3N0cmluZ2lmeSdcblxuZnVuY3Rpb24gY2xvbmVOb2RlIChvYmosIHBhcmVudCkge1xuICBsZXQgY2xvbmVkID0gbmV3IG9iai5jb25zdHJ1Y3RvcigpXG5cbiAgZm9yIChsZXQgaSBpbiBvYmopIHtcbiAgICBpZiAoIW9iai5oYXNPd25Qcm9wZXJ0eShpKSkgY29udGludWVcbiAgICBsZXQgdmFsdWUgPSBvYmpbaV1cbiAgICBsZXQgdHlwZSA9IHR5cGVvZiB2YWx1ZVxuXG4gICAgaWYgKGkgPT09ICdwYXJlbnQnICYmIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAocGFyZW50KSBjbG9uZWRbaV0gPSBwYXJlbnRcbiAgICB9IGVsc2UgaWYgKGkgPT09ICdzb3VyY2UnKSB7XG4gICAgICBjbG9uZWRbaV0gPSB2YWx1ZVxuICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgY2xvbmVkW2ldID0gdmFsdWUubWFwKGogPT4gY2xvbmVOb2RlKGosIGNsb25lZCkpXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCkgdmFsdWUgPSBjbG9uZU5vZGUodmFsdWUpXG4gICAgICBjbG9uZWRbaV0gPSB2YWx1ZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjbG9uZWRcbn1cblxuLyoqXG4gKiBBbGwgbm9kZSBjbGFzc2VzIGluaGVyaXQgdGhlIGZvbGxvd2luZyBjb21tb24gbWV0aG9kcy5cbiAqXG4gKiBAYWJzdHJhY3RcbiAqL1xuY2xhc3MgTm9kZSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2RlZmF1bHRzXSBWYWx1ZSBmb3Igbm9kZSBwcm9wZXJ0aWVzLlxuICAgKi9cbiAgY29uc3RydWN0b3IgKGRlZmF1bHRzID0geyB9KSB7XG4gICAgdGhpcy5yYXdzID0geyB9XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGlmICh0eXBlb2YgZGVmYXVsdHMgIT09ICdvYmplY3QnICYmIHR5cGVvZiBkZWZhdWx0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdQb3N0Q1NTIG5vZGVzIGNvbnN0cnVjdG9yIGFjY2VwdHMgb2JqZWN0LCBub3QgJyArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZGVmYXVsdHMpXG4gICAgICAgIClcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yIChsZXQgbmFtZSBpbiBkZWZhdWx0cykge1xuICAgICAgdGhpc1tuYW1lXSA9IGRlZmF1bHRzW25hbWVdXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBgQ3NzU3ludGF4RXJyb3JgIGluc3RhbmNlIGNvbnRhaW5pbmcgdGhlIG9yaWdpbmFsIHBvc2l0aW9uXG4gICAqIG9mIHRoZSBub2RlIGluIHRoZSBzb3VyY2UsIHNob3dpbmcgbGluZSBhbmQgY29sdW1uIG51bWJlcnMgYW5kIGFsc29cbiAgICogYSBzbWFsbCBleGNlcnB0IHRvIGZhY2lsaXRhdGUgZGVidWdnaW5nLlxuICAgKlxuICAgKiBJZiBwcmVzZW50LCBhbiBpbnB1dCBzb3VyY2UgbWFwIHdpbGwgYmUgdXNlZCB0byBnZXQgdGhlIG9yaWdpbmFsIHBvc2l0aW9uXG4gICAqIG9mIHRoZSBzb3VyY2UsIGV2ZW4gZnJvbSBhIHByZXZpb3VzIGNvbXBpbGF0aW9uIHN0ZXBcbiAgICogKGUuZy4sIGZyb20gU2FzcyBjb21waWxhdGlvbikuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIHByb2R1Y2VzIHZlcnkgdXNlZnVsIGVycm9yIG1lc3NhZ2VzLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAgICAgRXJyb3IgZGVzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0c10gICAgICBPcHRpb25zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0cy5wbHVnaW4gUGx1Z2luIG5hbWUgdGhhdCBjcmVhdGVkIHRoaXMgZXJyb3IuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3N0Q1NTIHdpbGwgc2V0IGl0IGF1dG9tYXRpY2FsbHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLndvcmQgICBBIHdvcmQgaW5zaWRlIGEgbm9kZeKAmXMgc3RyaW5nIHRoYXQgc2hvdWxkXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZSBoaWdobGlnaHRlZCBhcyB0aGUgc291cmNlIG9mIHRoZSBlcnJvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9wdHMuaW5kZXggIEFuIGluZGV4IGluc2lkZSBhIG5vZGXigJlzIHN0cmluZyB0aGF0IHNob3VsZFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmUgaGlnaGxpZ2h0ZWQgYXMgdGhlIHNvdXJjZSBvZiB0aGUgZXJyb3IuXG4gICAqXG4gICAqIEByZXR1cm4ge0Nzc1N5bnRheEVycm9yfSBFcnJvciBvYmplY3QgdG8gdGhyb3cgaXQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGlmICghdmFyaWFibGVzW25hbWVdKSB7XG4gICAqICAgdGhyb3cgZGVjbC5lcnJvcignVW5rbm93biB2YXJpYWJsZSAnICsgbmFtZSwgeyB3b3JkOiBuYW1lIH0pXG4gICAqICAgLy8gQ3NzU3ludGF4RXJyb3I6IHBvc3Rjc3MtdmFyczphLnNhc3M6NDozOiBVbmtub3duIHZhcmlhYmxlICRibGFja1xuICAgKiAgIC8vICAgY29sb3I6ICRibGFja1xuICAgKiAgIC8vIGFcbiAgICogICAvLyAgICAgICAgICBeXG4gICAqICAgLy8gICBiYWNrZ3JvdW5kOiB3aGl0ZVxuICAgKiB9XG4gICAqL1xuICBlcnJvciAobWVzc2FnZSwgb3B0cyA9IHsgfSkge1xuICAgIGlmICh0aGlzLnNvdXJjZSkge1xuICAgICAgbGV0IHBvcyA9IHRoaXMucG9zaXRpb25CeShvcHRzKVxuICAgICAgcmV0dXJuIHRoaXMuc291cmNlLmlucHV0LmVycm9yKG1lc3NhZ2UsIHBvcy5saW5lLCBwb3MuY29sdW1uLCBvcHRzKVxuICAgIH1cbiAgICByZXR1cm4gbmV3IENzc1N5bnRheEVycm9yKG1lc3NhZ2UpXG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgYXMgYSBjb252ZW5pZW5jZSB3cmFwcGVyIGZvciB7QGxpbmsgUmVzdWx0I3dhcm59LlxuICAgKlxuICAgKiBAcGFyYW0ge1Jlc3VsdH0gcmVzdWx0ICAgICAgVGhlIHtAbGluayBSZXN1bHR9IGluc3RhbmNlXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0IHdpbGwgcmVjZWl2ZSB0aGUgd2FybmluZy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgICAgICAgIFdhcm5pbmcgbWVzc2FnZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IFtvcHRzXSAgICAgIE9wdGlvbnNcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wdHMucGx1Z2luIFBsdWdpbiBuYW1lIHRoYXQgY3JlYXRlZCB0aGlzIHdhcm5pbmcuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3N0Q1NTIHdpbGwgc2V0IGl0IGF1dG9tYXRpY2FsbHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLndvcmQgICBBIHdvcmQgaW5zaWRlIGEgbm9kZeKAmXMgc3RyaW5nIHRoYXQgc2hvdWxkXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZSBoaWdobGlnaHRlZCBhcyB0aGUgc291cmNlIG9mIHRoZSB3YXJuaW5nLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb3B0cy5pbmRleCAgQW4gaW5kZXggaW5zaWRlIGEgbm9kZeKAmXMgc3RyaW5nIHRoYXQgc2hvdWxkXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZSBoaWdobGlnaHRlZCBhcyB0aGUgc291cmNlIG9mIHRoZSB3YXJuaW5nLlxuICAgKlxuICAgKiBAcmV0dXJuIHtXYXJuaW5nfSBDcmVhdGVkIHdhcm5pbmcgb2JqZWN0LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCBwbHVnaW4gPSBwb3N0Y3NzLnBsdWdpbigncG9zdGNzcy1kZXByZWNhdGVkJywgKCkgPT4ge1xuICAgKiAgIHJldHVybiAocm9vdCwgcmVzdWx0KSA9PiB7XG4gICAqICAgICByb290LndhbGtEZWNscygnYmFkJywgZGVjbCA9PiB7XG4gICAqICAgICAgIGRlY2wud2FybihyZXN1bHQsICdEZXByZWNhdGVkIHByb3BlcnR5IGJhZCcpXG4gICAqICAgICB9KVxuICAgKiAgIH1cbiAgICogfSlcbiAgICovXG4gIHdhcm4gKHJlc3VsdCwgdGV4dCwgb3B0cykge1xuICAgIGxldCBkYXRhID0geyBub2RlOiB0aGlzIH1cbiAgICBmb3IgKGxldCBpIGluIG9wdHMpIGRhdGFbaV0gPSBvcHRzW2ldXG4gICAgcmV0dXJuIHJlc3VsdC53YXJuKHRleHQsIGRhdGEpXG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgbm9kZSBmcm9tIGl0cyBwYXJlbnQgYW5kIGNsZWFucyB0aGUgcGFyZW50IHByb3BlcnRpZXNcbiAgICogZnJvbSB0aGUgbm9kZSBhbmQgaXRzIGNoaWxkcmVuLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBpZiAoZGVjbC5wcm9wLm1hdGNoKC9eLXdlYmtpdC0vKSkge1xuICAgKiAgIGRlY2wucmVtb3ZlKClcbiAgICogfVxuICAgKlxuICAgKiBAcmV0dXJuIHtOb2RlfSBOb2RlIHRvIG1ha2UgY2FsbHMgY2hhaW4uXG4gICAqL1xuICByZW1vdmUgKCkge1xuICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgdGhpcy5wYXJlbnQucmVtb3ZlQ2hpbGQodGhpcylcbiAgICB9XG4gICAgdGhpcy5wYXJlbnQgPSB1bmRlZmluZWRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBDU1Mgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbm9kZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmdpZmllcnxzeW50YXh9IFtzdHJpbmdpZmllcl0gQSBzeW50YXggdG8gdXNlXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIHN0cmluZyBnZW5lcmF0aW9uLlxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IENTUyBzdHJpbmcgb2YgdGhpcyBub2RlLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBwb3N0Y3NzLnJ1bGUoeyBzZWxlY3RvcjogJ2EnIH0pLnRvU3RyaW5nKCkgLy89PiBcImEge31cIlxuICAgKi9cbiAgdG9TdHJpbmcgKHN0cmluZ2lmaWVyID0gc3RyaW5naWZ5KSB7XG4gICAgaWYgKHN0cmluZ2lmaWVyLnN0cmluZ2lmeSkgc3RyaW5naWZpZXIgPSBzdHJpbmdpZmllci5zdHJpbmdpZnlcbiAgICBsZXQgcmVzdWx0ID0gJydcbiAgICBzdHJpbmdpZmllcih0aGlzLCBpID0+IHtcbiAgICAgIHJlc3VsdCArPSBpXG4gICAgfSlcbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBleGFjdCBjbG9uZSBvZiB0aGUgbm9kZS5cbiAgICpcbiAgICogVGhlIHJlc3VsdGluZyBjbG9uZWQgbm9kZSBhbmQgaXRzIChjbG9uZWQpIGNoaWxkcmVuIHdpbGwgcmV0YWluXG4gICAqIGNvZGUgc3R5bGUgcHJvcGVydGllcy5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IFtvdmVycmlkZXNdIE5ldyBwcm9wZXJ0aWVzIHRvIG92ZXJyaWRlIGluIHRoZSBjbG9uZS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogZGVjbC5yYXdzLmJlZm9yZSAgICAvLz0+IFwiXFxuICBcIlxuICAgKiBjb25zdCBjbG9uZWQgPSBkZWNsLmNsb25lKHsgcHJvcDogJy1tb3otJyArIGRlY2wucHJvcCB9KVxuICAgKiBjbG9uZWQucmF3cy5iZWZvcmUgIC8vPT4gXCJcXG4gIFwiXG4gICAqIGNsb25lZC50b1N0cmluZygpICAgLy89PiAtbW96LXRyYW5zZm9ybTogc2NhbGUoMClcbiAgICpcbiAgICogQHJldHVybiB7Tm9kZX0gQ2xvbmUgb2YgdGhlIG5vZGUuXG4gICAqL1xuICBjbG9uZSAob3ZlcnJpZGVzID0geyB9KSB7XG4gICAgbGV0IGNsb25lZCA9IGNsb25lTm9kZSh0aGlzKVxuICAgIGZvciAobGV0IG5hbWUgaW4gb3ZlcnJpZGVzKSB7XG4gICAgICBjbG9uZWRbbmFtZV0gPSBvdmVycmlkZXNbbmFtZV1cbiAgICB9XG4gICAgcmV0dXJuIGNsb25lZFxuICB9XG5cbiAgLyoqXG4gICAqIFNob3J0Y3V0IHRvIGNsb25lIHRoZSBub2RlIGFuZCBpbnNlcnQgdGhlIHJlc3VsdGluZyBjbG9uZWQgbm9kZVxuICAgKiBiZWZvcmUgdGhlIGN1cnJlbnQgbm9kZS5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IFtvdmVycmlkZXNdIE1ldyBwcm9wZXJ0aWVzIHRvIG92ZXJyaWRlIGluIHRoZSBjbG9uZS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogZGVjbC5jbG9uZUJlZm9yZSh7IHByb3A6ICctbW96LScgKyBkZWNsLnByb3AgfSlcbiAgICpcbiAgICogQHJldHVybiB7Tm9kZX0gTmV3IG5vZGVcbiAgICovXG4gIGNsb25lQmVmb3JlIChvdmVycmlkZXMgPSB7IH0pIHtcbiAgICBsZXQgY2xvbmVkID0gdGhpcy5jbG9uZShvdmVycmlkZXMpXG4gICAgdGhpcy5wYXJlbnQuaW5zZXJ0QmVmb3JlKHRoaXMsIGNsb25lZClcbiAgICByZXR1cm4gY2xvbmVkXG4gIH1cblxuICAvKipcbiAgICogU2hvcnRjdXQgdG8gY2xvbmUgdGhlIG5vZGUgYW5kIGluc2VydCB0aGUgcmVzdWx0aW5nIGNsb25lZCBub2RlXG4gICAqIGFmdGVyIHRoZSBjdXJyZW50IG5vZGUuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbb3ZlcnJpZGVzXSBOZXcgcHJvcGVydGllcyB0byBvdmVycmlkZSBpbiB0aGUgY2xvbmUuXG4gICAqXG4gICAqIEByZXR1cm4ge05vZGV9IE5ldyBub2RlLlxuICAgKi9cbiAgY2xvbmVBZnRlciAob3ZlcnJpZGVzID0geyB9KSB7XG4gICAgbGV0IGNsb25lZCA9IHRoaXMuY2xvbmUob3ZlcnJpZGVzKVxuICAgIHRoaXMucGFyZW50Lmluc2VydEFmdGVyKHRoaXMsIGNsb25lZClcbiAgICByZXR1cm4gY2xvbmVkXG4gIH1cblxuICAvKipcbiAgICogSW5zZXJ0cyBub2RlKHMpIGJlZm9yZSB0aGUgY3VycmVudCBub2RlIGFuZCByZW1vdmVzIHRoZSBjdXJyZW50IG5vZGUuXG4gICAqXG4gICAqIEBwYXJhbSB7Li4uTm9kZX0gbm9kZXMgTW9kZShzKSB0byByZXBsYWNlIGN1cnJlbnQgb25lLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBpZiAoYXRydWxlLm5hbWUgPT09ICdtaXhpbicpIHtcbiAgICogICBhdHJ1bGUucmVwbGFjZVdpdGgobWl4aW5SdWxlc1thdHJ1bGUucGFyYW1zXSlcbiAgICogfVxuICAgKlxuICAgKiBAcmV0dXJuIHtOb2RlfSBDdXJyZW50IG5vZGUgdG8gbWV0aG9kcyBjaGFpbi5cbiAgICovXG4gIHJlcGxhY2VXaXRoICguLi5ub2Rlcykge1xuICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgZm9yIChsZXQgbm9kZSBvZiBub2Rlcykge1xuICAgICAgICB0aGlzLnBhcmVudC5pbnNlcnRCZWZvcmUodGhpcywgbm9kZSlcbiAgICAgIH1cblxuICAgICAgdGhpcy5yZW1vdmUoKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbmV4dCBjaGlsZCBvZiB0aGUgbm9kZeKAmXMgcGFyZW50LlxuICAgKiBSZXR1cm5zIGB1bmRlZmluZWRgIGlmIHRoZSBjdXJyZW50IG5vZGUgaXMgdGhlIGxhc3QgY2hpbGQuXG4gICAqXG4gICAqIEByZXR1cm4ge05vZGV8dW5kZWZpbmVkfSBOZXh0IG5vZGUuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGlmIChjb21tZW50LnRleHQgPT09ICdkZWxldGUgbmV4dCcpIHtcbiAgICogICBjb25zdCBuZXh0ID0gY29tbWVudC5uZXh0KClcbiAgICogICBpZiAobmV4dCkge1xuICAgKiAgICAgbmV4dC5yZW1vdmUoKVxuICAgKiAgIH1cbiAgICogfVxuICAgKi9cbiAgbmV4dCAoKSB7XG4gICAgaWYgKCF0aGlzLnBhcmVudCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGxldCBpbmRleCA9IHRoaXMucGFyZW50LmluZGV4KHRoaXMpXG4gICAgcmV0dXJuIHRoaXMucGFyZW50Lm5vZGVzW2luZGV4ICsgMV1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyBjaGlsZCBvZiB0aGUgbm9kZeKAmXMgcGFyZW50LlxuICAgKiBSZXR1cm5zIGB1bmRlZmluZWRgIGlmIHRoZSBjdXJyZW50IG5vZGUgaXMgdGhlIGZpcnN0IGNoaWxkLlxuICAgKlxuICAgKiBAcmV0dXJuIHtOb2RlfHVuZGVmaW5lZH0gUHJldmlvdXMgbm9kZS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY29uc3QgYW5ub3RhdGlvbiA9IGRlY2wucHJldigpXG4gICAqIGlmIChhbm5vdGF0aW9uLnR5cGUgPT09ICdjb21tZW50Jykge1xuICAgKiAgIHJlYWRBbm5vdGF0aW9uKGFubm90YXRpb24udGV4dClcbiAgICogfVxuICAgKi9cbiAgcHJldiAoKSB7XG4gICAgaWYgKCF0aGlzLnBhcmVudCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGxldCBpbmRleCA9IHRoaXMucGFyZW50LmluZGV4KHRoaXMpXG4gICAgcmV0dXJuIHRoaXMucGFyZW50Lm5vZGVzW2luZGV4IC0gMV1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbnNlcnQgbmV3IG5vZGUgYmVmb3JlIGN1cnJlbnQgbm9kZSB0byBjdXJyZW50IG5vZGXigJlzIHBhcmVudC5cbiAgICpcbiAgICogSnVzdCBhbGlhcyBmb3IgYG5vZGUucGFyZW50Lmluc2VydEJlZm9yZShub2RlLCBhZGQpYC5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfG9iamVjdHxzdHJpbmd8Tm9kZVtdfSBhZGQgTmV3IG5vZGUuXG4gICAqXG4gICAqIEByZXR1cm4ge05vZGV9IFRoaXMgbm9kZSBmb3IgbWV0aG9kcyBjaGFpbi5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogZGVjbC5iZWZvcmUoJ2NvbnRlbnQ6IFwiXCInKVxuICAgKi9cbiAgYmVmb3JlIChhZGQpIHtcbiAgICB0aGlzLnBhcmVudC5pbnNlcnRCZWZvcmUodGhpcywgYWRkKVxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICAvKipcbiAgICogSW5zZXJ0IG5ldyBub2RlIGFmdGVyIGN1cnJlbnQgbm9kZSB0byBjdXJyZW50IG5vZGXigJlzIHBhcmVudC5cbiAgICpcbiAgICogSnVzdCBhbGlhcyBmb3IgYG5vZGUucGFyZW50Lmluc2VydEFmdGVyKG5vZGUsIGFkZClgLlxuICAgKlxuICAgKiBAcGFyYW0ge05vZGV8b2JqZWN0fHN0cmluZ3xOb2RlW119IGFkZCBOZXcgbm9kZS5cbiAgICpcbiAgICogQHJldHVybiB7Tm9kZX0gVGhpcyBub2RlIGZvciBtZXRob2RzIGNoYWluLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBkZWNsLmFmdGVyKCdjb2xvcjogYmxhY2snKVxuICAgKi9cbiAgYWZ0ZXIgKGFkZCkge1xuICAgIHRoaXMucGFyZW50Lmluc2VydEFmdGVyKHRoaXMsIGFkZClcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgdG9KU09OICgpIHtcbiAgICBsZXQgZml4ZWQgPSB7IH1cblxuICAgIGZvciAobGV0IG5hbWUgaW4gdGhpcykge1xuICAgICAgaWYgKCF0aGlzLmhhc093blByb3BlcnR5KG5hbWUpKSBjb250aW51ZVxuICAgICAgaWYgKG5hbWUgPT09ICdwYXJlbnQnKSBjb250aW51ZVxuICAgICAgbGV0IHZhbHVlID0gdGhpc1tuYW1lXVxuXG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICBmaXhlZFtuYW1lXSA9IHZhbHVlLm1hcChpID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIGkgPT09ICdvYmplY3QnICYmIGkudG9KU09OKSB7XG4gICAgICAgICAgICByZXR1cm4gaS50b0pTT04oKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gaVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZS50b0pTT04pIHtcbiAgICAgICAgZml4ZWRbbmFtZV0gPSB2YWx1ZS50b0pTT04oKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZml4ZWRbbmFtZV0gPSB2YWx1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmaXhlZFxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB7QGxpbmsgTm9kZSNyYXdzfSB2YWx1ZS4gSWYgdGhlIG5vZGUgaXMgbWlzc2luZ1xuICAgKiB0aGUgY29kZSBzdHlsZSBwcm9wZXJ0eSAoYmVjYXVzZSB0aGUgbm9kZSB3YXMgbWFudWFsbHkgYnVpbHQgb3IgY2xvbmVkKSxcbiAgICogUG9zdENTUyB3aWxsIHRyeSB0byBhdXRvZGV0ZWN0IHRoZSBjb2RlIHN0eWxlIHByb3BlcnR5IGJ5IGxvb2tpbmdcbiAgICogYXQgb3RoZXIgbm9kZXMgaW4gdGhlIHRyZWUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wICAgICAgICAgIE5hbWUgb2YgY29kZSBzdHlsZSBwcm9wZXJ0eS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtkZWZhdWx0VHlwZV0gTmFtZSBvZiBkZWZhdWx0IHZhbHVlLCBpdCBjYW4gYmUgbWlzc2VkXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHRoZSB2YWx1ZSBpcyB0aGUgc2FtZSBhcyBwcm9wLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCByb290ID0gcG9zdGNzcy5wYXJzZSgnYSB7IGJhY2tncm91bmQ6IHdoaXRlIH0nKVxuICAgKiByb290Lm5vZGVzWzBdLmFwcGVuZCh7IHByb3A6ICdjb2xvcicsIHZhbHVlOiAnYmxhY2snIH0pXG4gICAqIHJvb3Qubm9kZXNbMF0ubm9kZXNbMV0ucmF3cy5iZWZvcmUgICAvLz0+IHVuZGVmaW5lZFxuICAgKiByb290Lm5vZGVzWzBdLm5vZGVzWzFdLnJhdygnYmVmb3JlJykgLy89PiAnICdcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nfSBDb2RlIHN0eWxlIHZhbHVlLlxuICAgKi9cbiAgcmF3IChwcm9wLCBkZWZhdWx0VHlwZSkge1xuICAgIGxldCBzdHIgPSBuZXcgU3RyaW5naWZpZXIoKVxuICAgIHJldHVybiBzdHIucmF3KHRoaXMsIHByb3AsIGRlZmF1bHRUeXBlKVxuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIHRoZSBSb290IGluc3RhbmNlIG9mIHRoZSBub2Rl4oCZcyB0cmVlLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiByb290Lm5vZGVzWzBdLm5vZGVzWzBdLnJvb3QoKSA9PT0gcm9vdFxuICAgKlxuICAgKiBAcmV0dXJuIHtSb290fSBSb290IHBhcmVudC5cbiAgICovXG4gIHJvb3QgKCkge1xuICAgIGxldCByZXN1bHQgPSB0aGlzXG4gICAgd2hpbGUgKHJlc3VsdC5wYXJlbnQpIHJlc3VsdCA9IHJlc3VsdC5wYXJlbnRcbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgdGhlIGNvZGUgc3R5bGUgcHJvcGVydGllcyBmb3IgdGhlIG5vZGUgYW5kIGl0cyBjaGlsZHJlbi5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufSBba2VlcEJldHdlZW5dIEtlZXAgdGhlIHJhd3MuYmV0d2VlbiBzeW1ib2xzLlxuICAgKlxuICAgKiBAcmV0dXJuIHt1bmRlZmluZWR9XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIG5vZGUucmF3cy5iZWZvcmUgIC8vPT4gJyAnXG4gICAqIG5vZGUuY2xlYW5SYXdzKClcbiAgICogbm9kZS5yYXdzLmJlZm9yZSAgLy89PiB1bmRlZmluZWRcbiAgICovXG4gIGNsZWFuUmF3cyAoa2VlcEJldHdlZW4pIHtcbiAgICBkZWxldGUgdGhpcy5yYXdzLmJlZm9yZVxuICAgIGRlbGV0ZSB0aGlzLnJhd3MuYWZ0ZXJcbiAgICBpZiAoIWtlZXBCZXR3ZWVuKSBkZWxldGUgdGhpcy5yYXdzLmJldHdlZW5cbiAgfVxuXG4gIHBvc2l0aW9uSW5zaWRlIChpbmRleCkge1xuICAgIGxldCBzdHJpbmcgPSB0aGlzLnRvU3RyaW5nKClcbiAgICBsZXQgY29sdW1uID0gdGhpcy5zb3VyY2Uuc3RhcnQuY29sdW1uXG4gICAgbGV0IGxpbmUgPSB0aGlzLnNvdXJjZS5zdGFydC5saW5lXG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluZGV4OyBpKyspIHtcbiAgICAgIGlmIChzdHJpbmdbaV0gPT09ICdcXG4nKSB7XG4gICAgICAgIGNvbHVtbiA9IDFcbiAgICAgICAgbGluZSArPSAxXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb2x1bW4gKz0gMVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IGxpbmUsIGNvbHVtbiB9XG4gIH1cblxuICBwb3NpdGlvbkJ5IChvcHRzKSB7XG4gICAgbGV0IHBvcyA9IHRoaXMuc291cmNlLnN0YXJ0XG4gICAgaWYgKG9wdHMuaW5kZXgpIHtcbiAgICAgIHBvcyA9IHRoaXMucG9zaXRpb25JbnNpZGUob3B0cy5pbmRleClcbiAgICB9IGVsc2UgaWYgKG9wdHMud29yZCkge1xuICAgICAgbGV0IGluZGV4ID0gdGhpcy50b1N0cmluZygpLmluZGV4T2Yob3B0cy53b3JkKVxuICAgICAgaWYgKGluZGV4ICE9PSAtMSkgcG9zID0gdGhpcy5wb3NpdGlvbkluc2lkZShpbmRleClcbiAgICB9XG4gICAgcmV0dXJuIHBvc1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZW1iZXJvZiBOb2RlI1xuICAgKiBAbWVtYmVyIHtzdHJpbmd9IHR5cGUgU3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbm9kZeKAmXMgdHlwZS5cbiAgICogICAgICAgICAgICAgICAgICAgICAgIFBvc3NpYmxlIHZhbHVlcyBhcmUgYHJvb3RgLCBgYXRydWxlYCwgYHJ1bGVgLFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgYGRlY2xgLCBvciBgY29tbWVudGAuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHBvc3Rjc3MuZGVjbCh7IHByb3A6ICdjb2xvcicsIHZhbHVlOiAnYmxhY2snIH0pLnR5cGUgLy89PiAnZGVjbCdcbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZW1iZXJvZiBOb2RlI1xuICAgKiBAbWVtYmVyIHtDb250YWluZXJ9IHBhcmVudCBUaGUgbm9kZeKAmXMgcGFyZW50IG5vZGUuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHJvb3Qubm9kZXNbMF0ucGFyZW50ID09PSByb290XG4gICAqL1xuXG4gIC8qKlxuICAgKiBAbWVtYmVyb2YgTm9kZSNcbiAgICogQG1lbWJlciB7c291cmNlfSBzb3VyY2UgVGhlIGlucHV0IHNvdXJjZSBvZiB0aGUgbm9kZS5cbiAgICpcbiAgICogVGhlIHByb3BlcnR5IGlzIHVzZWQgaW4gc291cmNlIG1hcCBnZW5lcmF0aW9uLlxuICAgKlxuICAgKiBJZiB5b3UgY3JlYXRlIGEgbm9kZSBtYW51YWxseSAoZS5nLiwgd2l0aCBgcG9zdGNzcy5kZWNsKClgKSxcbiAgICogdGhhdCBub2RlIHdpbGwgbm90IGhhdmUgYSBgc291cmNlYCBwcm9wZXJ0eSBhbmQgd2lsbCBiZSBhYnNlbnRcbiAgICogZnJvbSB0aGUgc291cmNlIG1hcC4gRm9yIHRoaXMgcmVhc29uLCB0aGUgcGx1Z2luIGRldmVsb3BlciBzaG91bGRcbiAgICogY29uc2lkZXIgY2xvbmluZyBub2RlcyB0byBjcmVhdGUgbmV3IG9uZXMgKGluIHdoaWNoIGNhc2UgdGhlIG5ldyBub2Rl4oCZc1xuICAgKiBzb3VyY2Ugd2lsbCByZWZlcmVuY2UgdGhlIG9yaWdpbmFsLCBjbG9uZWQgbm9kZSkgb3Igc2V0dGluZ1xuICAgKiB0aGUgYHNvdXJjZWAgcHJvcGVydHkgbWFudWFsbHkuXG4gICAqXG4gICAqIGBgYGpzXG4gICAqIC8vIEJhZFxuICAgKiBjb25zdCBwcmVmaXhlZCA9IHBvc3Rjc3MuZGVjbCh7XG4gICAqICAgcHJvcDogJy1tb3otJyArIGRlY2wucHJvcCxcbiAgICogICB2YWx1ZTogZGVjbC52YWx1ZVxuICAgKiB9KVxuICAgKlxuICAgKiAvLyBHb29kXG4gICAqIGNvbnN0IHByZWZpeGVkID0gZGVjbC5jbG9uZSh7IHByb3A6ICctbW96LScgKyBkZWNsLnByb3AgfSlcbiAgICogYGBgXG4gICAqXG4gICAqIGBgYGpzXG4gICAqIGlmIChhdHJ1bGUubmFtZSA9PT0gJ2FkZC1saW5rJykge1xuICAgKiAgIGNvbnN0IHJ1bGUgPSBwb3N0Y3NzLnJ1bGUoeyBzZWxlY3RvcjogJ2EnLCBzb3VyY2U6IGF0cnVsZS5zb3VyY2UgfSlcbiAgICogICBhdHJ1bGUucGFyZW50Lmluc2VydEJlZm9yZShhdHJ1bGUsIHJ1bGUpXG4gICAqIH1cbiAgICogYGBgXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGRlY2wuc291cmNlLmlucHV0LmZyb20gLy89PiAnL2hvbWUvYWkvYS5zYXNzJ1xuICAgKiBkZWNsLnNvdXJjZS5zdGFydCAgICAgIC8vPT4geyBsaW5lOiAxMCwgY29sdW1uOiAyIH1cbiAgICogZGVjbC5zb3VyY2UuZW5kICAgICAgICAvLz0+IHsgbGluZTogMTAsIGNvbHVtbjogMTIgfVxuICAgKi9cblxuICAvKipcbiAgICogQG1lbWJlcm9mIE5vZGUjXG4gICAqIEBtZW1iZXIge29iamVjdH0gcmF3cyBJbmZvcm1hdGlvbiB0byBnZW5lcmF0ZSBieXRlLXRvLWJ5dGUgZXF1YWxcbiAgICogICAgICAgICAgICAgICAgICAgICAgIG5vZGUgc3RyaW5nIGFzIGl0IHdhcyBpbiB0aGUgb3JpZ2luIGlucHV0LlxuICAgKlxuICAgKiBFdmVyeSBwYXJzZXIgc2F2ZXMgaXRzIG93biBwcm9wZXJ0aWVzLFxuICAgKiBidXQgdGhlIGRlZmF1bHQgQ1NTIHBhcnNlciB1c2VzOlxuICAgKlxuICAgKiAqIGBiZWZvcmVgOiB0aGUgc3BhY2Ugc3ltYm9scyBiZWZvcmUgdGhlIG5vZGUuIEl0IGFsc28gc3RvcmVzIGAqYFxuICAgKiAgIGFuZCBgX2Agc3ltYm9scyBiZWZvcmUgdGhlIGRlY2xhcmF0aW9uIChJRSBoYWNrKS5cbiAgICogKiBgYWZ0ZXJgOiB0aGUgc3BhY2Ugc3ltYm9scyBhZnRlciB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgbm9kZVxuICAgKiAgIHRvIHRoZSBlbmQgb2YgdGhlIG5vZGUuXG4gICAqICogYGJldHdlZW5gOiB0aGUgc3ltYm9scyBiZXR3ZWVuIHRoZSBwcm9wZXJ0eSBhbmQgdmFsdWVcbiAgICogICBmb3IgZGVjbGFyYXRpb25zLCBzZWxlY3RvciBhbmQgYHtgIGZvciBydWxlcywgb3IgbGFzdCBwYXJhbWV0ZXJcbiAgICogICBhbmQgYHtgIGZvciBhdC1ydWxlcy5cbiAgICogKiBgc2VtaWNvbG9uYDogY29udGFpbnMgdHJ1ZSBpZiB0aGUgbGFzdCBjaGlsZCBoYXNcbiAgICogICBhbiAob3B0aW9uYWwpIHNlbWljb2xvbi5cbiAgICogKiBgYWZ0ZXJOYW1lYDogdGhlIHNwYWNlIGJldHdlZW4gdGhlIGF0LXJ1bGUgbmFtZSBhbmQgaXRzIHBhcmFtZXRlcnMuXG4gICAqICogYGxlZnRgOiB0aGUgc3BhY2Ugc3ltYm9scyBiZXR3ZWVuIGAvKmAgYW5kIHRoZSBjb21tZW504oCZcyB0ZXh0LlxuICAgKiAqIGByaWdodGA6IHRoZSBzcGFjZSBzeW1ib2xzIGJldHdlZW4gdGhlIGNvbW1lbnTigJlzIHRleHRcbiAgICogICBhbmQgPGNvZGU+KiYjNDc7PC9jb2RlPi5cbiAgICogKiBgaW1wb3J0YW50YDogdGhlIGNvbnRlbnQgb2YgdGhlIGltcG9ydGFudCBzdGF0ZW1lbnQsXG4gICAqICAgaWYgaXQgaXMgbm90IGp1c3QgYCFpbXBvcnRhbnRgLlxuICAgKlxuICAgKiBQb3N0Q1NTIGNsZWFucyBzZWxlY3RvcnMsIGRlY2xhcmF0aW9uIHZhbHVlcyBhbmQgYXQtcnVsZSBwYXJhbWV0ZXJzXG4gICAqIGZyb20gY29tbWVudHMgYW5kIGV4dHJhIHNwYWNlcywgYnV0IGl0IHN0b3JlcyBvcmlnaW4gY29udGVudCBpbiByYXdzXG4gICAqIHByb3BlcnRpZXMuIEFzIHN1Y2gsIGlmIHlvdSBkb27igJl0IGNoYW5nZSBhIGRlY2xhcmF0aW9u4oCZcyB2YWx1ZSxcbiAgICogUG9zdENTUyB3aWxsIHVzZSB0aGUgcmF3IHZhbHVlIHdpdGggY29tbWVudHMuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJvb3QgPSBwb3N0Y3NzLnBhcnNlKCdhIHtcXG4gIGNvbG9yOmJsYWNrXFxufScpXG4gICAqIHJvb3QuZmlyc3QuZmlyc3QucmF3cyAvLz0+IHsgYmVmb3JlOiAnXFxuICAnLCBiZXR3ZWVuOiAnOicgfVxuICAgKi9cbn1cblxuZXhwb3J0IGRlZmF1bHQgTm9kZVxuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IHBvc2l0aW9uXG4gKiBAcHJvcGVydHkge251bWJlcn0gbGluZSAgIFNvdXJjZSBsaW5lIGluIGZpbGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gY29sdW1uIFNvdXJjZSBjb2x1bW4gaW4gZmlsZS5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IHNvdXJjZVxuICogQHByb3BlcnR5IHtJbnB1dH0gaW5wdXQgICAge0BsaW5rIElucHV0fSB3aXRoIGlucHV0IGZpbGVcbiAqIEBwcm9wZXJ0eSB7cG9zaXRpb259IHN0YXJ0IFRoZSBzdGFydGluZyBwb3NpdGlvbiBvZiB0aGUgbm9kZeKAmXMgc291cmNlLlxuICogQHByb3BlcnR5IHtwb3NpdGlvbn0gZW5kICAgVGhlIGVuZGluZyBwb3NpdGlvbiBvZiB0aGUgbm9kZeKAmXMgc291cmNlLlxuICovXG4iXSwiZmlsZSI6Im5vZGUuanMifQ==
Note: See TracBrowser for help on using the repository browser.