css-syntax-error.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. 'use strict';
  2. exports.__esModule = true;
  3. 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; }; }();
  4. var _supportsColor = require('supports-color');
  5. var _supportsColor2 = _interopRequireDefault(_supportsColor);
  6. var _chalk = require('chalk');
  7. var _chalk2 = _interopRequireDefault(_chalk);
  8. var _terminalHighlight = require('./terminal-highlight');
  9. var _terminalHighlight2 = _interopRequireDefault(_terminalHighlight);
  10. var _warnOnce = require('./warn-once');
  11. var _warnOnce2 = _interopRequireDefault(_warnOnce);
  12. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  13. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14. /**
  15. * The CSS parser throws this error for broken CSS.
  16. *
  17. * Custom parsers can throw this error for broken custom syntax using
  18. * the {@link Node#error} method.
  19. *
  20. * PostCSS will use the input source map to detect the original error location.
  21. * If you wrote a Sass file, compiled it to CSS and then parsed it with PostCSS,
  22. * PostCSS will show the original position in the Sass file.
  23. *
  24. * If you need the position in the PostCSS input
  25. * (e.g., to debug the previous compiler), use `error.input.file`.
  26. *
  27. * @example
  28. * // Catching and checking syntax error
  29. * try {
  30. * postcss.parse('a{')
  31. * } catch (error) {
  32. * if ( error.name === 'CssSyntaxError' ) {
  33. * error //=> CssSyntaxError
  34. * }
  35. * }
  36. *
  37. * @example
  38. * // Raising error from plugin
  39. * throw node.error('Unknown variable', { plugin: 'postcss-vars' });
  40. */
  41. var CssSyntaxError = function () {
  42. /**
  43. * @param {string} message - error message
  44. * @param {number} [line] - source line of the error
  45. * @param {number} [column] - source column of the error
  46. * @param {string} [source] - source code of the broken file
  47. * @param {string} [file] - absolute path to the broken file
  48. * @param {string} [plugin] - PostCSS plugin name, if error came from plugin
  49. */
  50. function CssSyntaxError(message, line, column, source, file, plugin) {
  51. _classCallCheck(this, CssSyntaxError);
  52. /**
  53. * @member {string} - Always equal to `'CssSyntaxError'`. You should
  54. * always check error type
  55. * by `error.name === 'CssSyntaxError'` instead of
  56. * `error instanceof CssSyntaxError`, because
  57. * npm could have several PostCSS versions.
  58. *
  59. * @example
  60. * if ( error.name === 'CssSyntaxError' ) {
  61. * error //=> CssSyntaxError
  62. * }
  63. */
  64. this.name = 'CssSyntaxError';
  65. /**
  66. * @member {string} - Error message.
  67. *
  68. * @example
  69. * error.message //=> 'Unclosed block'
  70. */
  71. this.reason = message;
  72. if (file) {
  73. /**
  74. * @member {string} - Absolute path to the broken file.
  75. *
  76. * @example
  77. * error.file //=> 'a.sass'
  78. * error.input.file //=> 'a.css'
  79. */
  80. this.file = file;
  81. }
  82. if (source) {
  83. /**
  84. * @member {string} - Source code of the broken file.
  85. *
  86. * @example
  87. * error.source //=> 'a { b {} }'
  88. * error.input.column //=> 'a b { }'
  89. */
  90. this.source = source;
  91. }
  92. if (plugin) {
  93. /**
  94. * @member {string} - Plugin name, if error came from plugin.
  95. *
  96. * @example
  97. * error.plugin //=> 'postcss-vars'
  98. */
  99. this.plugin = plugin;
  100. }
  101. if (typeof line !== 'undefined' && typeof column !== 'undefined') {
  102. /**
  103. * @member {number} - Source line of the error.
  104. *
  105. * @example
  106. * error.line //=> 2
  107. * error.input.line //=> 4
  108. */
  109. this.line = line;
  110. /**
  111. * @member {number} - Source column of the error.
  112. *
  113. * @example
  114. * error.column //=> 1
  115. * error.input.column //=> 4
  116. */
  117. this.column = column;
  118. }
  119. this.setMessage();
  120. if (Error.captureStackTrace) {
  121. Error.captureStackTrace(this, CssSyntaxError);
  122. }
  123. }
  124. CssSyntaxError.prototype.setMessage = function setMessage() {
  125. /**
  126. * @member {string} - Full error text in the GNU error format
  127. * with plugin, file, line and column.
  128. *
  129. * @example
  130. * error.message //=> 'a.css:1:1: Unclosed block'
  131. */
  132. this.message = this.plugin ? this.plugin + ': ' : '';
  133. this.message += this.file ? this.file : '<css input>';
  134. if (typeof this.line !== 'undefined') {
  135. this.message += ':' + this.line + ':' + this.column;
  136. }
  137. this.message += ': ' + this.reason;
  138. };
  139. /**
  140. * Returns a few lines of CSS source that caused the error.
  141. *
  142. * If the CSS has an input source map without `sourceContent`,
  143. * this method will return an empty string.
  144. *
  145. * @param {boolean} [color] whether arrow will be colored red by terminal
  146. * color codes. By default, PostCSS will detect
  147. * color support by `process.stdout.isTTY`
  148. * and `process.env.NODE_DISABLE_COLORS`.
  149. *
  150. * @example
  151. * error.showSourceCode() //=> " 4 | }
  152. * // 5 | a {
  153. * // > 6 | bad
  154. * // | ^
  155. * // 7 | }
  156. * // 8 | b {"
  157. *
  158. * @return {string} few lines of CSS source that caused the error
  159. */
  160. CssSyntaxError.prototype.showSourceCode = function showSourceCode(color) {
  161. var _this = this;
  162. if (!this.source) return '';
  163. var css = this.source;
  164. if (typeof color === 'undefined') color = _supportsColor2.default;
  165. if (color) css = (0, _terminalHighlight2.default)(css);
  166. var lines = css.split(/\r?\n/);
  167. var start = Math.max(this.line - 3, 0);
  168. var end = Math.min(this.line + 2, lines.length);
  169. var maxWidth = String(end).length;
  170. var colors = new _chalk2.default.constructor({ enabled: true });
  171. function mark(text) {
  172. if (color) {
  173. return colors.red.bold(text);
  174. } else {
  175. return text;
  176. }
  177. }
  178. function aside(text) {
  179. if (color) {
  180. return colors.gray(text);
  181. } else {
  182. return text;
  183. }
  184. }
  185. return lines.slice(start, end).map(function (line, index) {
  186. var number = start + 1 + index;
  187. var gutter = ' ' + (' ' + number).slice(-maxWidth) + ' | ';
  188. if (number === _this.line) {
  189. var spacing = aside(gutter.replace(/\d/g, ' ')) + line.slice(0, _this.column - 1).replace(/[^\t]/g, ' ');
  190. return mark('>') + aside(gutter) + line + '\n ' + spacing + mark('^');
  191. } else {
  192. return ' ' + aside(gutter) + line;
  193. }
  194. }).join('\n');
  195. };
  196. /**
  197. * Returns error position, message and source code of the broken part.
  198. *
  199. * @example
  200. * error.toString() //=> "CssSyntaxError: app.css:1:1: Unclosed block
  201. * // > 1 | a {
  202. * // | ^"
  203. *
  204. * @return {string} error position, message and source code
  205. */
  206. CssSyntaxError.prototype.toString = function toString() {
  207. var code = this.showSourceCode();
  208. if (code) {
  209. code = '\n\n' + code + '\n';
  210. }
  211. return this.name + ': ' + this.message + code;
  212. };
  213. _createClass(CssSyntaxError, [{
  214. key: 'generated',
  215. get: function get() {
  216. (0, _warnOnce2.default)('CssSyntaxError#generated is depreacted. Use input instead.');
  217. return this.input;
  218. }
  219. /**
  220. * @memberof CssSyntaxError#
  221. * @member {Input} input - Input object with PostCSS internal information
  222. * about input file. If input has source map
  223. * from previous tool, PostCSS will use origin
  224. * (for example, Sass) source. You can use this
  225. * object to get PostCSS input source.
  226. *
  227. * @example
  228. * error.input.file //=> 'a.css'
  229. * error.file //=> 'a.sass'
  230. */
  231. }]);
  232. return CssSyntaxError;
  233. }();
  234. exports.default = CssSyntaxError;
  235. module.exports = exports['default'];
  236. //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9saWIvY3NzLXN5bnRheC1lcnJvci5lczYiXSwibmFtZXMiOlsiQ3NzU3ludGF4RXJyb3IiLCJtZXNzYWdlIiwibGluZSIsImNvbHVtbiIsInNvdXJjZSIsImZpbGUiLCJwbHVnaW4iLCJuYW1lIiwicmVhc29uIiwic2V0TWVzc2FnZSIsIkVycm9yIiwiY2FwdHVyZVN0YWNrVHJhY2UiLCJzaG93U291cmNlQ29kZSIsImNvbG9yIiwiY3NzIiwibGluZXMiLCJzcGxpdCIsInN0YXJ0IiwiTWF0aCIsIm1heCIsImVuZCIsIm1pbiIsImxlbmd0aCIsIm1heFdpZHRoIiwiU3RyaW5nIiwiY29sb3JzIiwiY29uc3RydWN0b3IiLCJlbmFibGVkIiwibWFyayIsInRleHQiLCJyZWQiLCJib2xkIiwiYXNpZGUiLCJncmF5Iiwic2xpY2UiLCJtYXAiLCJpbmRleCIsIm51bWJlciIsImd1dHRlciIsInNwYWNpbmciLCJyZXBsYWNlIiwiam9pbiIsInRvU3RyaW5nIiwiY29kZSIsImlucHV0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7OztBQUNBOzs7O0FBRUE7Ozs7QUFDQTs7Ozs7Ozs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBMkJNQSxjOztBQUVGOzs7Ozs7OztBQVFBLDRCQUFZQyxPQUFaLEVBQXFCQyxJQUFyQixFQUEyQkMsTUFBM0IsRUFBbUNDLE1BQW5DLEVBQTJDQyxJQUEzQyxFQUFpREMsTUFBakQsRUFBeUQ7QUFBQTs7QUFDckQ7Ozs7Ozs7Ozs7OztBQVlBLGFBQUtDLElBQUwsR0FBYyxnQkFBZDtBQUNBOzs7Ozs7QUFNQSxhQUFLQyxNQUFMLEdBQWNQLE9BQWQ7O0FBRUEsWUFBS0ksSUFBTCxFQUFZO0FBQ1I7Ozs7Ozs7QUFPQSxpQkFBS0EsSUFBTCxHQUFZQSxJQUFaO0FBQ0g7QUFDRCxZQUFLRCxNQUFMLEVBQWM7QUFDVjs7Ozs7OztBQU9BLGlCQUFLQSxNQUFMLEdBQWNBLE1BQWQ7QUFDSDtBQUNELFlBQUtFLE1BQUwsRUFBYztBQUNWOzs7Ozs7QUFNQSxpQkFBS0EsTUFBTCxHQUFjQSxNQUFkO0FBQ0g7QUFDRCxZQUFLLE9BQU9KLElBQVAsS0FBZ0IsV0FBaEIsSUFBK0IsT0FBT0MsTUFBUCxLQUFrQixXQUF0RCxFQUFvRTtBQUNoRTs7Ozs7OztBQU9BLGlCQUFLRCxJQUFMLEdBQWNBLElBQWQ7QUFDQTs7Ozs7OztBQU9BLGlCQUFLQyxNQUFMLEdBQWNBLE1BQWQ7QUFDSDs7QUFFRCxhQUFLTSxVQUFMOztBQUVBLFlBQUtDLE1BQU1DLGlCQUFYLEVBQStCO0FBQzNCRCxrQkFBTUMsaUJBQU4sQ0FBd0IsSUFBeEIsRUFBOEJYLGNBQTlCO0FBQ0g7QUFDSjs7NkJBRURTLFUseUJBQWE7QUFDVDs7Ozs7OztBQU9BLGFBQUtSLE9BQUwsR0FBZ0IsS0FBS0ssTUFBTCxHQUFjLEtBQUtBLE1BQUwsR0FBYyxJQUE1QixHQUFtQyxFQUFuRDtBQUNBLGFBQUtMLE9BQUwsSUFBZ0IsS0FBS0ksSUFBTCxHQUFZLEtBQUtBLElBQWpCLEdBQXdCLGFBQXhDO0FBQ0EsWUFBSyxPQUFPLEtBQUtILElBQVosS0FBcUIsV0FBMUIsRUFBd0M7QUFDcEMsaUJBQUtELE9BQUwsSUFBZ0IsTUFBTSxLQUFLQyxJQUFYLEdBQWtCLEdBQWxCLEdBQXdCLEtBQUtDLE1BQTdDO0FBQ0g7QUFDRCxhQUFLRixPQUFMLElBQWdCLE9BQU8sS0FBS08sTUFBNUI7QUFDSCxLOztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs2QkFxQkFJLGMsMkJBQWVDLEssRUFBTztBQUFBOztBQUNsQixZQUFLLENBQUMsS0FBS1QsTUFBWCxFQUFvQixPQUFPLEVBQVA7O0FBRXBCLFlBQUlVLE1BQU0sS0FBS1YsTUFBZjtBQUNBLFlBQUssT0FBT1MsS0FBUCxLQUFpQixXQUF0QixFQUFvQ0E7QUFDcEMsWUFBS0EsS0FBTCxFQUFhQyxNQUFNLGlDQUFrQkEsR0FBbEIsQ0FBTjs7QUFFYixZQUFJQyxRQUFRRCxJQUFJRSxLQUFKLENBQVUsT0FBVixDQUFaO0FBQ0EsWUFBSUMsUUFBUUMsS0FBS0MsR0FBTCxDQUFTLEtBQUtqQixJQUFMLEdBQVksQ0FBckIsRUFBd0IsQ0FBeEIsQ0FBWjtBQUNBLFlBQUlrQixNQUFRRixLQUFLRyxHQUFMLENBQVMsS0FBS25CLElBQUwsR0FBWSxDQUFyQixFQUF3QmEsTUFBTU8sTUFBOUIsQ0FBWjs7QUFFQSxZQUFJQyxXQUFXQyxPQUFPSixHQUFQLEVBQVlFLE1BQTNCO0FBQ0EsWUFBSUcsU0FBUyxJQUFJLGdCQUFNQyxXQUFWLENBQXNCLEVBQUVDLFNBQVMsSUFBWCxFQUF0QixDQUFiOztBQUVBLGlCQUFTQyxJQUFULENBQWNDLElBQWQsRUFBb0I7QUFDaEIsZ0JBQUtoQixLQUFMLEVBQWE7QUFDVCx1QkFBT1ksT0FBT0ssR0FBUCxDQUFXQyxJQUFYLENBQWdCRixJQUFoQixDQUFQO0FBQ0gsYUFGRCxNQUVPO0FBQ0gsdUJBQU9BLElBQVA7QUFDSDtBQUNKO0FBQ0QsaUJBQVNHLEtBQVQsQ0FBZUgsSUFBZixFQUFxQjtBQUNqQixnQkFBS2hCLEtBQUwsRUFBYTtBQUNULHVCQUFPWSxPQUFPUSxJQUFQLENBQVlKLElBQVosQ0FBUDtBQUNILGFBRkQsTUFFTztBQUNILHVCQUFPQSxJQUFQO0FBQ0g7QUFDSjs7QUFFRCxlQUFPZCxNQUFNbUIsS0FBTixDQUFZakIsS0FBWixFQUFtQkcsR0FBbkIsRUFBd0JlLEdBQXhCLENBQTZCLFVBQUNqQyxJQUFELEVBQU9rQyxLQUFQLEVBQWlCO0FBQ2pELGdCQUFJQyxTQUFTcEIsUUFBUSxDQUFSLEdBQVltQixLQUF6QjtBQUNBLGdCQUFJRSxTQUFTLE1BQU0sQ0FBQyxNQUFNRCxNQUFQLEVBQWVILEtBQWYsQ0FBcUIsQ0FBQ1gsUUFBdEIsQ0FBTixHQUF3QyxLQUFyRDtBQUNBLGdCQUFLYyxXQUFXLE1BQUtuQyxJQUFyQixFQUE0QjtBQUN4QixvQkFBSXFDLFVBQ0FQLE1BQU1NLE9BQU9FLE9BQVAsQ0FBZSxLQUFmLEVBQXNCLEdBQXRCLENBQU4sSUFDQXRDLEtBQUtnQyxLQUFMLENBQVcsQ0FBWCxFQUFjLE1BQUsvQixNQUFMLEdBQWMsQ0FBNUIsRUFBK0JxQyxPQUEvQixDQUF1QyxRQUF2QyxFQUFpRCxHQUFqRCxDQUZKO0FBR0EsdUJBQU9aLEtBQUssR0FBTCxJQUFZSSxNQUFNTSxNQUFOLENBQVosR0FBNEJwQyxJQUE1QixHQUFtQyxLQUFuQyxHQUNBcUMsT0FEQSxHQUNVWCxLQUFLLEdBQUwsQ0FEakI7QUFFSCxhQU5ELE1BTU87QUFDSCx1QkFBTyxNQUFNSSxNQUFNTSxNQUFOLENBQU4sR0FBc0JwQyxJQUE3QjtBQUNIO0FBQ0osU0FaTSxFQVlKdUMsSUFaSSxDQVlDLElBWkQsQ0FBUDtBQWFILEs7O0FBRUQ7Ozs7Ozs7Ozs7Ozs2QkFVQUMsUSx1QkFBVztBQUNQLFlBQUlDLE9BQU8sS0FBSy9CLGNBQUwsRUFBWDtBQUNBLFlBQUsrQixJQUFMLEVBQVk7QUFDUkEsbUJBQU8sU0FBU0EsSUFBVCxHQUFnQixJQUF2QjtBQUNIO0FBQ0QsZUFBTyxLQUFLcEMsSUFBTCxHQUFZLElBQVosR0FBbUIsS0FBS04sT0FBeEIsR0FBa0MwQyxJQUF6QztBQUNILEs7Ozs7NEJBRWU7QUFDWixvQ0FBUyw0REFBVDtBQUNBLG1CQUFPLEtBQUtDLEtBQVo7QUFDSDs7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7O2tCQWVXNUMsYyIsImZpbGUiOiJjc3Mtc3ludGF4LWVycm9yLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHN1cHBvcnRzQ29sb3IgZnJvbSAnc3VwcG9ydHMtY29sb3InO1xuaW1wb3J0IGNoYWxrICAgICAgICAgZnJvbSAnY2hhbGsnO1xuXG5pbXBvcnQgdGVybWluYWxIaWdobGlnaHQgZnJvbSAnLi90ZXJtaW5hbC1oaWdobGlnaHQnO1xuaW1wb3J0IHdhcm5PbmNlICAgICAgICAgIGZyb20gJy4vd2Fybi1vbmNlJztcblxuLyoqXG4gKiBUaGUgQ1NTIHBhcnNlciB0aHJvd3MgdGhpcyBlcnJvciBmb3IgYnJva2VuIENTUy5cbiAqXG4gKiBDdXN0b20gcGFyc2VycyBjYW4gdGhyb3cgdGhpcyBlcnJvciBmb3IgYnJva2VuIGN1c3RvbSBzeW50YXggdXNpbmdcbiAqIHRoZSB7QGxpbmsgTm9kZSNlcnJvcn0gbWV0aG9kLlxuICpcbiAqIFBvc3RDU1Mgd2lsbCB1c2UgdGhlIGlucHV0IHNvdXJjZSBtYXAgdG8gZGV0ZWN0IHRoZSBvcmlnaW5hbCBlcnJvciBsb2NhdGlvbi5cbiAqIElmIHlvdSB3cm90ZSBhIFNhc3MgZmlsZSwgY29tcGlsZWQgaXQgdG8gQ1NTIGFuZCB0aGVuIHBhcnNlZCBpdCB3aXRoIFBvc3RDU1MsXG4gKiBQb3N0Q1NTIHdpbGwgc2hvdyB0aGUgb3JpZ2luYWwgcG9zaXRpb24gaW4gdGhlIFNhc3MgZmlsZS5cbiAqXG4gKiBJZiB5b3UgbmVlZCB0aGUgcG9zaXRpb24gaW4gdGhlIFBvc3RDU1MgaW5wdXRcbiAqIChlLmcuLCB0byBkZWJ1ZyB0aGUgcHJldmlvdXMgY29tcGlsZXIpLCB1c2UgYGVycm9yLmlucHV0LmZpbGVgLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDYXRjaGluZyBhbmQgY2hlY2tpbmcgc3ludGF4IGVycm9yXG4gKiB0cnkge1xuICogICBwb3N0Y3NzLnBhcnNlKCdheycpXG4gKiB9IGNhdGNoIChlcnJvcikge1xuICogICBpZiAoIGVycm9yLm5hbWUgPT09ICdDc3NTeW50YXhFcnJvcicgKSB7XG4gKiAgICAgZXJyb3IgLy89PiBDc3NTeW50YXhFcnJvclxuICogICB9XG4gKiB9XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFJhaXNpbmcgZXJyb3IgZnJvbSBwbHVnaW5cbiAqIHRocm93IG5vZGUuZXJyb3IoJ1Vua25vd24gdmFyaWFibGUnLCB7IHBsdWdpbjogJ3Bvc3Rjc3MtdmFycycgfSk7XG4gKi9cbmNsYXNzIENzc1N5bnRheEVycm9yIHtcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlICAtIGVycm9yIG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xpbmVdICAgLSBzb3VyY2UgbGluZSBvZiB0aGUgZXJyb3JcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2NvbHVtbl0gLSBzb3VyY2UgY29sdW1uIG9mIHRoZSBlcnJvclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc291cmNlXSAtIHNvdXJjZSBjb2RlIG9mIHRoZSBicm9rZW4gZmlsZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbZmlsZV0gICAtIGFic29sdXRlIHBhdGggdG8gdGhlIGJyb2tlbiBmaWxlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtwbHVnaW5dIC0gUG9zdENTUyBwbHVnaW4gbmFtZSwgaWYgZXJyb3IgY2FtZSBmcm9tIHBsdWdpblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIGxpbmUsIGNvbHVtbiwgc291cmNlLCBmaWxlLCBwbHVnaW4pIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gLSBBbHdheXMgZXF1YWwgdG8gYCdDc3NTeW50YXhFcnJvcidgLiBZb3Ugc2hvdWxkXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICBhbHdheXMgY2hlY2sgZXJyb3IgdHlwZVxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgYnkgYGVycm9yLm5hbWUgPT09ICdDc3NTeW50YXhFcnJvcidgIGluc3RlYWQgb2ZcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgIGBlcnJvciBpbnN0YW5jZW9mIENzc1N5bnRheEVycm9yYCwgYmVjYXVzZVxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgbnBtIGNvdWxkIGhhdmUgc2V2ZXJhbCBQb3N0Q1NTIHZlcnNpb25zLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBpZiAoIGVycm9yLm5hbWUgPT09ICdDc3NTeW50YXhFcnJvcicgKSB7XG4gICAgICAgICAqICAgZXJyb3IgLy89PiBDc3NTeW50YXhFcnJvclxuICAgICAgICAgKiB9XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm5hbWUgICA9ICdDc3NTeW50YXhFcnJvcic7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IC0gRXJyb3IgbWVzc2FnZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogZXJyb3IubWVzc2FnZSAvLz0+ICdVbmNsb3NlZCBibG9jaydcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVhc29uID0gbWVzc2FnZTtcblxuICAgICAgICBpZiAoIGZpbGUgKSB7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gLSBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBicm9rZW4gZmlsZS5cbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgICAgICogZXJyb3IuZmlsZSAgICAgICAvLz0+ICdhLnNhc3MnXG4gICAgICAgICAgICAgKiBlcnJvci5pbnB1dC5maWxlIC8vPT4gJ2EuY3NzJ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB0aGlzLmZpbGUgPSBmaWxlO1xuICAgICAgICB9XG4gICAgICAgIGlmICggc291cmNlICkge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IC0gU291cmNlIGNvZGUgb2YgdGhlIGJyb2tlbiBmaWxlLlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAgICAgKiBlcnJvci5zb3VyY2UgICAgICAgLy89PiAnYSB7IGIge30gfSdcbiAgICAgICAgICAgICAqIGVycm9yLmlucHV0LmNvbHVtbiAvLz0+ICdhIGIgeyB9J1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIHBsdWdpbiApIHtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSAtIFBsdWdpbiBuYW1lLCBpZiBlcnJvciBjYW1lIGZyb20gcGx1Z2luLlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAgICAgKiBlcnJvci5wbHVnaW4gLy89PiAncG9zdGNzcy12YXJzJ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB0aGlzLnBsdWdpbiA9IHBsdWdpbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIHR5cGVvZiBsaW5lICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgY29sdW1uICE9PSAndW5kZWZpbmVkJyApIHtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfSAtIFNvdXJjZSBsaW5lIG9mIHRoZSBlcnJvci5cbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgICAgICogZXJyb3IubGluZSAgICAgICAvLz0+IDJcbiAgICAgICAgICAgICAqIGVycm9yLmlucHV0LmxpbmUgLy89PiA0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMubGluZSAgID0gbGluZTtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfSAtIFNvdXJjZSBjb2x1bW4gb2YgdGhlIGVycm9yLlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAgICAgKiBlcnJvci5jb2x1bW4gICAgICAgLy89PiAxXG4gICAgICAgICAgICAgKiBlcnJvci5pbnB1dC5jb2x1bW4gLy89PiA0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMuY29sdW1uID0gY29sdW1uO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRNZXNzYWdlKCk7XG5cbiAgICAgICAgaWYgKCBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSApIHtcbiAgICAgICAgICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIENzc1N5bnRheEVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldE1lc3NhZ2UoKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IC0gRnVsbCBlcnJvciB0ZXh0IGluIHRoZSBHTlUgZXJyb3IgZm9ybWF0XG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICB3aXRoIHBsdWdpbiwgZmlsZSwgbGluZSBhbmQgY29sdW1uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBlcnJvci5tZXNzYWdlIC8vPT4gJ2EuY3NzOjE6MTogVW5jbG9zZWQgYmxvY2snXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm1lc3NhZ2UgID0gdGhpcy5wbHVnaW4gPyB0aGlzLnBsdWdpbiArICc6ICcgOiAnJztcbiAgICAgICAgdGhpcy5tZXNzYWdlICs9IHRoaXMuZmlsZSA/IHRoaXMuZmlsZSA6ICc8Y3NzIGlucHV0Pic7XG4gICAgICAgIGlmICggdHlwZW9mIHRoaXMubGluZSAhPT0gJ3VuZGVmaW5lZCcgKSB7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2UgKz0gJzonICsgdGhpcy5saW5lICsgJzonICsgdGhpcy5jb2x1bW47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tZXNzYWdlICs9ICc6ICcgKyB0aGlzLnJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgZmV3IGxpbmVzIG9mIENTUyBzb3VyY2UgdGhhdCBjYXVzZWQgdGhlIGVycm9yLlxuICAgICAqXG4gICAgICogSWYgdGhlIENTUyBoYXMgYW4gaW5wdXQgc291cmNlIG1hcCB3aXRob3V0IGBzb3VyY2VDb250ZW50YCxcbiAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBhbiBlbXB0eSBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtjb2xvcl0gd2hldGhlciBhcnJvdyB3aWxsIGJlIGNvbG9yZWQgcmVkIGJ5IHRlcm1pbmFsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yIGNvZGVzLiBCeSBkZWZhdWx0LCBQb3N0Q1NTIHdpbGwgZGV0ZWN0XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yIHN1cHBvcnQgYnkgYHByb2Nlc3Muc3Rkb3V0LmlzVFRZYFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgYHByb2Nlc3MuZW52Lk5PREVfRElTQUJMRV9DT0xPUlNgLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBlcnJvci5zaG93U291cmNlQ29kZSgpIC8vPT4gXCIgIDQgfCB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgIDUgfCBhIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgID4gNiB8ICAgYmFkXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgfCAgIF5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgNyB8IH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgOCB8IGIge1wiXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IGZldyBsaW5lcyBvZiBDU1Mgc291cmNlIHRoYXQgY2F1c2VkIHRoZSBlcnJvclxuICAgICAqL1xuICAgIHNob3dTb3VyY2VDb2RlKGNvbG9yKSB7XG4gICAgICAgIGlmICggIXRoaXMuc291cmNlICkgcmV0dXJuICcnO1xuXG4gICAgICAgIGxldCBjc3MgPSB0aGlzLnNvdXJjZTtcbiAgICAgICAgaWYgKCB0eXBlb2YgY29sb3IgPT09ICd1bmRlZmluZWQnICkgY29sb3IgPSBzdXBwb3J0c0NvbG9yO1xuICAgICAgICBpZiAoIGNvbG9yICkgY3NzID0gdGVybWluYWxIaWdobGlnaHQoY3NzKTtcblxuICAgICAgICBsZXQgbGluZXMgPSBjc3Muc3BsaXQoL1xccj9cXG4vKTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gTWF0aC5tYXgodGhpcy5saW5lIC0gMywgMCk7XG4gICAgICAgIGxldCBlbmQgICA9IE1hdGgubWluKHRoaXMubGluZSArIDIsIGxpbmVzLmxlbmd0aCk7XG5cbiAgICAgICAgbGV0IG1heFdpZHRoID0gU3RyaW5nKGVuZCkubGVuZ3RoO1xuICAgICAgICBsZXQgY29sb3JzID0gbmV3IGNoYWxrLmNvbnN0cnVjdG9yKHsgZW5hYmxlZDogdHJ1ZSB9KTtcblxuICAgICAgICBmdW5jdGlvbiBtYXJrKHRleHQpIHtcbiAgICAgICAgICAgIGlmICggY29sb3IgKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbG9ycy5yZWQuYm9sZCh0ZXh0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gYXNpZGUodGV4dCkge1xuICAgICAgICAgICAgaWYgKCBjb2xvciApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sb3JzLmdyYXkodGV4dCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGxpbmVzLnNsaWNlKHN0YXJ0LCBlbmQpLm1hcCggKGxpbmUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBsZXQgbnVtYmVyID0gc3RhcnQgKyAxICsgaW5kZXg7XG4gICAgICAgICAgICBsZXQgZ3V0dGVyID0gJyAnICsgKCcgJyArIG51bWJlcikuc2xpY2UoLW1heFdpZHRoKSArICcgfCAnO1xuICAgICAgICAgICAgaWYgKCBudW1iZXIgPT09IHRoaXMubGluZSApIHtcbiAgICAgICAgICAgICAgICBsZXQgc3BhY2luZyA9XG4gICAgICAgICAgICAgICAgICAgIGFzaWRlKGd1dHRlci5yZXBsYWNlKC9cXGQvZywgJyAnKSkgK1xuICAgICAgICAgICAgICAgICAgICBsaW5lLnNsaWNlKDAsIHRoaXMuY29sdW1uIC0gMSkucmVwbGFjZSgvW15cXHRdL2csICcgJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hcmsoJz4nKSArIGFzaWRlKGd1dHRlcikgKyBsaW5lICsgJ1xcbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgc3BhY2luZyArIG1hcmsoJ14nKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICcgJyArIGFzaWRlKGd1dHRlcikgKyBsaW5lO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGVycm9yIHBvc2l0aW9uLCBtZXNzYWdlIGFuZCBzb3VyY2UgY29kZSBvZiB0aGUgYnJva2VuIHBhcnQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGVycm9yLnRvU3RyaW5nKCkgLy89PiBcIkNzc1N5bnRheEVycm9yOiBhcHAuY3NzOjE6MTogVW5jbG9zZWQgYmxvY2tcbiAgICAgKiAgICAgICAgICAgICAgICAgIC8vICAgID4gMSB8IGEge1xuICAgICAqICAgICAgICAgICAgICAgICAgLy8gICAgICAgIHwgXlwiXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IGVycm9yIHBvc2l0aW9uLCBtZXNzYWdlIGFuZCBzb3VyY2UgY29kZVxuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICBsZXQgY29kZSA9IHRoaXMuc2hvd1NvdXJjZUNvZGUoKTtcbiAgICAgICAgaWYgKCBjb2RlICkge1xuICAgICAgICAgICAgY29kZSA9ICdcXG5cXG4nICsgY29kZSArICdcXG4nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWUgKyAnOiAnICsgdGhpcy5tZXNzYWdlICsgY29kZTtcbiAgICB9XG5cbiAgICBnZXQgZ2VuZXJhdGVkKCkge1xuICAgICAgICB3YXJuT25jZSgnQ3NzU3ludGF4RXJyb3IjZ2VuZXJhdGVkIGlzIGRlcHJlYWN0ZWQuIFVzZSBpbnB1dCBpbnN0ZWFkLicpO1xuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAbWVtYmVyb2YgQ3NzU3ludGF4RXJyb3IjXG4gICAgICogQG1lbWJlciB7SW5wdXR9IGlucHV0IC0gSW5wdXQgb2JqZWN0IHdpdGggUG9zdENTUyBpbnRlcm5hbCBpbmZvcm1hdGlvblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGFib3V0IGlucHV0IGZpbGUuIElmIGlucHV0IGhhcyBzb3VyY2UgbWFwXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSBwcmV2aW91cyB0b29sLCBQb3N0Q1NTIHdpbGwgdXNlIG9yaWdpblxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIChmb3IgZXhhbXBsZSwgU2Fzcykgc291cmNlLiBZb3UgY2FuIHVzZSB0aGlzXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0IHRvIGdldCBQb3N0Q1NTIGlucHV0IHNvdXJjZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogZXJyb3IuaW5wdXQuZmlsZSAvLz0+ICdhLmNzcydcbiAgICAgKiBlcnJvci5maWxlICAgICAgIC8vPT4gJ2Euc2FzcydcbiAgICAgKi9cblxufVxuXG5leHBvcnQgZGVmYXVsdCBDc3NTeW50YXhFcnJvcjtcbiJdfQ==