xhs-mcp 0.8.11 → 0.8.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/xhs-mcp.cjs +22 -15
  2. package/package.json +1 -1
package/dist/xhs-mcp.cjs CHANGED
@@ -11,6 +11,13 @@
11
11
  /******/ "use strict";
12
12
  /******/ var __webpack_modules__ = ({
13
13
 
14
+ /***/ 103:
15
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
16
+
17
+ eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ d: () => (/* binding */ BaseService)\n/* harmony export */ });\n/* harmony import */ var _core_browser_browser_manager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3977);\n\nclass BaseService {\n config;\n browserManager;\n constructor(config, browserManager) {\n this.config = config;\n this.browserManager = browserManager ?? new _core_browser_browser_manager__WEBPACK_IMPORTED_MODULE_0__/* .BrowserManager */ .Gd(config);\n }\n getBrowserManager() {\n return this.browserManager;\n }\n getConfig() {\n return this.config;\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTAzLmpzIiwibWFwcGluZ3MiOiI7Ozs7QUFDaUU7QUFFMUQsTUFBZSxXQUFXO0lBQ1osTUFBTSxDQUFTO0lBQ2YsY0FBYyxDQUFpQjtJQUVsRCxZQUFZLE1BQWMsRUFBRSxjQUErQjtRQUN6RCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsSUFBSSxJQUFJLG1GQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVTLGlCQUFpQjtRQUN6QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUVTLFNBQVM7UUFDakIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7Q0FDRiIsInNvdXJjZXMiOlsid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL2Jhc2Uuc2VydmljZS50cz9hMzRkIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgQnJvd3Nlck1hbmFnZXIgfSBmcm9tICcuLi9jb3JlL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VTZXJ2aWNlIHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbmZpZzogQ29uZmlnO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYnJvd3Nlck1hbmFnZXI6IEJyb3dzZXJNYW5hZ2VyO1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnLCBicm93c2VyTWFuYWdlcj86IEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgdGhpcy5icm93c2VyTWFuYWdlciA9IGJyb3dzZXJNYW5hZ2VyID8/IG5ldyBCcm93c2VyTWFuYWdlcihjb25maWcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEJyb3dzZXJNYW5hZ2VyKCk6IEJyb3dzZXJNYW5hZ2VyIHtcbiAgICByZXR1cm4gdGhpcy5icm93c2VyTWFuYWdlcjtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRDb25maWcoKTogQ29uZmlnIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWc7XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///103\n\n}");
18
+
19
+ /***/ }),
20
+
14
21
  /***/ 181:
15
22
  /***/ ((module) => {
16
23
 
@@ -42,7 +49,7 @@ module.exports = require("node:process");
42
49
  /***/ 2094:
43
50
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
44
51
 
45
- eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ IB: () => (/* binding */ validateRequiredParams),\n/* harmony export */ ah: () => (/* binding */ safeErrorHandler),\n/* harmony export */ mo: () => (/* binding */ createMcpErrorResponse),\n/* harmony export */ q$: () => (/* binding */ createMcpToolResponse),\n/* harmony export */ yy: () => (/* binding */ sleep)\n/* harmony export */ });\n/* unused harmony exports isString, isNumber, isArray, safeJsonParse, validatePublishNoteParams, createApiResponse, retryWithBackoff */\n/**\n * Common utility functions for XHS MCP Server\n */\n/**\n * Sleep utility function\n * @param ms - Milliseconds to sleep\n * @returns Promise that resolves after the specified time\n */\nfunction sleep(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n/**\n * Safe error handler that logs errors without throwing\n * @param error - Error to handle\n * @param context - Additional context for the error\n * @param logger - Logger instance to use\n */\nfunction safeErrorHandler(error, context, logger) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`${context}: ${errorMessage}`);\n}\n/**\n * Validate required parameters\n * @param params - Object containing parameters to validate\n * @param requiredKeys - Array of required parameter keys\n * @throws Error if any required parameter is missing\n */\nfunction validateRequiredParams(params, requiredKeys) {\n const missingKeys = requiredKeys.filter((key) => params[key] === undefined || params[key] === null || params[key] === '');\n if (missingKeys.length > 0) {\n throw new Error(`Missing required parameters: ${missingKeys.join(', ')}`);\n }\n}\n/**\n * Type guard to check if a value is a string\n */\nfunction isString(value) {\n return typeof value === 'string';\n}\n/**\n * Type guard to check if a value is a number\n */\nfunction isNumber(value) {\n return typeof value === 'number' && !Number.isNaN(value);\n}\n/**\n * Type guard to check if a value is an array\n */\nfunction isArray(value) {\n return Array.isArray(value);\n}\n/**\n * Safely parse JSON string\n * @param jsonString - JSON string to parse\n * @param fallback - Fallback value if parsing fails\n * @returns Parsed object or fallback value\n */\nfunction safeJsonParse(jsonString, fallback) {\n try {\n return JSON.parse(jsonString);\n }\n catch {\n return fallback;\n }\n}\n/**\n * Validate publish note parameters with length constraints\n * @param title - Note title\n * @param note - Note content\n * @param imagePaths - Array of image paths\n * @throws Error if any parameter violates constraints\n */\nfunction validatePublishNoteParams(title, note, imagePaths) {\n // Validate title length (max 20 characters)\n if (title && title.length > 20) {\n throw new Error(`Title length cannot exceed 20 characters. Current length: ${title.length}`);\n }\n // Validate note content length (max 1000 characters)\n if (note && note.length > 1000) {\n throw new Error(`Note content length cannot exceed 1000 characters. Current length: ${note.length}`);\n }\n // Validate image count (max 18 images)\n if (imagePaths && imagePaths.length > 18) {\n throw new Error(`Maximum 18 images allowed. Current count: ${imagePaths.length}`);\n }\n}\n/**\n * Create a standardized response object\n * @param success - Whether the operation was successful\n * @param data - Optional data to include\n * @param message - Optional message\n * @param error - Optional error information\n * @returns Standardized response object\n */\nfunction createApiResponse(success, data, message, error) {\n const response = { success };\n if (data !== undefined)\n response.data = data;\n if (message !== undefined)\n response.message = message;\n if (error !== undefined)\n response.error = error;\n return response;\n}\n/**\n * Retry a function with exponential backoff\n * @param fn - Function to retry\n * @param maxRetries - Maximum number of retries\n * @param baseDelay - Base delay in milliseconds\n * @returns Promise that resolves with the function result\n */\nasync function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {\n let lastError;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n }\n catch (error) {\n lastError = error;\n if (attempt === maxRetries) {\n throw lastError;\n }\n const delay = baseDelay * Math.pow(2, attempt);\n await sleep(delay);\n }\n }\n throw lastError;\n}\n/**\n * Create a standardized MCP tool response\n * @param data - Data to include in the response\n * @returns Standardized MCP response format\n */\nfunction createMcpToolResponse(data) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(data, null, 2),\n },\n ],\n };\n}\n/**\n * Create a standardized MCP error response\n * @param error - Error to format\n * @returns Standardized MCP error response format\n */\nfunction createMcpErrorResponse(error) {\n const errorData = error instanceof Error\n ? {\n success: false,\n error: 'UnknownError',\n message: error.message,\n stack: error.stack,\n }\n : {\n success: false,\n error: 'UnknownError',\n message: String(error),\n };\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(errorData, null, 2),\n },\n ],\n };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O1FBQ0wsT0FBTyxFQUFFO1lBQ1A7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDcEM7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNJLFNBQVMsc0JBQXNCLENBQUMsS0FBYztJQUduRCxNQUFNLFNBQVMsR0FDYixLQUFLLFlBQVksS0FBSztRQUNwQixDQUFDLENBQUM7WUFDRSxPQUFPLEVBQUUsS0FBSztZQUNkLEtBQUssRUFBRSxjQUFjO1lBQ3JCLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztZQUN0QixLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUs7U0FDbkI7UUFDSCxDQUFDLENBQUM7WUFDRSxPQUFPLEVBQUUsS0FBSztZQUNkLEtBQUssRUFBRSxjQUFjO1lBQ3JCLE9BQU8sRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDO1NBQ3ZCLENBQUM7SUFFUixPQUFPO1FBQ0wsT0FBTyxFQUFFO1lBQ1A7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDekM7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvdXRpbHMudHM/OWM1YyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbW1vbiB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG4vKipcbiAqIFNsZWVwIHV0aWxpdHkgZnVuY3Rpb25cbiAqIEBwYXJhbSBtcyAtIE1pbGxpc2Vjb25kcyB0byBzbGVlcFxuICogQHJldHVybnMgUHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBzcGVjaWZpZWQgdGltZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbn1cblxuLyoqXG4gKiBTYWZlIGVycm9yIGhhbmRsZXIgdGhhdCBsb2dzIGVycm9ycyB3aXRob3V0IHRocm93aW5nXG4gKiBAcGFyYW0gZXJyb3IgLSBFcnJvciB0byBoYW5kbGVcbiAqIEBwYXJhbSBjb250ZXh0IC0gQWRkaXRpb25hbCBjb250ZXh0IGZvciB0aGUgZXJyb3JcbiAqIEBwYXJhbSBsb2dnZXIgLSBMb2dnZXIgaW5zdGFuY2UgdG8gdXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYWZlRXJyb3JIYW5kbGVyKFxuICBlcnJvcjogdW5rbm93bixcbiAgY29udGV4dDogc3RyaW5nLFxuICBsb2dnZXI6IHsgZXJyb3I6IChtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZCB9XG4pOiB2b2lkIHtcbiAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICBsb2dnZXIuZXJyb3IoYCR7Y29udGV4dH06ICR7ZXJyb3JNZXNzYWdlfWApO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHJlcXVpcmVkIHBhcmFtZXRlcnNcbiAqIEBwYXJhbSBwYXJhbXMgLSBPYmplY3QgY29udGFpbmluZyBwYXJhbWV0ZXJzIHRvIHZhbGlkYXRlXG4gKiBAcGFyYW0gcmVxdWlyZWRLZXlzIC0gQXJyYXkgb2YgcmVxdWlyZWQgcGFyYW1ldGVyIGtleXNcbiAqIEB0aHJvd3MgRXJyb3IgaWYgYW55IHJlcXVpcmVkIHBhcmFtZXRlciBpcyBtaXNzaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zKFxuICBwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICByZXF1aXJlZEtleXM6IHN0cmluZ1tdXG4pOiB2b2lkIHtcbiAgY29uc3QgbWlzc2luZ0tleXMgPSByZXF1aXJlZEtleXMuZmlsdGVyKFxuICAgIChrZXkpID0+IHBhcmFtc1trZXldID09PSB1bmRlZmluZWQgfHwgcGFyYW1zW2tleV0gPT09IG51bGwgfHwgcGFyYW1zW2tleV0gPT09ICcnXG4gICk7XG5cbiAgaWYgKG1pc3NpbmdLZXlzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyczogJHttaXNzaW5nS2V5cy5qb2luKCcsICcpfWApO1xuICB9XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhIG51bWJlclxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOdW1iZXIodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBudW1iZXIge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiAhTnVtYmVyLmlzTmFOKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYW4gYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXJyYXk8VD4odmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBUW10ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG5cbi8qKlxuICogU2FmZWx5IHBhcnNlIEpTT04gc3RyaW5nXG4gKiBAcGFyYW0ganNvblN0cmluZyAtIEpTT04gc3RyaW5nIHRvIHBhcnNlXG4gKiBAcGFyYW0gZmFsbGJhY2sgLSBGYWxsYmFjayB2YWx1ZSBpZiBwYXJzaW5nIGZhaWxzXG4gKiBAcmV0dXJucyBQYXJzZWQgb2JqZWN0IG9yIGZhbGxiYWNrIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYWZlSnNvblBhcnNlPFQ+KGpzb25TdHJpbmc6IHN0cmluZywgZmFsbGJhY2s6IFQpOiBUIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShqc29uU3RyaW5nKSBhcyBUO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsbGJhY2s7XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBwdWJsaXNoIG5vdGUgcGFyYW1ldGVycyB3aXRoIGxlbmd0aCBjb25zdHJhaW50c1xuICogQHBhcmFtIHRpdGxlIC0gTm90ZSB0aXRsZVxuICogQHBhcmFtIG5vdGUgLSBOb3RlIGNvbnRlbnRcbiAqIEBwYXJhbSBpbWFnZVBhdGhzIC0gQXJyYXkgb2YgaW1hZ2UgcGF0aHNcbiAqIEB0aHJvd3MgRXJyb3IgaWYgYW55IHBhcmFtZXRlciB2aW9sYXRlcyBjb25zdHJhaW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVQdWJsaXNoTm90ZVBhcmFtcyh0aXRsZTogc3RyaW5nLCBub3RlOiBzdHJpbmcsIGltYWdlUGF0aHM6IHN0cmluZ1tdKTogdm9pZCB7XG4gIC8vIFZhbGlkYXRlIHRpdGxlIGxlbmd0aCAobWF4IDIwIGNoYXJhY3RlcnMpXG4gIGlmICh0aXRsZSAmJiB0aXRsZS5sZW5ndGggPiAyMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGl0bGUgbGVuZ3RoIGNhbm5vdCBleGNlZWQgMjAgY2hhcmFjdGVycy4gQ3VycmVudCBsZW5ndGg6ICR7dGl0bGUubGVuZ3RofWApO1xuICB9XG5cbiAgLy8gVmFsaWRhdGUgbm90ZSBjb250ZW50IGxlbmd0aCAobWF4IDEwMDAgY2hhcmFjdGVycylcbiAgaWYgKG5vdGUgJiYgbm90ZS5sZW5ndGggPiAxMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYE5vdGUgY29udGVudCBsZW5ndGggY2Fubm90IGV4Y2VlZCAxMDAwIGNoYXJhY3RlcnMuIEN1cnJlbnQgbGVuZ3RoOiAke25vdGUubGVuZ3RofWBcbiAgICApO1xuICB9XG5cbiAgLy8gVmFsaWRhdGUgaW1hZ2UgY291bnQgKG1heCAxOCBpbWFnZXMpXG4gIGlmIChpbWFnZVBhdGhzICYmIGltYWdlUGF0aHMubGVuZ3RoID4gMTgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE1heGltdW0gMTggaW1hZ2VzIGFsbG93ZWQuIEN1cnJlbnQgY291bnQ6ICR7aW1hZ2VQYXRocy5sZW5ndGh9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBzdGFuZGFyZGl6ZWQgcmVzcG9uc2Ugb2JqZWN0XG4gKiBAcGFyYW0gc3VjY2VzcyAtIFdoZXRoZXIgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bFxuICogQHBhcmFtIGRhdGEgLSBPcHRpb25hbCBkYXRhIHRvIGluY2x1ZGVcbiAqIEBwYXJhbSBtZXNzYWdlIC0gT3B0aW9uYWwgbWVzc2FnZVxuICogQHBhcmFtIGVycm9yIC0gT3B0aW9uYWwgZXJyb3IgaW5mb3JtYXRpb25cbiAqIEByZXR1cm5zIFN0YW5kYXJkaXplZCByZXNwb25zZSBvYmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFwaVJlc3BvbnNlPFQgPSB1bmtub3duPihcbiAgc3VjY2VzczogYm9vbGVhbixcbiAgZGF0YT86IFQsXG4gIG1lc3NhZ2U/OiBzdHJpbmcsXG4gIGVycm9yPzogc3RyaW5nXG4pOiB7IHN1Y2Nlc3M6IGJvb2xlYW47IGRhdGE/OiBUOyBtZXNzYWdlPzogc3RyaW5nOyBlcnJvcj86IHN0cmluZyB9IHtcbiAgY29uc3QgcmVzcG9uc2U6IHsgc3VjY2VzczogYm9vbGVhbjsgZGF0YT86IFQ7IG1lc3NhZ2U/OiBzdHJpbmc7IGVycm9yPzogc3RyaW5nIH0gPSB7IHN1Y2Nlc3MgfTtcblxuICBpZiAoZGF0YSAhPT0gdW5kZWZpbmVkKSByZXNwb25zZS5kYXRhID0gZGF0YTtcbiAgaWYgKG1lc3NhZ2UgIT09IHVuZGVmaW5lZCkgcmVzcG9uc2UubWVzc2FnZSA9IG1lc3NhZ2U7XG4gIGlmIChlcnJvciAhPT0gdW5kZWZpbmVkKSByZXNwb25zZS5lcnJvciA9IGVycm9yO1xuXG4gIHJldHVybiByZXNwb25zZTtcbn1cblxuLyoqXG4gKiBSZXRyeSBhIGZ1bmN0aW9uIHdpdGggZXhwb25lbnRpYWwgYmFja29mZlxuICogQHBhcmFtIGZuIC0gRnVuY3Rpb24gdG8gcmV0cnlcbiAqIEBwYXJhbSBtYXhSZXRyaWVzIC0gTWF4aW11bSBudW1iZXIgb2YgcmV0cmllc1xuICogQHBhcmFtIGJhc2VEZWxheSAtIEJhc2UgZGVsYXkgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgZnVuY3Rpb24gcmVzdWx0XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXRyeVdpdGhCYWNrb2ZmPFQ+KFxuICBmbjogKCkgPT4gUHJvbWlzZTxUPixcbiAgbWF4UmV0cmllczogbnVtYmVyID0gMyxcbiAgYmFzZURlbGF5OiBudW1iZXIgPSAxMDAwXG4pOiBQcm9taXNlPFQ+IHtcbiAgbGV0IGxhc3RFcnJvcjogRXJyb3I7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPD0gbWF4UmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBmbigpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsYXN0RXJyb3IgPSBlcnJvciBhcyBFcnJvcjtcblxuICAgICAgaWYgKGF0dGVtcHQgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgdGhyb3cgbGFzdEVycm9yO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZWxheSA9IGJhc2VEZWxheSAqIE1hdGgucG93KDIsIGF0dGVtcHQpO1xuICAgICAgYXdhaXQgc2xlZXAoZGVsYXkpO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IGxhc3RFcnJvciE7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgc3RhbmRhcmRpemVkIE1DUCB0b29sIHJlc3BvbnNlXG4gKiBAcGFyYW0gZGF0YSAtIERhdGEgdG8gaW5jbHVkZSBpbiB0aGUgcmVzcG9uc2VcbiAqIEByZXR1cm5zIFN0YW5kYXJkaXplZCBNQ1AgcmVzcG9uc2UgZm9ybWF0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNY3BUb29sUmVzcG9uc2U8VCA9IHVua25vd24+KFxuICBkYXRhOiBUXG4pOiB7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfSB7XG4gIHJldHVybiB7XG4gICAgY29udGVudDogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIHN0YW5kYXJkaXplZCBNQ1AgZXJyb3IgcmVzcG9uc2VcbiAqIEBwYXJhbSBlcnJvciAtIEVycm9yIHRvIGZvcm1hdFxuICogQHJldHVybnMgU3RhbmRhcmRpemVkIE1DUCBlcnJvciByZXNwb25zZSBmb3JtYXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1jcEVycm9yUmVzcG9uc2UoZXJyb3I6IHVua25vd24pOiB7XG4gIGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT47XG59IHtcbiAgY29uc3QgZXJyb3JEYXRhID1cbiAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yXG4gICAgICA/IHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcjogJ1Vua25vd25FcnJvcicsXG4gICAgICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSxcbiAgICAgICAgICBzdGFjazogZXJyb3Iuc3RhY2ssXG4gICAgICAgIH1cbiAgICAgIDoge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGVycm9yOiAnVW5rbm93bkVycm9yJyxcbiAgICAgICAgICBtZXNzYWdlOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICB9O1xuXG4gIHJldHVybiB7XG4gICAgY29udGVudDogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KGVycm9yRGF0YSwgbnVsbCwgMiksXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2094\n\n}");
52
+ eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ IB: () => (/* binding */ validateRequiredParams),\n/* harmony export */ ah: () => (/* binding */ safeErrorHandler),\n/* harmony export */ mo: () => (/* binding */ createMcpErrorResponse),\n/* harmony export */ q$: () => (/* binding */ createMcpToolResponse),\n/* harmony export */ yy: () => (/* binding */ sleep)\n/* harmony export */ });\n/* unused harmony exports isString, isNumber, isArray, safeJsonParse, validatePublishNoteParams, createApiResponse, retryWithBackoff */\n/**\n * Common utility functions for XHS MCP Server\n */\n/**\n * Sleep utility function\n * @param ms - Milliseconds to sleep\n * @returns Promise that resolves after the specified time\n */\nfunction sleep(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n/**\n * Safe error handler that logs errors without throwing\n * @param error - Error to handle\n * @param context - Additional context for the error\n * @param logger - Logger instance to use\n */\nfunction safeErrorHandler(error, context, logger) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`${context}: ${errorMessage}`);\n}\n/**\n * Validate required parameters\n * @param params - Object containing parameters to validate\n * @param requiredKeys - Array of required parameter keys\n * @throws Error if any required parameter is missing\n */\nfunction validateRequiredParams(params, requiredKeys) {\n const missingKeys = requiredKeys.filter((key) => params[key] === undefined || params[key] === null || params[key] === '');\n if (missingKeys.length > 0) {\n throw new Error(`Missing required parameters: ${missingKeys.join(', ')}`);\n }\n}\n/**\n * Type guard to check if a value is a string\n */\nfunction isString(value) {\n return typeof value === 'string';\n}\n/**\n * Type guard to check if a value is a number\n */\nfunction isNumber(value) {\n return typeof value === 'number' && !Number.isNaN(value);\n}\n/**\n * Type guard to check if a value is an array\n */\nfunction isArray(value) {\n return Array.isArray(value);\n}\n/**\n * Safely parse JSON string\n * @param jsonString - JSON string to parse\n * @param fallback - Fallback value if parsing fails\n * @returns Parsed object or fallback value\n */\nfunction safeJsonParse(jsonString, fallback) {\n try {\n return JSON.parse(jsonString);\n }\n catch {\n return fallback;\n }\n}\n/**\n * Validate publish note parameters with length constraints\n * @param title - Note title\n * @param note - Note content\n * @param imagePaths - Array of image paths\n * @throws Error if any parameter violates constraints\n */\nfunction validatePublishNoteParams(title, note, imagePaths) {\n // Validate title length (max 20 characters)\n if (title && title.length > 20) {\n throw new Error(`Title length cannot exceed 20 characters. Current length: ${title.length}`);\n }\n // Validate note content length (max 1000 characters)\n if (note && note.length > 1000) {\n throw new Error(`Note content length cannot exceed 1000 characters. Current length: ${note.length}`);\n }\n // Validate image count (max 18 images)\n if (imagePaths && imagePaths.length > 18) {\n throw new Error(`Maximum 18 images allowed. Current count: ${imagePaths.length}`);\n }\n}\n/**\n * Create a standardized response object\n * @param success - Whether the operation was successful\n * @param data - Optional data to include\n * @param message - Optional message\n * @param error - Optional error information\n * @returns Standardized response object\n */\nfunction createApiResponse(success, data, message, error) {\n const response = { success };\n if (data !== undefined)\n response.data = data;\n if (message !== undefined)\n response.message = message;\n if (error !== undefined)\n response.error = error;\n return response;\n}\n/**\n * Retry a function with exponential backoff\n * @param fn - Function to retry\n * @param maxRetries - Maximum number of retries\n * @param baseDelay - Base delay in milliseconds\n * @returns Promise that resolves with the function result\n */\nasync function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {\n let lastError;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n }\n catch (error) {\n lastError = error;\n if (attempt === maxRetries) {\n throw lastError;\n }\n const delay = baseDelay * Math.pow(2, attempt);\n await sleep(delay);\n }\n }\n throw lastError;\n}\n/**\n * Create a standardized MCP tool response\n * @param data - Data to include in the response\n * @returns Standardized MCP response format\n */\nfunction createMcpToolResponse(data) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(data, null, 2),\n },\n ],\n };\n}\n/**\n * Create a standardized MCP error response\n * @param error - Error to format\n * @returns Standardized MCP error response format\n */\nfunction createMcpErrorResponse(error) {\n const errorData = error instanceof Error\n ? {\n success: false,\n error: 'UnknownError',\n message: error.message,\n }\n : {\n success: false,\n error: 'UnknownError',\n message: String(error),\n };\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(errorData, null, 2),\n },\n ],\n };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O1FBQ0wsT0FBTyxFQUFFO1lBQ1A7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDcEM7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNJLFNBQVMsc0JBQXNCLENBQUMsS0FBYztJQUduRCxNQUFNLFNBQVMsR0FDYixLQUFLLFlBQVksS0FBSztRQUNwQixDQUFDLENBQUM7WUFDRSxPQUFPLEVBQUUsS0FBSztZQUNkLEtBQUssRUFBRSxjQUFjO1lBQ3JCLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztTQUN2QjtRQUNILENBQUMsQ0FBQztZQUNFLE9BQU8sRUFBRSxLQUFLO1lBQ2QsS0FBSyxFQUFFLGNBQWM7WUFDckIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUM7U0FDdkIsQ0FBQztJQUVSLE9BQU87UUFDTCxPQUFPLEVBQUU7WUFDUDtnQkFDRSxJQUFJLEVBQUUsTUFBTTtnQkFDWixJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzthQUN6QztTQUNGO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NoYXJlZC91dGlscy50cz85YzVjIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29tbW9uIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbi8qKlxuICogU2xlZXAgdXRpbGl0eSBmdW5jdGlvblxuICogQHBhcmFtIG1zIC0gTWlsbGlzZWNvbmRzIHRvIHNsZWVwXG4gKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIHNwZWNpZmllZCB0aW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xufVxuXG4vKipcbiAqIFNhZmUgZXJyb3IgaGFuZGxlciB0aGF0IGxvZ3MgZXJyb3JzIHdpdGhvdXQgdGhyb3dpbmdcbiAqIEBwYXJhbSBlcnJvciAtIEVycm9yIHRvIGhhbmRsZVxuICogQHBhcmFtIGNvbnRleHQgLSBBZGRpdGlvbmFsIGNvbnRleHQgZm9yIHRoZSBlcnJvclxuICogQHBhcmFtIGxvZ2dlciAtIExvZ2dlciBpbnN0YW5jZSB0byB1c2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNhZmVFcnJvckhhbmRsZXIoXG4gIGVycm9yOiB1bmtub3duLFxuICBjb250ZXh0OiBzdHJpbmcsXG4gIGxvZ2dlcjogeyBlcnJvcjogKG1lc3NhZ2U6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkIH1cbik6IHZvaWQge1xuICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gIGxvZ2dlci5lcnJvcihgJHtjb250ZXh0fTogJHtlcnJvck1lc3NhZ2V9YCk7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgcmVxdWlyZWQgcGFyYW1ldGVyc1xuICogQHBhcmFtIHBhcmFtcyAtIE9iamVjdCBjb250YWluaW5nIHBhcmFtZXRlcnMgdG8gdmFsaWRhdGVcbiAqIEBwYXJhbSByZXF1aXJlZEtleXMgLSBBcnJheSBvZiByZXF1aXJlZCBwYXJhbWV0ZXIga2V5c1xuICogQHRocm93cyBFcnJvciBpZiBhbnkgcmVxdWlyZWQgcGFyYW1ldGVyIGlzIG1pc3NpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUmVxdWlyZWRQYXJhbXMoXG4gIHBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIHJlcXVpcmVkS2V5czogc3RyaW5nW11cbik6IHZvaWQge1xuICBjb25zdCBtaXNzaW5nS2V5cyA9IHJlcXVpcmVkS2V5cy5maWx0ZXIoXG4gICAgKGtleSkgPT4gcGFyYW1zW2tleV0gPT09IHVuZGVmaW5lZCB8fCBwYXJhbXNba2V5XSA9PT0gbnVsbCB8fCBwYXJhbXNba2V5XSA9PT0gJydcbiAgKTtcblxuICBpZiAobWlzc2luZ0tleXMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXJzOiAke21pc3NpbmdLZXlzLmpvaW4oJywgJyl9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYSBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgc3RyaW5nIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZyc7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgbnVtYmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmICFOdW1iZXIuaXNOYU4odmFsdWUpO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhbiBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBcnJheTxUPih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFRbXSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cblxuLyoqXG4gKiBTYWZlbHkgcGFyc2UgSlNPTiBzdHJpbmdcbiAqIEBwYXJhbSBqc29uU3RyaW5nIC0gSlNPTiBzdHJpbmcgdG8gcGFyc2VcbiAqIEBwYXJhbSBmYWxsYmFjayAtIEZhbGxiYWNrIHZhbHVlIGlmIHBhcnNpbmcgZmFpbHNcbiAqIEByZXR1cm5zIFBhcnNlZCBvYmplY3Qgb3IgZmFsbGJhY2sgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNhZmVKc29uUGFyc2U8VD4oanNvblN0cmluZzogc3RyaW5nLCBmYWxsYmFjazogVCk6IFQge1xuICB0cnkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGpzb25TdHJpbmcpIGFzIFQ7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxsYmFjaztcbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlIHB1Ymxpc2ggbm90ZSBwYXJhbWV0ZXJzIHdpdGggbGVuZ3RoIGNvbnN0cmFpbnRzXG4gKiBAcGFyYW0gdGl0bGUgLSBOb3RlIHRpdGxlXG4gKiBAcGFyYW0gbm90ZSAtIE5vdGUgY29udGVudFxuICogQHBhcmFtIGltYWdlUGF0aHMgLSBBcnJheSBvZiBpbWFnZSBwYXRoc1xuICogQHRocm93cyBFcnJvciBpZiBhbnkgcGFyYW1ldGVyIHZpb2xhdGVzIGNvbnN0cmFpbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVB1Ymxpc2hOb3RlUGFyYW1zKHRpdGxlOiBzdHJpbmcsIG5vdGU6IHN0cmluZywgaW1hZ2VQYXRoczogc3RyaW5nW10pOiB2b2lkIHtcbiAgLy8gVmFsaWRhdGUgdGl0bGUgbGVuZ3RoIChtYXggMjAgY2hhcmFjdGVycylcbiAgaWYgKHRpdGxlICYmIHRpdGxlLmxlbmd0aCA+IDIwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUaXRsZSBsZW5ndGggY2Fubm90IGV4Y2VlZCAyMCBjaGFyYWN0ZXJzLiBDdXJyZW50IGxlbmd0aDogJHt0aXRsZS5sZW5ndGh9YCk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBub3RlIGNvbnRlbnQgbGVuZ3RoIChtYXggMTAwMCBjaGFyYWN0ZXJzKVxuICBpZiAobm90ZSAmJiBub3RlLmxlbmd0aCA+IDEwMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTm90ZSBjb250ZW50IGxlbmd0aCBjYW5ub3QgZXhjZWVkIDEwMDAgY2hhcmFjdGVycy4gQ3VycmVudCBsZW5ndGg6ICR7bm90ZS5sZW5ndGh9YFxuICAgICk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBpbWFnZSBjb3VudCAobWF4IDE4IGltYWdlcylcbiAgaWYgKGltYWdlUGF0aHMgJiYgaW1hZ2VQYXRocy5sZW5ndGggPiAxOCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTWF4aW11bSAxOCBpbWFnZXMgYWxsb3dlZC4gQ3VycmVudCBjb3VudDogJHtpbWFnZVBhdGhzLmxlbmd0aH1gKTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhIHN0YW5kYXJkaXplZCByZXNwb25zZSBvYmplY3RcbiAqIEBwYXJhbSBzdWNjZXNzIC0gV2hldGhlciB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsXG4gKiBAcGFyYW0gZGF0YSAtIE9wdGlvbmFsIGRhdGEgdG8gaW5jbHVkZVxuICogQHBhcmFtIG1lc3NhZ2UgLSBPcHRpb25hbCBtZXNzYWdlXG4gKiBAcGFyYW0gZXJyb3IgLSBPcHRpb25hbCBlcnJvciBpbmZvcm1hdGlvblxuICogQHJldHVybnMgU3RhbmRhcmRpemVkIHJlc3BvbnNlIG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXBpUmVzcG9uc2U8VCA9IHVua25vd24+KFxuICBzdWNjZXNzOiBib29sZWFuLFxuICBkYXRhPzogVCxcbiAgbWVzc2FnZT86IHN0cmluZyxcbiAgZXJyb3I/OiBzdHJpbmdcbik6IHsgc3VjY2VzczogYm9vbGVhbjsgZGF0YT86IFQ7IG1lc3NhZ2U/OiBzdHJpbmc7IGVycm9yPzogc3RyaW5nIH0ge1xuICBjb25zdCByZXNwb25zZTogeyBzdWNjZXNzOiBib29sZWFuOyBkYXRhPzogVDsgbWVzc2FnZT86IHN0cmluZzsgZXJyb3I/OiBzdHJpbmcgfSA9IHsgc3VjY2VzcyB9O1xuXG4gIGlmIChkYXRhICE9PSB1bmRlZmluZWQpIHJlc3BvbnNlLmRhdGEgPSBkYXRhO1xuICBpZiAobWVzc2FnZSAhPT0gdW5kZWZpbmVkKSByZXNwb25zZS5tZXNzYWdlID0gbWVzc2FnZTtcbiAgaWYgKGVycm9yICE9PSB1bmRlZmluZWQpIHJlc3BvbnNlLmVycm9yID0gZXJyb3I7XG5cbiAgcmV0dXJuIHJlc3BvbnNlO1xufVxuXG4vKipcbiAqIFJldHJ5IGEgZnVuY3Rpb24gd2l0aCBleHBvbmVudGlhbCBiYWNrb2ZmXG4gKiBAcGFyYW0gZm4gLSBGdW5jdGlvbiB0byByZXRyeVxuICogQHBhcmFtIG1heFJldHJpZXMgLSBNYXhpbXVtIG51bWJlciBvZiByZXRyaWVzXG4gKiBAcGFyYW0gYmFzZURlbGF5IC0gQmFzZSBkZWxheSBpbiBtaWxsaXNlY29uZHNcbiAqIEByZXR1cm5zIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBmdW5jdGlvbiByZXN1bHRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJldHJ5V2l0aEJhY2tvZmY8VD4oXG4gIGZuOiAoKSA9PiBQcm9taXNlPFQ+LFxuICBtYXhSZXRyaWVzOiBudW1iZXIgPSAzLFxuICBiYXNlRGVsYXk6IG51bWJlciA9IDEwMDBcbik6IFByb21pc2U8VD4ge1xuICBsZXQgbGFzdEVycm9yOiBFcnJvcjtcblxuICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgYXR0ZW1wdCA8PSBtYXhSZXRyaWVzOyBhdHRlbXB0KyspIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxhc3RFcnJvciA9IGVycm9yIGFzIEVycm9yO1xuXG4gICAgICBpZiAoYXR0ZW1wdCA9PT0gbWF4UmV0cmllcykge1xuICAgICAgICB0aHJvdyBsYXN0RXJyb3I7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlbGF5ID0gYmFzZURlbGF5ICogTWF0aC5wb3coMiwgYXR0ZW1wdCk7XG4gICAgICBhd2FpdCBzbGVlcChkZWxheSk7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbGFzdEVycm9yITtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBzdGFuZGFyZGl6ZWQgTUNQIHRvb2wgcmVzcG9uc2VcbiAqIEBwYXJhbSBkYXRhIC0gRGF0YSB0byBpbmNsdWRlIGluIHRoZSByZXNwb25zZVxuICogQHJldHVybnMgU3RhbmRhcmRpemVkIE1DUCByZXNwb25zZSBmb3JtYXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1jcFRvb2xSZXNwb25zZTxUID0gdW5rbm93bj4oXG4gIGRhdGE6IFRcbik6IHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9IHtcbiAgcmV0dXJuIHtcbiAgICBjb250ZW50OiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMiksXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgc3RhbmRhcmRpemVkIE1DUCBlcnJvciByZXNwb25zZVxuICogQHBhcmFtIGVycm9yIC0gRXJyb3IgdG8gZm9ybWF0XG4gKiBAcmV0dXJucyBTdGFuZGFyZGl6ZWQgTUNQIGVycm9yIHJlc3BvbnNlIGZvcm1hdFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWNwRXJyb3JSZXNwb25zZShlcnJvcjogdW5rbm93bik6IHtcbiAgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9Pjtcbn0ge1xuICBjb25zdCBlcnJvckRhdGEgPVxuICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgID8ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGVycm9yOiAnVW5rbm93bkVycm9yJyxcbiAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLFxuICAgICAgICB9XG4gICAgICA6IHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcjogJ1Vua25vd25FcnJvcicsXG4gICAgICAgICAgbWVzc2FnZTogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgfTtcblxuICByZXR1cm4ge1xuICAgIGNvbnRlbnQ6IFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeShlcnJvckRhdGEsIG51bGwsIDIpLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2094\n\n}");
46
53
 
47
54
  /***/ }),
48
55
 
@@ -60,17 +67,17 @@ eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n zj: () => (
60
67
 
61
68
  /***/ }),
62
69
 
63
- /***/ 3100:
64
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
70
+ /***/ 3193:
71
+ /***/ ((module) => {
65
72
 
66
- eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n d: () => (/* binding */ BaseService)\n});\n\n// EXTERNAL MODULE: external \"puppeteer\"\nvar external_puppeteer_ = __webpack_require__(9916);\nvar external_puppeteer_default = /*#__PURE__*/__webpack_require__.n(external_puppeteer_);\n// EXTERNAL MODULE: ./src/shared/errors.ts\nvar errors = __webpack_require__(7636);\n// EXTERNAL MODULE: ./src/shared/config.ts + 1 modules\nvar shared_config = __webpack_require__(2207);\n// EXTERNAL MODULE: ./src/shared/cookies.ts\nvar shared_cookies = __webpack_require__(4760);\n// EXTERNAL MODULE: ./src/shared/logger.ts\nvar logger = __webpack_require__(9135);\n// EXTERNAL MODULE: ./src/shared/utils.ts\nvar utils = __webpack_require__(2094);\n;// ./src/core/browser/browser-pool.service.ts\n/**\n * Browser Pool Service for XHS Operations\n * Manages browser instance lifecycle with pooling, health monitoring, and automatic cleanup\n */\n\n\n\n\n\nclass BrowserPoolService {\n config;\n pool = new Map();\n options;\n healthCheckTimer = null;\n cleanupTimer = null;\n isShuttingDown = false;\n constructor(config, options) {\n this.config = config || (0,shared_config/* getConfig */.zj)();\n // Set default options with configuration from environment or defaults\n this.options = {\n minInstances: options?.minInstances ?? 2,\n maxInstances: options?.maxInstances ?? 5,\n idleTimeout: options?.idleTimeout ?? 300000, // 5 minutes\n maxAge: options?.maxAge ?? 1800000, // 30 minutes\n healthCheckInterval: options?.healthCheckInterval ?? 60000, // 1 minute\n maxUsageCount: options?.maxUsageCount ?? 100,\n };\n this.startHealthMonitoring();\n this.startCleanupMonitoring();\n }\n /**\n * Acquire a browser instance from the pool\n */\n async acquireBrowser(options) {\n if (this.isShuttingDown) {\n throw new errors/* XHSError */.a_('Browser pool is shutting down', 'BrowserPoolError');\n }\n const timeout = options?.timeout ?? 30000;\n const startTime = Date.now();\n while (Date.now() - startTime < timeout) {\n // Try to find an available healthy browser\n const availableBrowser = this.findAvailableBrowser();\n if (availableBrowser) {\n availableBrowser.isAvailable = false;\n availableBrowser.lastUsed = new Date();\n availableBrowser.usageCount++;\n logger/* logger */.v.debug(`Acquired browser ${availableBrowser.id} from pool`);\n return availableBrowser;\n }\n // If no available browser and we can create more, create one\n if (this.pool.size < this.options.maxInstances) {\n try {\n const newBrowser = await this.createBrowserInstance();\n newBrowser.isAvailable = false;\n newBrowser.lastUsed = new Date();\n newBrowser.usageCount++;\n logger/* logger */.v.info(`Created new browser ${newBrowser.id} for pool`);\n return newBrowser;\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to create new browser instance: ${error}`);\n }\n }\n // Wait a bit before retrying\n await (0,utils/* sleep */.yy)(100);\n }\n throw new errors/* XHSError */.a_(`Failed to acquire browser within ${timeout}ms timeout`, 'BrowserPoolTimeout', { timeout, poolSize: this.pool.size, availableCount: this.getAvailableCount() });\n }\n /**\n * Release a browser instance back to the pool\n */\n async releaseBrowser(browser) {\n const managedBrowser = this.pool.get(browser.id);\n if (!managedBrowser) {\n logger/* logger */.v.warn(`Attempted to release unknown browser ${browser.id}`);\n return;\n }\n // Check if browser should be retired due to age or usage\n const shouldRetire = this.shouldRetireBrowser(managedBrowser);\n if (shouldRetire) {\n logger/* logger */.v.info(`Retiring browser ${browser.id} due to ${shouldRetire}`);\n await this.removeBrowserFromPool(browser.id);\n // Ensure we maintain minimum instances\n await this.ensureMinimumInstances();\n return;\n }\n // Perform health check before returning to pool\n const isHealthy = await this.checkBrowserHealth(managedBrowser);\n if (!isHealthy) {\n logger/* logger */.v.warn(`Browser ${browser.id} failed health check, removing from pool`);\n await this.removeBrowserFromPool(browser.id);\n await this.ensureMinimumInstances();\n return;\n }\n // Return to pool\n managedBrowser.isAvailable = true;\n managedBrowser.isHealthy = true;\n logger/* logger */.v.debug(`Released browser ${browser.id} back to pool`);\n }\n /**\n * Get current pool statistics\n */\n getPoolStats() {\n const instances = Array.from(this.pool.values());\n const availableInstances = instances.filter((b) => b.isAvailable && b.isHealthy).length;\n const busyInstances = instances.filter((b) => !b.isAvailable).length;\n const unhealthyInstances = instances.filter((b) => !b.isHealthy).length;\n const totalUsage = instances.reduce((sum, b) => sum + b.usageCount, 0);\n const ages = instances.map((b) => Date.now() - b.createdAt.getTime());\n const averageAge = ages.length > 0 ? ages.reduce((sum, age) => sum + age, 0) / ages.length : 0;\n const oldestInstance = instances.length > 0\n ? instances.reduce((oldest, current) => current.createdAt < oldest.createdAt ? current : oldest).createdAt\n : null;\n const newestInstance = instances.length > 0\n ? instances.reduce((newest, current) => current.createdAt > newest.createdAt ? current : newest).createdAt\n : null;\n return {\n totalInstances: instances.length,\n availableInstances,\n busyInstances,\n unhealthyInstances,\n totalUsage,\n averageAge,\n oldestInstance,\n newestInstance,\n };\n }\n /**\n * Cleanup and shutdown the browser pool\n */\n async cleanup() {\n this.isShuttingDown = true;\n // Stop monitoring timers\n if (this.healthCheckTimer) {\n clearInterval(this.healthCheckTimer);\n this.healthCheckTimer = null;\n }\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n // Close all browsers\n const closePromises = Array.from(this.pool.values()).map(async (managedBrowser) => {\n try {\n await managedBrowser.browser.close();\n logger/* logger */.v.debug(`Closed browser ${managedBrowser.id}`);\n }\n catch (error) {\n logger/* logger */.v.warn(`Error closing browser ${managedBrowser.id}: ${error}`);\n }\n });\n await Promise.allSettled(closePromises);\n this.pool.clear();\n logger/* logger */.v.info('Browser pool cleanup completed');\n }\n /**\n * Create a new browser instance\n */\n async createBrowserInstance() {\n try {\n const launchOptions = {\n headless: this.config.browser.headlessDefault,\n slowMo: this.config.browser.slowmo,\n args: [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--no-first-run',\n '--no-zygote',\n '--disable-gpu',\n '--disable-background-timer-throttling',\n '--disable-backgrounding-occluded-windows',\n '--disable-renderer-backgrounding',\n ],\n };\n const browser = await external_puppeteer_default().launch(launchOptions);\n const context = await browser.createBrowserContext();\n const id = this.generateBrowserId();\n const managedBrowser = {\n browser,\n context,\n id,\n createdAt: new Date(),\n lastUsed: new Date(),\n isAvailable: true,\n isHealthy: true,\n usageCount: 0,\n };\n this.pool.set(id, managedBrowser);\n // Set up browser event handlers\n browser.on('disconnected', () => {\n logger/* logger */.v.warn(`Browser ${id} disconnected unexpectedly`);\n this.handleBrowserDisconnection(id);\n });\n return managedBrowser;\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to create browser instance: ${error}`);\n throw new errors/* BrowserLaunchError */.EE(`Failed to create browser instance: ${error}`, { poolSize: this.pool.size }, error);\n }\n }\n /**\n * Find an available healthy browser in the pool\n */\n findAvailableBrowser() {\n for (const browser of this.pool.values()) {\n if (browser.isAvailable && browser.isHealthy) {\n return browser;\n }\n }\n return null;\n }\n /**\n * Check if a browser should be retired\n */\n shouldRetireBrowser(browser) {\n const age = Date.now() - browser.createdAt.getTime();\n if (age > this.options.maxAge) {\n return 'max age exceeded';\n }\n if (browser.usageCount >= this.options.maxUsageCount) {\n return 'max usage count exceeded';\n }\n return null;\n }\n /**\n * Perform health check on a browser instance\n */\n async checkBrowserHealth(browser) {\n try {\n // Check if browser is connected\n if (!browser.browser.isConnected()) {\n return false;\n }\n // Try to create and close a test page\n const page = await browser.context.newPage();\n await page.close();\n return true;\n }\n catch (error) {\n logger/* logger */.v.debug(`Browser ${browser.id} health check failed: ${error}`);\n return false;\n }\n }\n /**\n * Remove a browser from the pool\n */\n async removeBrowserFromPool(browserId) {\n const browser = this.pool.get(browserId);\n if (!browser) {\n return;\n }\n try {\n await browser.browser.close();\n }\n catch (error) {\n logger/* logger */.v.warn(`Error closing browser ${browserId}: ${error}`);\n }\n this.pool.delete(browserId);\n logger/* logger */.v.debug(`Removed browser ${browserId} from pool`);\n }\n /**\n * Handle browser disconnection\n */\n async handleBrowserDisconnection(browserId) {\n const browser = this.pool.get(browserId);\n if (browser) {\n browser.isHealthy = false;\n browser.isAvailable = false;\n }\n // Remove the disconnected browser and ensure minimum instances\n await this.removeBrowserFromPool(browserId);\n await this.ensureMinimumInstances();\n }\n /**\n * Ensure minimum number of instances are available\n */\n async ensureMinimumInstances() {\n if (this.isShuttingDown) {\n return;\n }\n const healthyCount = Array.from(this.pool.values()).filter((b) => b.isHealthy).length;\n const needed = this.options.minInstances - healthyCount;\n if (needed > 0) {\n logger/* logger */.v.info(`Creating ${needed} browser instances to maintain minimum pool size`);\n const createPromises = Array.from({ length: needed }, () => this.createBrowserInstance().catch((error) => {\n logger/* logger */.v.error(`Failed to create browser for minimum instances: ${error}`);\n return null;\n }));\n await Promise.allSettled(createPromises);\n }\n }\n /**\n * Get count of available browsers\n */\n getAvailableCount() {\n return Array.from(this.pool.values()).filter((b) => b.isAvailable && b.isHealthy).length;\n }\n /**\n * Start health monitoring\n */\n startHealthMonitoring() {\n this.healthCheckTimer = setInterval(async () => {\n if (this.isShuttingDown) {\n return;\n }\n const unhealthyBrowsers = [];\n for (const [id, browser] of this.pool.entries()) {\n if (!browser.isAvailable) {\n continue; // Skip browsers currently in use\n }\n const isHealthy = await this.checkBrowserHealth(browser);\n if (!isHealthy) {\n unhealthyBrowsers.push(id);\n browser.isHealthy = false;\n }\n }\n // Remove unhealthy browsers\n for (const id of unhealthyBrowsers) {\n logger/* logger */.v.warn(`Removing unhealthy browser ${id} during health check`);\n await this.removeBrowserFromPool(id);\n }\n // Ensure minimum instances after cleanup\n if (unhealthyBrowsers.length > 0) {\n await this.ensureMinimumInstances();\n }\n }, this.options.healthCheckInterval);\n }\n /**\n * Start cleanup monitoring for idle browsers\n */\n startCleanupMonitoring() {\n this.cleanupTimer = setInterval(async () => {\n if (this.isShuttingDown) {\n return;\n }\n const now = Date.now();\n const browsersToRemove = [];\n for (const [id, browser] of this.pool.entries()) {\n if (!browser.isAvailable) {\n continue; // Skip browsers currently in use\n }\n const idleTime = now - browser.lastUsed.getTime();\n const shouldRetire = this.shouldRetireBrowser(browser);\n if (idleTime > this.options.idleTimeout || shouldRetire) {\n // Only remove if we have more than minimum instances\n const healthyCount = Array.from(this.pool.values()).filter((b) => b.isHealthy).length;\n if (healthyCount > this.options.minInstances) {\n browsersToRemove.push(id);\n }\n }\n }\n // Remove idle/old browsers\n for (const id of browsersToRemove) {\n const reason = this.shouldRetireBrowser(this.pool.get(id)) || 'idle timeout';\n logger/* logger */.v.info(`Removing browser ${id} due to ${reason}`);\n await this.removeBrowserFromPool(id);\n }\n }, this.options.healthCheckInterval);\n }\n /**\n * Generate unique browser ID\n */\n generateBrowserId() {\n return `browser_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n }\n}\n// Global browser pool instance\nlet globalBrowserPool = null;\nfunction getBrowserPool() {\n if (!globalBrowserPool) {\n globalBrowserPool = new BrowserPoolService();\n }\n return globalBrowserPool;\n}\nasync function cleanupBrowserPool() {\n if (globalBrowserPool) {\n await globalBrowserPool.cleanup();\n globalBrowserPool = null;\n }\n}\n\n;// ./src/core/browser/browser.manager.ts\n/**\n * Browser Manager for XHS Operations\n */\n\n\n\n\n\n\n\nclass BrowserManager {\n config;\n browser = null;\n browserPool = null;\n usePool = false;\n constructor(config, usePool = false) {\n this.config = config || (0,shared_config/* getConfig */.zj)();\n this.usePool = usePool;\n if (this.usePool) {\n this.browserPool = new BrowserPoolService(this.config);\n }\n }\n async createPage(headless, executablePath, shouldLoadCookies = true) {\n try {\n // Use browser pool if enabled\n if (this.usePool && this.browserPool) {\n return await this.createPageFromPool(shouldLoadCookies);\n }\n // Fallback to traditional browser management\n // Launch browser if not already launched\n if (!this.browser) {\n this.browser = await this.launchBrowser(headless, executablePath);\n }\n // Create new page\n const page = await this.browser.newPage();\n // Configure page timeouts\n page.setDefaultTimeout(this.config.browser.defaultTimeout);\n page.setDefaultNavigationTimeout(this.config.browser.navigationTimeout);\n // Load cookies if requested\n if (shouldLoadCookies) {\n await this.loadCookiesIntoPage(page);\n }\n return page;\n }\n catch (error) {\n logger/* logger */.v.error(`Browser page creation error: ${error}`);\n throw this.handlePuppeteerError(error, 'create_page');\n }\n }\n /**\n * Create a page using the browser pool\n */\n async createPageFromPool(shouldLoadCookies = true) {\n if (!this.browserPool) {\n throw new errors/* XHSError */.a_('Browser pool not initialized', 'BrowserPoolError');\n }\n const managedBrowser = await this.browserPool.acquireBrowser();\n try {\n // Create new page from the managed browser context\n const page = await managedBrowser.context.newPage();\n // Configure page timeouts\n page.setDefaultTimeout(this.config.browser.defaultTimeout);\n page.setDefaultNavigationTimeout(this.config.browser.navigationTimeout);\n // Load cookies if requested\n if (shouldLoadCookies) {\n await this.loadCookiesIntoPage(page);\n }\n // Store reference to managed browser for cleanup\n page._managedBrowser = managedBrowser;\n // Set up page close handler to release browser back to pool\n page.once('close', async () => {\n try {\n await this.browserPool.releaseBrowser(managedBrowser);\n }\n catch (error) {\n logger/* logger */.v.warn(`Error releasing browser back to pool: ${error}`);\n }\n });\n return page;\n }\n catch (error) {\n // Release browser back to pool on error\n try {\n await this.browserPool.releaseBrowser(managedBrowser);\n }\n catch (releaseError) {\n logger/* logger */.v.warn(`Error releasing browser after page creation failure: ${releaseError}`);\n }\n throw error;\n }\n }\n async launchBrowser(headless, executablePath) {\n const isHeadless = false; // temporarily disable headless mode for debugging\n try {\n const launchOptions = {\n headless: isHeadless,\n slowMo: this.config.browser.slowmo,\n args: [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--no-first-run',\n '--no-zygote',\n '--disable-gpu',\n ],\n };\n if (executablePath) {\n launchOptions.executablePath = executablePath;\n }\n const browser = await external_puppeteer_default().launch(launchOptions);\n return browser;\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to launch browser: ${error}`);\n throw new errors/* BrowserLaunchError */.EE(`Failed to launch browser: ${error}`, { headless: isHeadless, executablePath }, error);\n }\n }\n async loadCookiesIntoPage(page) {\n try {\n const cookies = (0,shared_cookies/* loadCookies */.O4)();\n if (!cookies) {\n return false;\n }\n // Convert our cookie format to Puppeteer format\n const puppeteerCookies = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain,\n path: cookie.path,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite,\n }));\n await page.setCookie(...puppeteerCookies);\n return true;\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to load cookies: ${error}`);\n return false;\n }\n }\n async saveCookiesFromPage(page) {\n try {\n const cookies = await page.cookies();\n // Convert Puppeteer cookie format to app format\n const appCookies = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain,\n path: cookie.path,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite,\n }));\n (0,shared_cookies/* saveCookies */.XM)(appCookies);\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to save cookies: ${error}`);\n throw this.handlePuppeteerError(error, 'save_cookies');\n }\n }\n async navigateWithRetry(page, url, waitUntil = 'load', maxRetries) {\n const retries = maxRetries || this.config.xhs.maxRetries;\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n await page.goto(url, {\n waitUntil,\n timeout: this.config.browser.navigationTimeout,\n });\n return;\n }\n catch (error) {\n if (error instanceof Error && error.name === 'TimeoutError') {\n if (attempt === retries) {\n throw new errors/* BrowserNavigationError */.Jk(`Failed to navigate to ${url} after ${retries + 1} attempts`, { url, attempts: attempt + 1 }, error);\n }\n await (0,utils/* sleep */.yy)(this.config.xhs.retryDelay * 1000);\n }\n else {\n throw error;\n }\n }\n }\n }\n async tryWaitForSelector(page, selector, timeout, visible = true) {\n try {\n await page.waitForSelector(selector, {\n timeout: timeout || this.config.browser.defaultTimeout,\n visible,\n });\n return true;\n }\n catch (error) {\n if (error instanceof Error && error.name === 'TimeoutError') {\n return false;\n }\n throw error;\n }\n }\n async waitForSelectorVisible(page, selector, timeout) {\n return this.tryWaitForSelector(page, selector, timeout, true);\n }\n async waitForSelectorHidden(page, selector, timeout) {\n return this.tryWaitForSelector(page, selector, timeout, false);\n }\n async cleanup() {\n // Cleanup browser pool if using it\n if (this.usePool && this.browserPool) {\n try {\n await this.browserPool.cleanup();\n }\n catch (error) {\n logger/* logger */.v.warn(`Error cleaning up browser pool: ${error}`);\n }\n finally {\n this.browserPool = null;\n }\n }\n // Cleanup traditional browser instance\n if (this.browser) {\n try {\n await this.browser.close();\n }\n catch (error) {\n logger/* logger */.v.warn(`Error closing browser: ${error}`);\n }\n finally {\n this.browser = null;\n }\n }\n }\n /**\n * Get browser pool statistics (if using pool)\n */\n getBrowserPoolStats() {\n if (this.usePool && this.browserPool) {\n return this.browserPool.getPoolStats();\n }\n return null;\n }\n /**\n * Enable browser pooling\n */\n enableBrowserPool() {\n if (!this.usePool) {\n this.usePool = true;\n this.browserPool = new BrowserPoolService(this.config);\n }\n }\n /**\n * Disable browser pooling\n */\n async disableBrowserPool() {\n if (this.usePool && this.browserPool) {\n await this.browserPool.cleanup();\n this.browserPool = null;\n this.usePool = false;\n }\n }\n handlePuppeteerError(error, operationName) {\n const context = { operationName };\n if (error.name === 'TimeoutError') {\n if (operationName.toLowerCase().includes('login')) {\n return new errors/* XHSError */.a_(`Login operation timed out during ${operationName}`, 'LoginTimeoutError', context, error);\n }\n else {\n return new errors/* XHSError */.a_(`Browser operation timed out: ${operationName}`, 'BrowserError', context, error);\n }\n }\n else {\n if (error.message.toLowerCase().includes('navigation')) {\n return new errors/* BrowserNavigationError */.Jk(`Navigation failed during ${operationName}: ${error.message}`, context, error);\n }\n else {\n return new errors/* XHSError */.a_(`Browser error during ${operationName}: ${error.message}`, 'BrowserError', context, error);\n }\n }\n }\n}\n// Global browser manager instance\nlet globalBrowserManager = null;\nfunction getBrowserManager(usePool = false) {\n if (!globalBrowserManager) {\n globalBrowserManager = new BrowserManager(undefined, usePool);\n }\n return globalBrowserManager;\n}\nfunction getPooledBrowserManager() {\n return getBrowserManager(true);\n}\nasync function cleanupGlobalBrowserManager() {\n if (globalBrowserManager) {\n await globalBrowserManager.cleanup();\n globalBrowserManager = null;\n }\n}\n\n;// ./src/shared/base.service.ts\n/**\n * Base service class for XHS MCP Server services\n */\n\n/**\n * Base service class that provides common functionality for all services\n */\nclass BaseService {\n config;\n browserManager;\n constructor(config) {\n this.config = config;\n this.browserManager = new BrowserManager(config);\n }\n /**\n * Get the browser manager instance\n */\n getBrowserManager() {\n return this.browserManager;\n }\n /**\n * Get the configuration\n */\n getConfig() {\n return this.config;\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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SUFBSSxvQkFBb0IsR0FBMEIsSUFBSSxDQUFDO0FBRWhELFNBQVMsaUJBQWlCLENBQUMsVUFBbUIsS0FBSztJQUN4RCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUMxQixvQkFBb0IsR0FBRyxJQUFJLGNBQWMsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUNELE9BQU8sb0JBQW9CLENBQUM7QUFDOUIsQ0FBQztBQUVNLFNBQVMsdUJBQXVCO0lBQ3JDLE9BQU8saUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVNLEtBQUssVUFBVSwyQkFBMkI7SUFDL0MsSUFBSSxvQkFBb0IsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sb0JBQW9CLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDckMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO0lBQzlCLENBQUM7QUFDSCxDQUFDOzs7QUNsWEQ7O0dBRUc7QUFHOEQ7QUFFakU7O0dBRUc7QUFDSSxNQUFlLFdBQVc7SUFDWixNQUFNLENBQVM7SUFDZixjQUFjLENBQWlCO0lBRWxELFlBQVksTUFBYztRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7T0FFRztJQUNPLGlCQUFpQjtRQUN6QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQUVEOztPQUVHO0lBQ08sU0FBUztRQUNqQixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQztDQUNGIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL2Jyb3dzZXIvYnJvd3Nlci1wb29sLnNlcnZpY2UudHM/NGM1NCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvYnJvd3Nlci9icm93c2VyLm1hbmFnZXIudHM/NGMwZiIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NoYXJlZC9iYXNlLnNlcnZpY2UudHM/YTM0ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEJyb3dzZXIgUG9vbCBTZXJ2aWNlIGZvciBYSFMgT3BlcmF0aW9uc1xuICogTWFuYWdlcyBicm93c2VyIGluc3RhbmNlIGxpZmVjeWNsZSB3aXRoIHBvb2xpbmcsIGhlYWx0aCBtb25pdG9yaW5nLCBhbmQgYXV0b21hdGljIGNsZWFudXBcbiAqL1xuXG5pbXBvcnQgcHVwcGV0ZWVyLCB7IEJyb3dzZXIsIEJyb3dzZXJDb250ZXh0LCBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBCcm93c2VyTGF1bmNoRXJyb3IsIFhIU0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1hbmFnZWRCcm93c2VyIHtcbiAgYnJvd3NlcjogQnJvd3NlcjtcbiAgY29udGV4dDogQnJvd3NlckNvbnRleHQ7XG4gIGlkOiBzdHJpbmc7XG4gIGNyZWF0ZWRBdDogRGF0ZTtcbiAgbGFzdFVzZWQ6IERhdGU7XG4gIGlzQXZhaWxhYmxlOiBib29sZWFuO1xuICBpc0hlYWx0aHk6IGJvb2xlYW47XG4gIHVzYWdlQ291bnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCcm93c2VyUG9vbFN0YXRzIHtcbiAgdG90YWxJbnN0YW5jZXM6IG51bWJlcjtcbiAgYXZhaWxhYmxlSW5zdGFuY2VzOiBudW1iZXI7XG4gIGJ1c3lJbnN0YW5jZXM6IG51bWJlcjtcbiAgdW5oZWFsdGh5SW5zdGFuY2VzOiBudW1iZXI7XG4gIHRvdGFsVXNhZ2U6IG51bWJlcjtcbiAgYXZlcmFnZUFnZTogbnVtYmVyO1xuICBvbGRlc3RJbnN0YW5jZTogRGF0ZSB8IG51bGw7XG4gIG5ld2VzdEluc3RhbmNlOiBEYXRlIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCcm93c2VyUG9vbE9wdGlvbnMge1xuICBtaW5JbnN0YW5jZXM/OiBudW1iZXI7XG4gIG1heEluc3RhbmNlcz86IG51bWJlcjtcbiAgaWRsZVRpbWVvdXQ/OiBudW1iZXI7XG4gIG1heEFnZT86IG51bWJlcjtcbiAgaGVhbHRoQ2hlY2tJbnRlcnZhbD86IG51bWJlcjtcbiAgbWF4VXNhZ2VDb3VudD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNsYXNzIEJyb3dzZXJQb29sU2VydmljZSB7XG4gIHByaXZhdGUgY29uZmlnOiBDb25maWc7XG4gIHByaXZhdGUgcG9vbDogTWFwPHN0cmluZywgTWFuYWdlZEJyb3dzZXI+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIG9wdGlvbnM6IFJlcXVpcmVkPEJyb3dzZXJQb29sT3B0aW9ucz47XG4gIHByaXZhdGUgaGVhbHRoQ2hlY2tUaW1lcjogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjbGVhbnVwVGltZXI6IE5vZGVKUy5UaW1lb3V0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaXNTaHV0dGluZ0Rvd24gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc/OiBDb25maWcsIG9wdGlvbnM/OiBCcm93c2VyUG9vbE9wdGlvbnMpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCBnZXRDb25maWcoKTtcblxuICAgIC8vIFNldCBkZWZhdWx0IG9wdGlvbnMgd2l0aCBjb25maWd1cmF0aW9uIGZyb20gZW52aXJvbm1lbnQgb3IgZGVmYXVsdHNcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBtaW5JbnN0YW5jZXM6IG9wdGlvbnM/Lm1pbkluc3RhbmNlcyA/PyAyLFxuICAgICAgbWF4SW5zdGFuY2VzOiBvcHRpb25zPy5tYXhJbnN0YW5jZXMgPz8gNSxcbiAgICAgIGlkbGVUaW1lb3V0OiBvcHRpb25zPy5pZGxlVGltZW91dCA/PyAzMDAwMDAsIC8vIDUgbWludXRlc1xuICAgICAgbWF4QWdlOiBvcHRpb25zPy5tYXhBZ2UgPz8gMTgwMDAwMCwgLy8gMzAgbWludXRlc1xuICAgICAgaGVhbHRoQ2hlY2tJbnRlcnZhbDogb3B0aW9ucz8uaGVhbHRoQ2hlY2tJbnRlcnZhbCA/PyA2MDAwMCwgLy8gMSBtaW51dGVcbiAgICAgIG1heFVzYWdlQ291bnQ6IG9wdGlvbnM/Lm1heFVzYWdlQ291bnQgPz8gMTAwLFxuICAgIH07XG5cbiAgICB0aGlzLnN0YXJ0SGVhbHRoTW9uaXRvcmluZygpO1xuICAgIHRoaXMuc3RhcnRDbGVhbnVwTW9uaXRvcmluZygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjcXVpcmUgYSBicm93c2VyIGluc3RhbmNlIGZyb20gdGhlIHBvb2xcbiAgICovXG4gIGFzeW5jIGFjcXVpcmVCcm93c2VyKG9wdGlvbnM/OiB7IHRpbWVvdXQ/OiBudW1iZXIgfSk6IFByb21pc2U8TWFuYWdlZEJyb3dzZXI+IHtcbiAgICBpZiAodGhpcy5pc1NodXR0aW5nRG93bikge1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKCdCcm93c2VyIHBvb2wgaXMgc2h1dHRpbmcgZG93bicsICdCcm93c2VyUG9vbEVycm9yJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdGltZW91dCA9IG9wdGlvbnM/LnRpbWVvdXQgPz8gMzAwMDA7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIC0gc3RhcnRUaW1lIDwgdGltZW91dCkge1xuICAgICAgLy8gVHJ5IHRvIGZpbmQgYW4gYXZhaWxhYmxlIGhlYWx0aHkgYnJvd3NlclxuICAgICAgY29uc3QgYXZhaWxhYmxlQnJvd3NlciA9IHRoaXMuZmluZEF2YWlsYWJsZUJyb3dzZXIoKTtcbiAgICAgIGlmIChhdmFpbGFibGVCcm93c2VyKSB7XG4gICAgICAgIGF2YWlsYWJsZUJyb3dzZXIuaXNBdmFpbGFibGUgPSBmYWxzZTtcbiAgICAgICAgYXZhaWxhYmxlQnJvd3Nlci5sYXN0VXNlZCA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGF2YWlsYWJsZUJyb3dzZXIudXNhZ2VDb3VudCsrO1xuXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgQWNxdWlyZWQgYnJvd3NlciAke2F2YWlsYWJsZUJyb3dzZXIuaWR9IGZyb20gcG9vbGApO1xuICAgICAgICByZXR1cm4gYXZhaWxhYmxlQnJvd3NlcjtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgbm8gYXZhaWxhYmxlIGJyb3dzZXIgYW5kIHdlIGNhbiBjcmVhdGUgbW9yZSwgY3JlYXRlIG9uZVxuICAgICAgaWYgKHRoaXMucG9vbC5zaXplIDwgdGhpcy5vcHRpb25zLm1heEluc3RhbmNlcykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG5ld0Jyb3dzZXIgPSBhd2FpdCB0aGlzLmNyZWF0ZUJyb3dzZXJJbnN0YW5jZSgpO1xuICAgICAgICAgIG5ld0Jyb3dzZXIuaXNBdmFpbGFibGUgPSBmYWxzZTtcbiAgICAgICAgICBuZXdCcm93c2VyLmxhc3RVc2VkID0gbmV3IERhdGUoKTtcbiAgICAgICAgICBuZXdCcm93c2VyLnVzYWdlQ291bnQrKztcblxuICAgICAgICAgIGxvZ2dlci5pbmZvKGBDcmVhdGVkIG5ldyBicm93c2VyICR7bmV3QnJvd3Nlci5pZH0gZm9yIHBvb2xgKTtcbiAgICAgICAgICByZXR1cm4gbmV3QnJvd3NlcjtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgbmV3IGJyb3dzZXIgaW5zdGFuY2U6ICR7ZXJyb3J9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gV2FpdCBhIGJpdCBiZWZvcmUgcmV0cnlpbmdcbiAgICAgIGF3YWl0IHNsZWVwKDEwMCk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFhIU0Vycm9yKFxuICAgICAgYEZhaWxlZCB0byBhY3F1aXJlIGJyb3dzZXIgd2l0aGluICR7dGltZW91dH1tcyB0aW1lb3V0YCxcbiAgICAgICdCcm93c2VyUG9vbFRpbWVvdXQnLFxuICAgICAgeyB0aW1lb3V0LCBwb29sU2l6ZTogdGhpcy5wb29sLnNpemUsIGF2YWlsYWJsZUNvdW50OiB0aGlzLmdldEF2YWlsYWJsZUNvdW50KCkgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVsZWFzZSBhIGJyb3dzZXIgaW5zdGFuY2UgYmFjayB0byB0aGUgcG9vbFxuICAgKi9cbiAgYXN5bmMgcmVsZWFzZUJyb3dzZXIoYnJvd3NlcjogTWFuYWdlZEJyb3dzZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtYW5hZ2VkQnJvd3NlciA9IHRoaXMucG9vbC5nZXQoYnJvd3Nlci5pZCk7XG4gICAgaWYgKCFtYW5hZ2VkQnJvd3Nlcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEF0dGVtcHRlZCB0byByZWxlYXNlIHVua25vd24gYnJvd3NlciAke2Jyb3dzZXIuaWR9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYnJvd3NlciBzaG91bGQgYmUgcmV0aXJlZCBkdWUgdG8gYWdlIG9yIHVzYWdlXG4gICAgY29uc3Qgc2hvdWxkUmV0aXJlID0gdGhpcy5zaG91bGRSZXRpcmVCcm93c2VyKG1hbmFnZWRCcm93c2VyKTtcbiAgICBpZiAoc2hvdWxkUmV0aXJlKSB7XG4gICAgICBsb2dnZXIuaW5mbyhgUmV0aXJpbmcgYnJvd3NlciAke2Jyb3dzZXIuaWR9IGR1ZSB0byAke3Nob3VsZFJldGlyZX1gKTtcbiAgICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGJyb3dzZXIuaWQpO1xuXG4gICAgICAvLyBFbnN1cmUgd2UgbWFpbnRhaW4gbWluaW11bSBpbnN0YW5jZXNcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlTWluaW11bUluc3RhbmNlcygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFBlcmZvcm0gaGVhbHRoIGNoZWNrIGJlZm9yZSByZXR1cm5pbmcgdG8gcG9vbFxuICAgIGNvbnN0IGlzSGVhbHRoeSA9IGF3YWl0IHRoaXMuY2hlY2tCcm93c2VySGVhbHRoKG1hbmFnZWRCcm93c2VyKTtcbiAgICBpZiAoIWlzSGVhbHRoeSkge1xuICAgICAgbG9nZ2VyLndhcm4oYEJyb3dzZXIgJHticm93c2VyLmlkfSBmYWlsZWQgaGVhbHRoIGNoZWNrLCByZW1vdmluZyBmcm9tIHBvb2xgKTtcbiAgICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGJyb3dzZXIuaWQpO1xuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVNaW5pbXVtSW5zdGFuY2VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIHRvIHBvb2xcbiAgICBtYW5hZ2VkQnJvd3Nlci5pc0F2YWlsYWJsZSA9IHRydWU7XG4gICAgbWFuYWdlZEJyb3dzZXIuaXNIZWFsdGh5ID0gdHJ1ZTtcblxuICAgIGxvZ2dlci5kZWJ1ZyhgUmVsZWFzZWQgYnJvd3NlciAke2Jyb3dzZXIuaWR9IGJhY2sgdG8gcG9vbGApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHBvb2wgc3RhdGlzdGljc1xuICAgKi9cbiAgZ2V0UG9vbFN0YXRzKCk6IEJyb3dzZXJQb29sU3RhdHMge1xuICAgIGNvbnN0IGluc3RhbmNlcyA9IEFycmF5LmZyb20odGhpcy5wb29sLnZhbHVlcygpKTtcbiAgICBjb25zdCBhdmFpbGFibGVJbnN0YW5jZXMgPSBpbnN0YW5jZXMuZmlsdGVyKChiKSA9PiBiLmlzQXZhaWxhYmxlICYmIGIuaXNIZWFsdGh5KS5sZW5ndGg7XG4gICAgY29uc3QgYnVzeUluc3RhbmNlcyA9IGluc3RhbmNlcy5maWx0ZXIoKGIpID0+ICFiLmlzQXZhaWxhYmxlKS5sZW5ndGg7XG4gICAgY29uc3QgdW5oZWFsdGh5SW5zdGFuY2VzID0gaW5zdGFuY2VzLmZpbHRlcigoYikgPT4gIWIuaXNIZWFsdGh5KS5sZW5ndGg7XG4gICAgY29uc3QgdG90YWxVc2FnZSA9IGluc3RhbmNlcy5yZWR1Y2UoKHN1bSwgYikgPT4gc3VtICsgYi51c2FnZUNvdW50LCAwKTtcblxuICAgIGNvbnN0IGFnZXMgPSBpbnN0YW5jZXMubWFwKChiKSA9PiBEYXRlLm5vdygpIC0gYi5jcmVhdGVkQXQuZ2V0VGltZSgpKTtcbiAgICBjb25zdCBhdmVyYWdlQWdlID0gYWdlcy5sZW5ndGggPiAwID8gYWdlcy5yZWR1Y2UoKHN1bSwgYWdlKSA9PiBzdW0gKyBhZ2UsIDApIC8gYWdlcy5sZW5ndGggOiAwO1xuXG4gICAgY29uc3Qgb2xkZXN0SW5zdGFuY2UgPVxuICAgICAgaW5zdGFuY2VzLmxlbmd0aCA+IDBcbiAgICAgICAgPyBpbnN0YW5jZXMucmVkdWNlKChvbGRlc3QsIGN1cnJlbnQpID0+XG4gICAgICAgICAgICBjdXJyZW50LmNyZWF0ZWRBdCA8IG9sZGVzdC5jcmVhdGVkQXQgPyBjdXJyZW50IDogb2xkZXN0XG4gICAgICAgICAgKS5jcmVhdGVkQXRcbiAgICAgICAgOiBudWxsO1xuXG4gICAgY29uc3QgbmV3ZXN0SW5zdGFuY2UgPVxuICAgICAgaW5zdGFuY2VzLmxlbmd0aCA+IDBcbiAgICAgICAgPyBpbnN0YW5jZXMucmVkdWNlKChuZXdlc3QsIGN1cnJlbnQpID0+XG4gICAgICAgICAgICBjdXJyZW50LmNyZWF0ZWRBdCA+IG5ld2VzdC5jcmVhdGVkQXQgPyBjdXJyZW50IDogbmV3ZXN0XG4gICAgICAgICAgKS5jcmVhdGVkQXRcbiAgICAgICAgOiBudWxsO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsSW5zdGFuY2VzOiBpbnN0YW5jZXMubGVuZ3RoLFxuICAgICAgYXZhaWxhYmxlSW5zdGFuY2VzLFxuICAgICAgYnVzeUluc3RhbmNlcyxcbiAgICAgIHVuaGVhbHRoeUluc3RhbmNlcyxcbiAgICAgIHRvdGFsVXNhZ2UsXG4gICAgICBhdmVyYWdlQWdlLFxuICAgICAgb2xkZXN0SW5zdGFuY2UsXG4gICAgICBuZXdlc3RJbnN0YW5jZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFudXAgYW5kIHNodXRkb3duIHRoZSBicm93c2VyIHBvb2xcbiAgICovXG4gIGFzeW5jIGNsZWFudXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5pc1NodXR0aW5nRG93biA9IHRydWU7XG5cbiAgICAvLyBTdG9wIG1vbml0b3JpbmcgdGltZXJzXG4gICAgaWYgKHRoaXMuaGVhbHRoQ2hlY2tUaW1lcikge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmhlYWx0aENoZWNrVGltZXIpO1xuICAgICAgdGhpcy5oZWFsdGhDaGVja1RpbWVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jbGVhbnVwVGltZXIpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhbnVwVGltZXIpO1xuICAgICAgdGhpcy5jbGVhbnVwVGltZXIgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIENsb3NlIGFsbCBicm93c2Vyc1xuICAgIGNvbnN0IGNsb3NlUHJvbWlzZXMgPSBBcnJheS5mcm9tKHRoaXMucG9vbC52YWx1ZXMoKSkubWFwKGFzeW5jIChtYW5hZ2VkQnJvd3NlcikgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgbWFuYWdlZEJyb3dzZXIuYnJvd3Nlci5jbG9zZSgpO1xuICAgICAgICBsb2dnZXIuZGVidWcoYENsb3NlZCBicm93c2VyICR7bWFuYWdlZEJyb3dzZXIuaWR9YCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihgRXJyb3IgY2xvc2luZyBicm93c2VyICR7bWFuYWdlZEJyb3dzZXIuaWR9OiAke2Vycm9yfWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGNsb3NlUHJvbWlzZXMpO1xuICAgIHRoaXMucG9vbC5jbGVhcigpO1xuXG4gICAgbG9nZ2VyLmluZm8oJ0Jyb3dzZXIgcG9vbCBjbGVhbnVwIGNvbXBsZXRlZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBicm93c2VyIGluc3RhbmNlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNyZWF0ZUJyb3dzZXJJbnN0YW5jZSgpOiBQcm9taXNlPE1hbmFnZWRCcm93c2VyPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGxhdW5jaE9wdGlvbnM6IGFueSA9IHtcbiAgICAgICAgaGVhZGxlc3M6IHRoaXMuY29uZmlnLmJyb3dzZXIuaGVhZGxlc3NEZWZhdWx0LFxuICAgICAgICBzbG93TW86IHRoaXMuY29uZmlnLmJyb3dzZXIuc2xvd21vLFxuICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgJy0tbm8tc2FuZGJveCcsXG4gICAgICAgICAgJy0tZGlzYWJsZS1zZXR1aWQtc2FuZGJveCcsXG4gICAgICAgICAgJy0tZGlzYWJsZS1kZXYtc2htLXVzYWdlJyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWFjY2VsZXJhdGVkLTJkLWNhbnZhcycsXG4gICAgICAgICAgJy0tbm8tZmlyc3QtcnVuJyxcbiAgICAgICAgICAnLS1uby16eWdvdGUnLFxuICAgICAgICAgICctLWRpc2FibGUtZ3B1JyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWJhY2tncm91bmQtdGltZXItdGhyb3R0bGluZycsXG4gICAgICAgICAgJy0tZGlzYWJsZS1iYWNrZ3JvdW5kaW5nLW9jY2x1ZGVkLXdpbmRvd3MnLFxuICAgICAgICAgICctLWRpc2FibGUtcmVuZGVyZXItYmFja2dyb3VuZGluZycsXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaChsYXVuY2hPcHRpb25zKTtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBhd2FpdCBicm93c2VyLmNyZWF0ZUJyb3dzZXJDb250ZXh0KCk7XG5cbiAgICAgIGNvbnN0IGlkID0gdGhpcy5nZW5lcmF0ZUJyb3dzZXJJZCgpO1xuICAgICAgY29uc3QgbWFuYWdlZEJyb3dzZXI6IE1hbmFnZWRCcm93c2VyID0ge1xuICAgICAgICBicm93c2VyLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICBpZCxcbiAgICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICBsYXN0VXNlZDogbmV3IERhdGUoKSxcbiAgICAgICAgaXNBdmFpbGFibGU6IHRydWUsXG4gICAgICAgIGlzSGVhbHRoeTogdHJ1ZSxcbiAgICAgICAgdXNhZ2VDb3VudDogMCxcbiAgICAgIH07XG5cbiAgICAgIHRoaXMucG9vbC5zZXQoaWQsIG1hbmFnZWRCcm93c2VyKTtcblxuICAgICAgLy8gU2V0IHVwIGJyb3dzZXIgZXZlbnQgaGFuZGxlcnNcbiAgICAgIGJyb3dzZXIub24oJ2Rpc2Nvbm5lY3RlZCcsICgpID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEJyb3dzZXIgJHtpZH0gZGlzY29ubmVjdGVkIHVuZXhwZWN0ZWRseWApO1xuICAgICAgICB0aGlzLmhhbmRsZUJyb3dzZXJEaXNjb25uZWN0aW9uKGlkKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbWFuYWdlZEJyb3dzZXI7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBicm93c2VyIGluc3RhbmNlOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IEJyb3dzZXJMYXVuY2hFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBjcmVhdGUgYnJvd3NlciBpbnN0YW5jZTogJHtlcnJvcn1gLFxuICAgICAgICB7IHBvb2xTaXplOiB0aGlzLnBvb2wuc2l6ZSB9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhbiBhdmFpbGFibGUgaGVhbHRoeSBicm93c2VyIGluIHRoZSBwb29sXG4gICAqL1xuICBwcml2YXRlIGZpbmRBdmFpbGFibGVCcm93c2VyKCk6IE1hbmFnZWRCcm93c2VyIHwgbnVsbCB7XG4gICAgZm9yIChjb25zdCBicm93c2VyIG9mIHRoaXMucG9vbC52YWx1ZXMoKSkge1xuICAgICAgaWYgKGJyb3dzZXIuaXNBdmFpbGFibGUgJiYgYnJvd3Nlci5pc0hlYWx0aHkpIHtcbiAgICAgICAgcmV0dXJuIGJyb3dzZXI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgYnJvd3NlciBzaG91bGQgYmUgcmV0aXJlZFxuICAgKi9cbiAgcHJpdmF0ZSBzaG91bGRSZXRpcmVCcm93c2VyKGJyb3dzZXI6IE1hbmFnZWRCcm93c2VyKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3QgYWdlID0gRGF0ZS5ub3coKSAtIGJyb3dzZXIuY3JlYXRlZEF0LmdldFRpbWUoKTtcblxuICAgIGlmIChhZ2UgPiB0aGlzLm9wdGlvbnMubWF4QWdlKSB7XG4gICAgICByZXR1cm4gJ21heCBhZ2UgZXhjZWVkZWQnO1xuICAgIH1cblxuICAgIGlmIChicm93c2VyLnVzYWdlQ291bnQgPj0gdGhpcy5vcHRpb25zLm1heFVzYWdlQ291bnQpIHtcbiAgICAgIHJldHVybiAnbWF4IHVzYWdlIGNvdW50IGV4Y2VlZGVkJztcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGhlYWx0aCBjaGVjayBvbiBhIGJyb3dzZXIgaW5zdGFuY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY2hlY2tCcm93c2VySGVhbHRoKGJyb3dzZXI6IE1hbmFnZWRCcm93c2VyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENoZWNrIGlmIGJyb3dzZXIgaXMgY29ubmVjdGVkXG4gICAgICBpZiAoIWJyb3dzZXIuYnJvd3Nlci5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gVHJ5IHRvIGNyZWF0ZSBhbmQgY2xvc2UgYSB0ZXN0IHBhZ2VcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBicm93c2VyLmNvbnRleHQubmV3UGFnZSgpO1xuICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmRlYnVnKGBCcm93c2VyICR7YnJvd3Nlci5pZH0gaGVhbHRoIGNoZWNrIGZhaWxlZDogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEgYnJvd3NlciBmcm9tIHRoZSBwb29sXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlbW92ZUJyb3dzZXJGcm9tUG9vbChicm93c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJyb3dzZXIgPSB0aGlzLnBvb2wuZ2V0KGJyb3dzZXJJZCk7XG4gICAgaWYgKCFicm93c2VyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGJyb3dzZXIuYnJvd3Nlci5jbG9zZSgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRXJyb3IgY2xvc2luZyBicm93c2VyICR7YnJvd3NlcklkfTogJHtlcnJvcn1gKTtcbiAgICB9XG5cbiAgICB0aGlzLnBvb2wuZGVsZXRlKGJyb3dzZXJJZCk7XG4gICAgbG9nZ2VyLmRlYnVnKGBSZW1vdmVkIGJyb3dzZXIgJHticm93c2VySWR9IGZyb20gcG9vbGApO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBicm93c2VyIGRpc2Nvbm5lY3Rpb25cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlQnJvd3NlckRpc2Nvbm5lY3Rpb24oYnJvd3NlcklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBicm93c2VyID0gdGhpcy5wb29sLmdldChicm93c2VySWQpO1xuICAgIGlmIChicm93c2VyKSB7XG4gICAgICBicm93c2VyLmlzSGVhbHRoeSA9IGZhbHNlO1xuICAgICAgYnJvd3Nlci5pc0F2YWlsYWJsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSB0aGUgZGlzY29ubmVjdGVkIGJyb3dzZXIgYW5kIGVuc3VyZSBtaW5pbXVtIGluc3RhbmNlc1xuICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGJyb3dzZXJJZCk7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVNaW5pbXVtSW5zdGFuY2VzKCk7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlIG1pbmltdW0gbnVtYmVyIG9mIGluc3RhbmNlcyBhcmUgYXZhaWxhYmxlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNTaHV0dGluZ0Rvd24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoZWFsdGh5Q291bnQgPSBBcnJheS5mcm9tKHRoaXMucG9vbC52YWx1ZXMoKSkuZmlsdGVyKChiKSA9PiBiLmlzSGVhbHRoeSkubGVuZ3RoO1xuXG4gICAgY29uc3QgbmVlZGVkID0gdGhpcy5vcHRpb25zLm1pbkluc3RhbmNlcyAtIGhlYWx0aHlDb3VudDtcblxuICAgIGlmIChuZWVkZWQgPiAwKSB7XG4gICAgICBsb2dnZXIuaW5mbyhgQ3JlYXRpbmcgJHtuZWVkZWR9IGJyb3dzZXIgaW5zdGFuY2VzIHRvIG1haW50YWluIG1pbmltdW0gcG9vbCBzaXplYCk7XG5cbiAgICAgIGNvbnN0IGNyZWF0ZVByb21pc2VzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogbmVlZGVkIH0sICgpID0+XG4gICAgICAgIHRoaXMuY3JlYXRlQnJvd3Nlckluc3RhbmNlKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGJyb3dzZXIgZm9yIG1pbmltdW0gaW5zdGFuY2VzOiAke2Vycm9yfWApO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGNyZWF0ZVByb21pc2VzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNvdW50IG9mIGF2YWlsYWJsZSBicm93c2Vyc1xuICAgKi9cbiAgcHJpdmF0ZSBnZXRBdmFpbGFibGVDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMucG9vbC52YWx1ZXMoKSkuZmlsdGVyKChiKSA9PiBiLmlzQXZhaWxhYmxlICYmIGIuaXNIZWFsdGh5KS5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgaGVhbHRoIG1vbml0b3JpbmdcbiAgICovXG4gIHByaXZhdGUgc3RhcnRIZWFsdGhNb25pdG9yaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuaGVhbHRoQ2hlY2tUaW1lciA9IHNldEludGVydmFsKGFzeW5jICgpID0+IHtcbiAgICAgIGlmICh0aGlzLmlzU2h1dHRpbmdEb3duKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdW5oZWFsdGh5QnJvd3NlcnM6IHN0cmluZ1tdID0gW107XG5cbiAgICAgIGZvciAoY29uc3QgW2lkLCBicm93c2VyXSBvZiB0aGlzLnBvb2wuZW50cmllcygpKSB7XG4gICAgICAgIGlmICghYnJvd3Nlci5pc0F2YWlsYWJsZSkge1xuICAgICAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIGJyb3dzZXJzIGN1cnJlbnRseSBpbiB1c2VcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlzSGVhbHRoeSA9IGF3YWl0IHRoaXMuY2hlY2tCcm93c2VySGVhbHRoKGJyb3dzZXIpO1xuICAgICAgICBpZiAoIWlzSGVhbHRoeSkge1xuICAgICAgICAgIHVuaGVhbHRoeUJyb3dzZXJzLnB1c2goaWQpO1xuICAgICAgICAgIGJyb3dzZXIuaXNIZWFsdGh5ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gUmVtb3ZlIHVuaGVhbHRoeSBicm93c2Vyc1xuICAgICAgZm9yIChjb25zdCBpZCBvZiB1bmhlYWx0aHlCcm93c2Vycykge1xuICAgICAgICBsb2dnZXIud2FybihgUmVtb3ZpbmcgdW5oZWFsdGh5IGJyb3dzZXIgJHtpZH0gZHVyaW5nIGhlYWx0aCBjaGVja2ApO1xuICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUJyb3dzZXJGcm9tUG9vbChpZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEVuc3VyZSBtaW5pbXVtIGluc3RhbmNlcyBhZnRlciBjbGVhbnVwXG4gICAgICBpZiAodW5oZWFsdGh5QnJvd3NlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTtcbiAgICAgIH1cbiAgICB9LCB0aGlzLm9wdGlvbnMuaGVhbHRoQ2hlY2tJbnRlcnZhbCk7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgY2xlYW51cCBtb25pdG9yaW5nIGZvciBpZGxlIGJyb3dzZXJzXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0Q2xlYW51cE1vbml0b3JpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhbnVwVGltZXIgPSBzZXRJbnRlcnZhbChhc3luYyAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5pc1NodXR0aW5nRG93bikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBjb25zdCBicm93c2Vyc1RvUmVtb3ZlOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IFtpZCwgYnJvd3Nlcl0gb2YgdGhpcy5wb29sLmVudHJpZXMoKSkge1xuICAgICAgICBpZiAoIWJyb3dzZXIuaXNBdmFpbGFibGUpIHtcbiAgICAgICAgICBjb250aW51ZTsgLy8gU2tpcCBicm93c2VycyBjdXJyZW50bHkgaW4gdXNlXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpZGxlVGltZSA9IG5vdyAtIGJyb3dzZXIubGFzdFVzZWQuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCBzaG91bGRSZXRpcmUgPSB0aGlzLnNob3VsZFJldGlyZUJyb3dzZXIoYnJvd3Nlcik7XG5cbiAgICAgICAgaWYgKGlkbGVUaW1lID4gdGhpcy5vcHRpb25zLmlkbGVUaW1lb3V0IHx8IHNob3VsZFJldGlyZSkge1xuICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGlmIHdlIGhhdmUgbW9yZSB0aGFuIG1pbmltdW0gaW5zdGFuY2VzXG4gICAgICAgICAgY29uc3QgaGVhbHRoeUNvdW50ID0gQXJyYXkuZnJvbSh0aGlzLnBvb2wudmFsdWVzKCkpLmZpbHRlcigoYikgPT4gYi5pc0hlYWx0aHkpLmxlbmd0aDtcblxuICAgICAgICAgIGlmIChoZWFsdGh5Q291bnQgPiB0aGlzLm9wdGlvbnMubWluSW5zdGFuY2VzKSB7XG4gICAgICAgICAgICBicm93c2Vyc1RvUmVtb3ZlLnB1c2goaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBSZW1vdmUgaWRsZS9vbGQgYnJvd3NlcnNcbiAgICAgIGZvciAoY29uc3QgaWQgb2YgYnJvd3NlcnNUb1JlbW92ZSkge1xuICAgICAgICBjb25zdCByZWFzb24gPSB0aGlzLnNob3VsZFJldGlyZUJyb3dzZXIodGhpcy5wb29sLmdldChpZCkhKSB8fCAnaWRsZSB0aW1lb3V0JztcbiAgICAgICAgbG9nZ2VyLmluZm8oYFJlbW92aW5nIGJyb3dzZXIgJHtpZH0gZHVlIHRvICR7cmVhc29ufWApO1xuICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUJyb3dzZXJGcm9tUG9vbChpZCk7XG4gICAgICB9XG4gICAgfSwgdGhpcy5vcHRpb25zLmhlYWx0aENoZWNrSW50ZXJ2YWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHVuaXF1ZSBicm93c2VyIElEXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlQnJvd3NlcklkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBicm93c2VyXyR7RGF0ZS5ub3coKX1fJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMiwgMTEpfWA7XG4gIH1cbn1cblxuLy8gR2xvYmFsIGJyb3dzZXIgcG9vbCBpbnN0YW5jZVxubGV0IGdsb2JhbEJyb3dzZXJQb29sOiBCcm93c2VyUG9vbFNlcnZpY2UgfCBudWxsID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJyb3dzZXJQb29sKCk6IEJyb3dzZXJQb29sU2VydmljZSB7XG4gIGlmICghZ2xvYmFsQnJvd3NlclBvb2wpIHtcbiAgICBnbG9iYWxCcm93c2VyUG9vbCA9IG5ldyBCcm93c2VyUG9vbFNlcnZpY2UoKTtcbiAgfVxuICByZXR1cm4gZ2xvYmFsQnJvd3NlclBvb2w7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGVhbnVwQnJvd3NlclBvb2woKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChnbG9iYWxCcm93c2VyUG9vbCkge1xuICAgIGF3YWl0IGdsb2JhbEJyb3dzZXJQb29sLmNsZWFudXAoKTtcbiAgICBnbG9iYWxCcm93c2VyUG9vbCA9IG51bGw7XG4gIH1cbn1cbiIsIi8qKlxuICogQnJvd3NlciBNYW5hZ2VyIGZvciBYSFMgT3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCBwdXBwZXRlZXIsIHsgQnJvd3NlciwgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBDb25maWcsIENvb2tpZSB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBCcm93c2VyTGF1bmNoRXJyb3IsIEJyb3dzZXJOYXZpZ2F0aW9uRXJyb3IsIFhIU0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IGxvYWRDb29raWVzLCBzYXZlQ29va2llcyB9IGZyb20gJy4uLy4uL3NoYXJlZC9jb29raWVzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgQnJvd3NlclBvb2xTZXJ2aWNlLCBNYW5hZ2VkQnJvd3NlciB9IGZyb20gJy4vYnJvd3Nlci1wb29sLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgQnJvd3Nlck1hbmFnZXIge1xuICBwcml2YXRlIGNvbmZpZzogQ29uZmlnO1xuICBwcml2YXRlIGJyb3dzZXI6IEJyb3dzZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBicm93c2VyUG9vbDogQnJvd3NlclBvb2xTZXJ2aWNlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdXNlUG9vbDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZz86IENvbmZpZywgdXNlUG9vbDogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWcgfHwgZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy51c2VQb29sID0gdXNlUG9vbDtcblxuICAgIGlmICh0aGlzLnVzZVBvb2wpIHtcbiAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBuZXcgQnJvd3NlclBvb2xTZXJ2aWNlKHRoaXMuY29uZmlnKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjcmVhdGVQYWdlKFxuICAgIGhlYWRsZXNzPzogYm9vbGVhbixcbiAgICBleGVjdXRhYmxlUGF0aD86IHN0cmluZyxcbiAgICBzaG91bGRMb2FkQ29va2llczogYm9vbGVhbiA9IHRydWVcbiAgKTogUHJvbWlzZTxQYWdlPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFVzZSBicm93c2VyIHBvb2wgaWYgZW5hYmxlZFxuICAgICAgaWYgKHRoaXMudXNlUG9vbCAmJiB0aGlzLmJyb3dzZXJQb29sKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNyZWF0ZVBhZ2VGcm9tUG9vbChzaG91bGRMb2FkQ29va2llcyk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZhbGxiYWNrIHRvIHRyYWRpdGlvbmFsIGJyb3dzZXIgbWFuYWdlbWVudFxuICAgICAgLy8gTGF1bmNoIGJyb3dzZXIgaWYgbm90IGFscmVhZHkgbGF1bmNoZWRcbiAgICAgIGlmICghdGhpcy5icm93c2VyKSB7XG4gICAgICAgIHRoaXMuYnJvd3NlciA9IGF3YWl0IHRoaXMubGF1bmNoQnJvd3NlcihoZWFkbGVzcywgZXhlY3V0YWJsZVBhdGgpO1xuICAgICAgfVxuXG4gICAgICAvLyBDcmVhdGUgbmV3IHBhZ2VcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmJyb3dzZXIubmV3UGFnZSgpO1xuXG4gICAgICAvLyBDb25maWd1cmUgcGFnZSB0aW1lb3V0c1xuICAgICAgcGFnZS5zZXREZWZhdWx0VGltZW91dCh0aGlzLmNvbmZpZy5icm93c2VyLmRlZmF1bHRUaW1lb3V0KTtcbiAgICAgIHBhZ2Uuc2V0RGVmYXVsdE5hdmlnYXRpb25UaW1lb3V0KHRoaXMuY29uZmlnLmJyb3dzZXIubmF2aWdhdGlvblRpbWVvdXQpO1xuXG4gICAgICAvLyBMb2FkIGNvb2tpZXMgaWYgcmVxdWVzdGVkXG4gICAgICBpZiAoc2hvdWxkTG9hZENvb2tpZXMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5sb2FkQ29va2llc0ludG9QYWdlKHBhZ2UpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFnZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBCcm93c2VyIHBhZ2UgY3JlYXRpb24gZXJyb3I6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyB0aGlzLmhhbmRsZVB1cHBldGVlckVycm9yKGVycm9yIGFzIEVycm9yLCAnY3JlYXRlX3BhZ2UnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgcGFnZSB1c2luZyB0aGUgYnJvd3NlciBwb29sXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNyZWF0ZVBhZ2VGcm9tUG9vbChzaG91bGRMb2FkQ29va2llczogYm9vbGVhbiA9IHRydWUpOiBQcm9taXNlPFBhZ2U+IHtcbiAgICBpZiAoIXRoaXMuYnJvd3NlclBvb2wpIHtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcignQnJvd3NlciBwb29sIG5vdCBpbml0aWFsaXplZCcsICdCcm93c2VyUG9vbEVycm9yJyk7XG4gICAgfVxuXG4gICAgY29uc3QgbWFuYWdlZEJyb3dzZXIgPSBhd2FpdCB0aGlzLmJyb3dzZXJQb29sLmFjcXVpcmVCcm93c2VyKCk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gQ3JlYXRlIG5ldyBwYWdlIGZyb20gdGhlIG1hbmFnZWQgYnJvd3NlciBjb250ZXh0XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgbWFuYWdlZEJyb3dzZXIuY29udGV4dC5uZXdQYWdlKCk7XG5cbiAgICAgIC8vIENvbmZpZ3VyZSBwYWdlIHRpbWVvdXRzXG4gICAgICBwYWdlLnNldERlZmF1bHRUaW1lb3V0KHRoaXMuY29uZmlnLmJyb3dzZXIuZGVmYXVsdFRpbWVvdXQpO1xuICAgICAgcGFnZS5zZXREZWZhdWx0TmF2aWdhdGlvblRpbWVvdXQodGhpcy5jb25maWcuYnJvd3Nlci5uYXZpZ2F0aW9uVGltZW91dCk7XG5cbiAgICAgIC8vIExvYWQgY29va2llcyBpZiByZXF1ZXN0ZWRcbiAgICAgIGlmIChzaG91bGRMb2FkQ29va2llcykge1xuICAgICAgICBhd2FpdCB0aGlzLmxvYWRDb29raWVzSW50b1BhZ2UocGFnZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBtYW5hZ2VkIGJyb3dzZXIgZm9yIGNsZWFudXBcbiAgICAgIChwYWdlIGFzIFBhZ2UgJiB7IF9tYW5hZ2VkQnJvd3Nlcj86IE1hbmFnZWRCcm93c2VyIH0pLl9tYW5hZ2VkQnJvd3NlciA9IG1hbmFnZWRCcm93c2VyO1xuXG4gICAgICAvLyBTZXQgdXAgcGFnZSBjbG9zZSBoYW5kbGVyIHRvIHJlbGVhc2UgYnJvd3NlciBiYWNrIHRvIHBvb2xcbiAgICAgIHBhZ2Uub25jZSgnY2xvc2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyUG9vbCEucmVsZWFzZUJyb3dzZXIobWFuYWdlZEJyb3dzZXIpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci53YXJuKGBFcnJvciByZWxlYXNpbmcgYnJvd3NlciBiYWNrIHRvIHBvb2w6ICR7ZXJyb3J9YCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcGFnZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gUmVsZWFzZSBicm93c2VyIGJhY2sgdG8gcG9vbCBvbiBlcnJvclxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyUG9vbC5yZWxlYXNlQnJvd3NlcihtYW5hZ2VkQnJvd3Nlcik7XG4gICAgICB9IGNhdGNoIChyZWxlYXNlRXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIHJlbGVhc2luZyBicm93c2VyIGFmdGVyIHBhZ2UgY3JlYXRpb24gZmFpbHVyZTogJHtyZWxlYXNlRXJyb3J9YCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxhdW5jaEJyb3dzZXIoaGVhZGxlc3M/OiBib29sZWFuLCBleGVjdXRhYmxlUGF0aD86IHN0cmluZyk6IFByb21pc2U8QnJvd3Nlcj4ge1xuICAgIGNvbnN0IGlzSGVhZGxlc3MgPSBmYWxzZTsgLy8gdGVtcG9yYXJpbHkgZGlzYWJsZSBoZWFkbGVzcyBtb2RlIGZvciBkZWJ1Z2dpbmdcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBsYXVuY2hPcHRpb25zOiBhbnkgPSB7XG4gICAgICAgIGhlYWRsZXNzOiBpc0hlYWRsZXNzLFxuICAgICAgICBzbG93TW86IHRoaXMuY29uZmlnLmJyb3dzZXIuc2xvd21vLFxuICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgJy0tbm8tc2FuZGJveCcsXG4gICAgICAgICAgJy0tZGlzYWJsZS1zZXR1aWQtc2FuZGJveCcsXG4gICAgICAgICAgJy0tZGlzYWJsZS1kZXYtc2htLXVzYWdlJyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWFjY2VsZXJhdGVkLTJkLWNhbnZhcycsXG4gICAgICAgICAgJy0tbm8tZmlyc3QtcnVuJyxcbiAgICAgICAgICAnLS1uby16eWdvdGUnLFxuICAgICAgICAgICctLWRpc2FibGUtZ3B1JyxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGlmIChleGVjdXRhYmxlUGF0aCkge1xuICAgICAgICBsYXVuY2hPcHRpb25zLmV4ZWN1dGFibGVQYXRoID0gZXhlY3V0YWJsZVBhdGg7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJyb3dzZXIgPSBhd2FpdCBwdXBwZXRlZXIubGF1bmNoKGxhdW5jaE9wdGlvbnMpO1xuXG4gICAgICByZXR1cm4gYnJvd3NlcjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gbGF1bmNoIGJyb3dzZXI6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgQnJvd3NlckxhdW5jaEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGxhdW5jaCBicm93c2VyOiAke2Vycm9yfWAsXG4gICAgICAgIHsgaGVhZGxlc3M6IGlzSGVhZGxlc3MsIGV4ZWN1dGFibGVQYXRoIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZENvb2tpZXNJbnRvUGFnZShwYWdlOiBQYWdlKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvb2tpZXMgPSBsb2FkQ29va2llcygpO1xuXG4gICAgICBpZiAoIWNvb2tpZXMpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBDb252ZXJ0IG91ciBjb29raWUgZm9ybWF0IHRvIFB1cHBldGVlciBmb3JtYXRcbiAgICAgIGNvbnN0IHB1cHBldGVlckNvb2tpZXMgPSBjb29raWVzLm1hcCgoY29va2llKSA9PiAoe1xuICAgICAgICBuYW1lOiBjb29raWUubmFtZSxcbiAgICAgICAgdmFsdWU6IGNvb2tpZS52YWx1ZSxcbiAgICAgICAgZG9tYWluOiBjb29raWUuZG9tYWluLFxuICAgICAgICBwYXRoOiBjb29raWUucGF0aCxcbiAgICAgICAgZXhwaXJlczogY29va2llLmV4cGlyZXMsXG4gICAgICAgIGh0dHBPbmx5OiBjb29raWUuaHR0cE9ubHksXG4gICAgICAgIHNlY3VyZTogY29va2llLnNlY3VyZSxcbiAgICAgICAgc2FtZVNpdGU6IGNvb2tpZS5zYW1lU2l0ZSBhcyAnU3RyaWN0JyB8ICdMYXgnIHwgJ05vbmUnIHwgdW5kZWZpbmVkLFxuICAgICAgfSkpO1xuXG4gICAgICBhd2FpdCBwYWdlLnNldENvb2tpZSguLi5wdXBwZXRlZXJDb29raWVzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGxvYWQgY29va2llczogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlQ29va2llc0Zyb21QYWdlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29va2llcyA9IGF3YWl0IHBhZ2UuY29va2llcygpO1xuXG4gICAgICAvLyBDb252ZXJ0IFB1cHBldGVlciBjb29raWUgZm9ybWF0IHRvIGFwcCBmb3JtYXRcbiAgICAgIGNvbnN0IGFwcENvb2tpZXM6IENvb2tpZVtdID0gY29va2llcy5tYXAoKGNvb2tpZSkgPT4gKHtcbiAgICAgICAgbmFtZTogY29va2llLm5hbWUsXG4gICAgICAgIHZhbHVlOiBjb29raWUudmFsdWUsXG4gICAgICAgIGRvbWFpbjogY29va2llLmRvbWFpbixcbiAgICAgICAgcGF0aDogY29va2llLnBhdGgsXG4gICAgICAgIGV4cGlyZXM6IGNvb2tpZS5leHBpcmVzLFxuICAgICAgICBodHRwT25seTogY29va2llLmh0dHBPbmx5LFxuICAgICAgICBzZWN1cmU6IGNvb2tpZS5zZWN1cmUsXG4gICAgICAgIHNhbWVTaXRlOiBjb29raWUuc2FtZVNpdGUgYXMgJ1N0cmljdCcgfCAnTGF4JyB8ICdOb25lJyxcbiAgICAgIH0pKTtcblxuICAgICAgc2F2ZUNvb2tpZXMoYXBwQ29va2llcyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHNhdmUgY29va2llczogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IHRoaXMuaGFuZGxlUHVwcGV0ZWVyRXJyb3IoZXJyb3IgYXMgRXJyb3IsICdzYXZlX2Nvb2tpZXMnKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBuYXZpZ2F0ZVdpdGhSZXRyeShcbiAgICBwYWdlOiBQYWdlLFxuICAgIHVybDogc3RyaW5nLFxuICAgIHdhaXRVbnRpbDogJ2xvYWQnIHwgJ2RvbWNvbnRlbnRsb2FkZWQnIHwgJ25ldHdvcmtpZGxlMCcgfCAnbmV0d29ya2lkbGUyJyA9ICdsb2FkJyxcbiAgICBtYXhSZXRyaWVzPzogbnVtYmVyXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJldHJpZXMgPSBtYXhSZXRyaWVzIHx8IHRoaXMuY29uZmlnLnhocy5tYXhSZXRyaWVzO1xuXG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPD0gcmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBwYWdlLmdvdG8odXJsLCB7XG4gICAgICAgICAgd2FpdFVudGlsLFxuICAgICAgICAgIHRpbWVvdXQ6IHRoaXMuY29uZmlnLmJyb3dzZXIubmF2aWdhdGlvblRpbWVvdXQsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5uYW1lID09PSAnVGltZW91dEVycm9yJykge1xuICAgICAgICAgIGlmIChhdHRlbXB0ID09PSByZXRyaWVzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQnJvd3Nlck5hdmlnYXRpb25FcnJvcihcbiAgICAgICAgICAgICAgYEZhaWxlZCB0byBuYXZpZ2F0ZSB0byAke3VybH0gYWZ0ZXIgJHtyZXRyaWVzICsgMX0gYXR0ZW1wdHNgLFxuICAgICAgICAgICAgICB7IHVybCwgYXR0ZW1wdHM6IGF0dGVtcHQgKyAxIH0sXG4gICAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGF3YWl0IHNsZWVwKHRoaXMuY29uZmlnLnhocy5yZXRyeURlbGF5ICogMTAwMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyB0cnlXYWl0Rm9yU2VsZWN0b3IoXG4gICAgcGFnZTogUGFnZSxcbiAgICBzZWxlY3Rvcjogc3RyaW5nLFxuICAgIHRpbWVvdXQ/OiBudW1iZXIsXG4gICAgdmlzaWJsZTogYm9vbGVhbiA9IHRydWVcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKHNlbGVjdG9yLCB7XG4gICAgICAgIHRpbWVvdXQ6IHRpbWVvdXQgfHwgdGhpcy5jb25maWcuYnJvd3Nlci5kZWZhdWx0VGltZW91dCxcbiAgICAgICAgdmlzaWJsZSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdUaW1lb3V0RXJyb3InKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHdhaXRGb3JTZWxlY3RvclZpc2libGUocGFnZTogUGFnZSwgc2VsZWN0b3I6IHN0cmluZywgdGltZW91dD86IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnRyeVdhaXRGb3JTZWxlY3RvcihwYWdlLCBzZWxlY3RvciwgdGltZW91dCwgdHJ1ZSk7XG4gIH1cblxuICBhc3luYyB3YWl0Rm9yU2VsZWN0b3JIaWRkZW4ocGFnZTogUGFnZSwgc2VsZWN0b3I6IHN0cmluZywgdGltZW91dD86IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnRyeVdhaXRGb3JTZWxlY3RvcihwYWdlLCBzZWxlY3RvciwgdGltZW91dCwgZmFsc2UpO1xuICB9XG5cbiAgYXN5bmMgY2xlYW51cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBDbGVhbnVwIGJyb3dzZXIgcG9vbCBpZiB1c2luZyBpdFxuICAgIGlmICh0aGlzLnVzZVBvb2wgJiYgdGhpcy5icm93c2VyUG9vbCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyUG9vbC5jbGVhbnVwKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihgRXJyb3IgY2xlYW5pbmcgdXAgYnJvd3NlciBwb29sOiAke2Vycm9yfWApO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhpcy5icm93c2VyUG9vbCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2xlYW51cCB0cmFkaXRpb25hbCBicm93c2VyIGluc3RhbmNlXG4gICAgaWYgKHRoaXMuYnJvd3Nlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyLmNsb3NlKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihgRXJyb3IgY2xvc2luZyBicm93c2VyOiAke2Vycm9yfWApO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhpcy5icm93c2VyID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGJyb3dzZXIgcG9vbCBzdGF0aXN0aWNzIChpZiB1c2luZyBwb29sKVxuICAgKi9cbiAgZ2V0QnJvd3NlclBvb2xTdGF0cygpIHtcbiAgICBpZiAodGhpcy51c2VQb29sICYmIHRoaXMuYnJvd3NlclBvb2wpIHtcbiAgICAgIHJldHVybiB0aGlzLmJyb3dzZXJQb29sLmdldFBvb2xTdGF0cygpO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmFibGUgYnJvd3NlciBwb29saW5nXG4gICAqL1xuICBlbmFibGVCcm93c2VyUG9vbCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudXNlUG9vbCkge1xuICAgICAgdGhpcy51c2VQb29sID0gdHJ1ZTtcbiAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBuZXcgQnJvd3NlclBvb2xTZXJ2aWNlKHRoaXMuY29uZmlnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGlzYWJsZSBicm93c2VyIHBvb2xpbmdcbiAgICovXG4gIGFzeW5jIGRpc2FibGVCcm93c2VyUG9vbCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy51c2VQb29sICYmIHRoaXMuYnJvd3NlclBvb2wpIHtcbiAgICAgIGF3YWl0IHRoaXMuYnJvd3NlclBvb2wuY2xlYW51cCgpO1xuICAgICAgdGhpcy5icm93c2VyUG9vbCA9IG51bGw7XG4gICAgICB0aGlzLnVzZVBvb2wgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVB1cHBldGVlckVycm9yKGVycm9yOiBFcnJvciwgb3BlcmF0aW9uTmFtZTogc3RyaW5nKTogWEhTRXJyb3Ige1xuICAgIGNvbnN0IGNvbnRleHQgPSB7IG9wZXJhdGlvbk5hbWUgfTtcblxuICAgIGlmIChlcnJvci5uYW1lID09PSAnVGltZW91dEVycm9yJykge1xuICAgICAgaWYgKG9wZXJhdGlvbk5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnbG9naW4nKSkge1xuICAgICAgICByZXR1cm4gbmV3IFhIU0Vycm9yKFxuICAgICAgICAgIGBMb2dpbiBvcGVyYXRpb24gdGltZWQgb3V0IGR1cmluZyAke29wZXJhdGlvbk5hbWV9YCxcbiAgICAgICAgICAnTG9naW5UaW1lb3V0RXJyb3InLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgWEhTRXJyb3IoXG4gICAgICAgICAgYEJyb3dzZXIgb3BlcmF0aW9uIHRpbWVkIG91dDogJHtvcGVyYXRpb25OYW1lfWAsXG4gICAgICAgICAgJ0Jyb3dzZXJFcnJvcicsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZXJyb3IubWVzc2FnZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCduYXZpZ2F0aW9uJykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBCcm93c2VyTmF2aWdhdGlvbkVycm9yKFxuICAgICAgICAgIGBOYXZpZ2F0aW9uIGZhaWxlZCBkdXJpbmcgJHtvcGVyYXRpb25OYW1lfTogJHtlcnJvci5tZXNzYWdlfWAsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBYSFNFcnJvcihcbiAgICAgICAgICBgQnJvd3NlciBlcnJvciBkdXJpbmcgJHtvcGVyYXRpb25OYW1lfTogJHtlcnJvci5tZXNzYWdlfWAsXG4gICAgICAgICAgJ0Jyb3dzZXJFcnJvcicsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vLyBHbG9iYWwgYnJvd3NlciBtYW5hZ2VyIGluc3RhbmNlXG5sZXQgZ2xvYmFsQnJvd3Nlck1hbmFnZXI6IEJyb3dzZXJNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCcm93c2VyTWFuYWdlcih1c2VQb29sOiBib29sZWFuID0gZmFsc2UpOiBCcm93c2VyTWFuYWdlciB7XG4gIGlmICghZ2xvYmFsQnJvd3Nlck1hbmFnZXIpIHtcbiAgICBnbG9iYWxCcm93c2VyTWFuYWdlciA9IG5ldyBCcm93c2VyTWFuYWdlcih1bmRlZmluZWQsIHVzZVBvb2wpO1xuICB9XG4gIHJldHVybiBnbG9iYWxCcm93c2VyTWFuYWdlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvb2xlZEJyb3dzZXJNYW5hZ2VyKCk6IEJyb3dzZXJNYW5hZ2VyIHtcbiAgcmV0dXJuIGdldEJyb3dzZXJNYW5hZ2VyKHRydWUpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2xlYW51cEdsb2JhbEJyb3dzZXJNYW5hZ2VyKCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoZ2xvYmFsQnJvd3Nlck1hbmFnZXIpIHtcbiAgICBhd2FpdCBnbG9iYWxCcm93c2VyTWFuYWdlci5jbGVhbnVwKCk7XG4gICAgZ2xvYmFsQnJvd3Nlck1hbmFnZXIgPSBudWxsO1xuICB9XG59XG4iLCIvKipcbiAqIEJhc2Ugc2VydmljZSBjbGFzcyBmb3IgWEhTIE1DUCBTZXJ2ZXIgc2VydmljZXNcbiAqL1xuXG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IEJyb3dzZXJNYW5hZ2VyIH0gZnJvbSAnLi4vY29yZS9icm93c2VyL2Jyb3dzZXIubWFuYWdlcic7XG5cbi8qKlxuICogQmFzZSBzZXJ2aWNlIGNsYXNzIHRoYXQgcHJvdmlkZXMgY29tbW9uIGZ1bmN0aW9uYWxpdHkgZm9yIGFsbCBzZXJ2aWNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZVNlcnZpY2Uge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY29uZmlnOiBDb25maWc7XG4gIHByb3RlY3RlZCByZWFkb25seSBicm93c2VyTWFuYWdlcjogQnJvd3Nlck1hbmFnZXI7XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLmJyb3dzZXJNYW5hZ2VyID0gbmV3IEJyb3dzZXJNYW5hZ2VyKGNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBicm93c2VyIG1hbmFnZXIgaW5zdGFuY2VcbiAgICovXG4gIHByb3RlY3RlZCBnZXRCcm93c2VyTWFuYWdlcigpOiBCcm93c2VyTWFuYWdlciB7XG4gICAgcmV0dXJuIHRoaXMuYnJvd3Nlck1hbmFnZXI7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0Q29uZmlnKCk6IENvbmZpZyB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnO1xuICB9XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3100\n\n}");
73
+ module.exports = require("string_decoder");
67
74
 
68
75
  /***/ }),
69
76
 
70
- /***/ 3193:
71
- /***/ ((module) => {
77
+ /***/ 3977:
78
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
72
79
 
73
- module.exports = require("string_decoder");
80
+ eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n Gd: () => (/* binding */ BrowserManager)\n});\n\n// UNUSED EXPORTS: cleanupGlobalBrowserManager, getBrowserManager, getPooledBrowserManager\n\n// EXTERNAL MODULE: external \"puppeteer\"\nvar external_puppeteer_ = __webpack_require__(9916);\nvar external_puppeteer_default = /*#__PURE__*/__webpack_require__.n(external_puppeteer_);\n// EXTERNAL MODULE: ./src/shared/errors.ts\nvar errors = __webpack_require__(7636);\n// EXTERNAL MODULE: ./src/shared/config.ts + 1 modules\nvar shared_config = __webpack_require__(2207);\n// EXTERNAL MODULE: ./src/shared/cookies.ts\nvar shared_cookies = __webpack_require__(4760);\n// EXTERNAL MODULE: ./src/shared/logger.ts\nvar logger = __webpack_require__(9135);\n// EXTERNAL MODULE: ./src/shared/utils.ts\nvar utils = __webpack_require__(2094);\n;// ./src/core/browser/browser-pool.service.ts\n/**\n * Browser Pool Service for XHS Operations\n * Manages browser instance lifecycle with pooling, health monitoring, and automatic cleanup\n */\n\n\n\n\n\nclass BrowserPoolService {\n config;\n pool = new Map();\n options;\n healthCheckTimer = null;\n cleanupTimer = null;\n isShuttingDown = false;\n constructor(config, options) {\n this.config = config || (0,shared_config/* getConfig */.zj)();\n // Set default options with configuration from environment or defaults\n const idleTimeout = options?.idleTimeout ?? 300000;\n this.options = {\n minInstances: options?.minInstances ?? 2,\n maxInstances: options?.maxInstances ?? 5,\n idleTimeout,\n maxAge: options?.maxAge ?? 1800000, // 30 minutes\n healthCheckInterval: options?.healthCheckInterval ?? 60000, // 1 minute\n maxUsageCount: options?.maxUsageCount ?? 100,\n stuckTimeout: options?.stuckTimeout ?? 600000, // 10 minutes\n };\n this.startHealthMonitoring();\n this.startCleanupMonitoring();\n }\n /**\n * Acquire a browser instance from the pool\n */\n async acquireBrowser(options) {\n if (this.isShuttingDown) {\n throw new errors/* XHSError */.a_('Browser pool is shutting down', 'BrowserPoolError');\n }\n const timeout = options?.timeout ?? 30000;\n const startTime = Date.now();\n while (Date.now() - startTime < timeout) {\n // Try to find an available healthy browser\n const availableBrowser = this.findAvailableBrowser();\n if (availableBrowser) {\n availableBrowser.isAvailable = false;\n availableBrowser.lastUsed = new Date();\n availableBrowser.usageCount++;\n logger/* logger */.v.debug(`Acquired browser ${availableBrowser.id} from pool`);\n return availableBrowser;\n }\n // If no available browser and we can create more, create one\n if (this.pool.size < this.options.maxInstances) {\n try {\n const newBrowser = await this.createBrowserInstance();\n newBrowser.isAvailable = false;\n newBrowser.lastUsed = new Date();\n newBrowser.usageCount++;\n logger/* logger */.v.info(`Created new browser ${newBrowser.id} for pool`);\n return newBrowser;\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to create new browser instance: ${error}`);\n }\n }\n // Wait a bit before retrying\n await (0,utils/* sleep */.yy)(100);\n }\n throw new errors/* XHSError */.a_(`Failed to acquire browser within ${timeout}ms timeout`, 'BrowserPoolTimeout', { timeout, poolSize: this.pool.size, availableCount: this.getAvailableCount() });\n }\n /**\n * Release a browser instance back to the pool\n */\n async releaseBrowser(browser) {\n const managedBrowser = this.pool.get(browser.id);\n if (!managedBrowser) {\n logger/* logger */.v.warn(`Attempted to release unknown browser ${browser.id}`);\n return;\n }\n // If idleTimeout <= 0, close browser immediately instead of returning to pool\n if (this.options.idleTimeout <= 0) {\n logger/* logger */.v.debug(`Browser ${browser.id} released with idleTimeout=0, closing immediately`);\n await this.removeBrowserFromPool(browser.id);\n await this.ensureMinimumInstances();\n return;\n }\n // Check if browser should be retired due to age or usage\n const shouldRetire = this.shouldRetireBrowser(managedBrowser);\n if (shouldRetire) {\n logger/* logger */.v.info(`Retiring browser ${browser.id} due to ${shouldRetire}`);\n await this.removeBrowserFromPool(browser.id);\n // Ensure we maintain minimum instances\n await this.ensureMinimumInstances();\n return;\n }\n // Perform health check before returning to pool\n const isHealthy = await this.checkBrowserHealth(managedBrowser);\n if (!isHealthy) {\n logger/* logger */.v.warn(`Browser ${browser.id} failed health check, removing from pool`);\n await this.removeBrowserFromPool(browser.id);\n await this.ensureMinimumInstances();\n return;\n }\n // Return to pool\n managedBrowser.isAvailable = true;\n managedBrowser.isHealthy = true;\n logger/* logger */.v.debug(`Released browser ${browser.id} back to pool`);\n }\n /**\n * Get current pool statistics\n */\n getPoolStats() {\n const instances = Array.from(this.pool.values());\n const availableInstances = instances.filter((b) => b.isAvailable && b.isHealthy).length;\n const busyInstances = instances.filter((b) => !b.isAvailable).length;\n const unhealthyInstances = instances.filter((b) => !b.isHealthy).length;\n const totalUsage = instances.reduce((sum, b) => sum + b.usageCount, 0);\n const ages = instances.map((b) => Date.now() - b.createdAt.getTime());\n const averageAge = ages.length > 0 ? ages.reduce((sum, age) => sum + age, 0) / ages.length : 0;\n const oldestInstance = instances.length > 0\n ? instances.reduce((oldest, current) => current.createdAt < oldest.createdAt ? current : oldest).createdAt\n : null;\n const newestInstance = instances.length > 0\n ? instances.reduce((newest, current) => current.createdAt > newest.createdAt ? current : newest).createdAt\n : null;\n return {\n totalInstances: instances.length,\n availableInstances,\n busyInstances,\n unhealthyInstances,\n totalUsage,\n averageAge,\n oldestInstance,\n newestInstance,\n };\n }\n /**\n * Cleanup and shutdown the browser pool\n */\n async cleanup() {\n this.isShuttingDown = true;\n // Stop monitoring timers\n if (this.healthCheckTimer) {\n clearInterval(this.healthCheckTimer);\n this.healthCheckTimer = null;\n }\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n // Close all browsers\n const closePromises = Array.from(this.pool.values()).map(async (managedBrowser) => {\n try {\n await managedBrowser.browser.close();\n logger/* logger */.v.debug(`Closed browser ${managedBrowser.id}`);\n }\n catch (error) {\n logger/* logger */.v.warn(`Error closing browser ${managedBrowser.id}: ${error}`);\n }\n });\n await Promise.allSettled(closePromises);\n this.pool.clear();\n logger/* logger */.v.info('Browser pool cleanup completed');\n }\n /**\n * Create a new browser instance\n */\n async createBrowserInstance() {\n try {\n const launchOptions = {\n headless: this.config.browser.headlessDefault,\n slowMo: this.config.browser.slowmo,\n args: [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--no-first-run',\n '--no-zygote',\n '--disable-gpu',\n '--disable-background-timer-throttling',\n '--disable-backgrounding-occluded-windows',\n '--disable-renderer-backgrounding',\n ],\n };\n const browser = await external_puppeteer_default().launch(launchOptions);\n const context = await browser.createBrowserContext();\n const id = this.generateBrowserId();\n const managedBrowser = {\n browser,\n context,\n id,\n createdAt: new Date(),\n lastUsed: new Date(),\n isAvailable: true,\n isHealthy: true,\n usageCount: 0,\n };\n this.pool.set(id, managedBrowser);\n // Set up browser event handlers\n browser.on('disconnected', () => {\n logger/* logger */.v.warn(`Browser ${id} disconnected unexpectedly`);\n this.handleBrowserDisconnection(id);\n });\n return managedBrowser;\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to create browser instance: ${error}`);\n throw new errors/* BrowserLaunchError */.EE(`Failed to create browser instance: ${error}`, { poolSize: this.pool.size }, error);\n }\n }\n /**\n * Find an available healthy browser in the pool\n */\n findAvailableBrowser() {\n for (const browser of this.pool.values()) {\n if (browser.isAvailable && browser.isHealthy) {\n return browser;\n }\n }\n return null;\n }\n /**\n * Check if a browser should be retired\n */\n shouldRetireBrowser(browser) {\n const age = Date.now() - browser.createdAt.getTime();\n if (age > this.options.maxAge) {\n return 'max age exceeded';\n }\n if (browser.usageCount >= this.options.maxUsageCount) {\n return 'max usage count exceeded';\n }\n return null;\n }\n /**\n * Perform health check on a browser instance\n */\n async checkBrowserHealth(browser) {\n try {\n // Check if browser is connected\n if (!browser.browser.isConnected()) {\n return false;\n }\n // Try to create and close a test page\n const page = await browser.context.newPage();\n await page.close();\n return true;\n }\n catch (error) {\n logger/* logger */.v.debug(`Browser ${browser.id} health check failed: ${error}`);\n return false;\n }\n }\n /**\n * Remove a browser from the pool\n */\n async removeBrowserFromPool(browserId) {\n const browser = this.pool.get(browserId);\n if (!browser) {\n return;\n }\n try {\n await browser.browser.close();\n }\n catch (error) {\n logger/* logger */.v.warn(`Error closing browser ${browserId}: ${error}`);\n }\n this.pool.delete(browserId);\n logger/* logger */.v.debug(`Removed browser ${browserId} from pool`);\n }\n /**\n * Handle browser disconnection\n */\n async handleBrowserDisconnection(browserId) {\n const browser = this.pool.get(browserId);\n if (browser) {\n browser.isHealthy = false;\n browser.isAvailable = false;\n }\n // Remove the disconnected browser and ensure minimum instances\n await this.removeBrowserFromPool(browserId);\n await this.ensureMinimumInstances();\n }\n /**\n * Ensure minimum number of instances are available\n */\n async ensureMinimumInstances() {\n if (this.isShuttingDown) {\n return;\n }\n const healthyCount = Array.from(this.pool.values()).filter((b) => b.isHealthy).length;\n const needed = this.options.minInstances - healthyCount;\n if (needed > 0) {\n logger/* logger */.v.info(`Creating ${needed} browser instances to maintain minimum pool size`);\n const createPromises = Array.from({ length: needed }, () => this.createBrowserInstance().catch((error) => {\n logger/* logger */.v.error(`Failed to create browser for minimum instances: ${error}`);\n return null;\n }));\n await Promise.allSettled(createPromises);\n }\n }\n /**\n * Get count of available browsers\n */\n getAvailableCount() {\n return Array.from(this.pool.values()).filter((b) => b.isAvailable && b.isHealthy).length;\n }\n /**\n * Start health monitoring\n */\n startHealthMonitoring() {\n this.healthCheckTimer = setInterval(async () => {\n if (this.isShuttingDown) {\n return;\n }\n const unhealthyBrowsers = [];\n for (const [id, browser] of this.pool.entries()) {\n if (!browser.isAvailable) {\n continue; // Skip browsers currently in use\n }\n const isHealthy = await this.checkBrowserHealth(browser);\n if (!isHealthy) {\n unhealthyBrowsers.push(id);\n browser.isHealthy = false;\n }\n }\n // Remove unhealthy browsers\n for (const id of unhealthyBrowsers) {\n logger/* logger */.v.warn(`Removing unhealthy browser ${id} during health check`);\n await this.removeBrowserFromPool(id);\n }\n // Ensure minimum instances after cleanup\n if (unhealthyBrowsers.length > 0) {\n await this.ensureMinimumInstances();\n }\n }, this.options.healthCheckInterval);\n }\n /**\n * Start cleanup monitoring for idle and stuck browsers\n */\n startCleanupMonitoring() {\n this.cleanupTimer = setInterval(async () => {\n if (this.isShuttingDown) {\n return;\n }\n const now = Date.now();\n const browsersToRemove = [];\n for (const [id, browser] of this.pool.entries()) {\n const idleTime = now - browser.lastUsed.getTime();\n const shouldRetire = this.shouldRetireBrowser(browser);\n // Also check stuck browsers (busy but stuck timeout exceeded)\n // These are usually caused by unhandled exceptions preventing releaseBrowser from being called\n const isStuck = !browser.isAvailable && idleTime > this.options.stuckTimeout;\n if (idleTime > this.options.idleTimeout || shouldRetire || isStuck) {\n const healthyCount = Array.from(this.pool.values()).filter((b) => b.isHealthy).length;\n // Force removal for stuck browsers (don't check minimum instance count)\n // Otherwise only remove if above minimum instances\n if (isStuck || healthyCount > this.options.minInstances) {\n browsersToRemove.push(id);\n }\n }\n }\n // Remove idle/old/stuck browsers\n for (const id of browsersToRemove) {\n const browser = this.pool.get(id);\n const isStuck = browser && !browser.isAvailable;\n const reason = this.shouldRetireBrowser(browser) || (isStuck ? 'stuck browser timeout' : 'idle timeout');\n logger/* logger */.v.info(`Removing browser ${id} due to ${reason}`);\n // For stuck browsers, try to close any open pages first\n if (isStuck && browser) {\n try {\n const pages = await browser.context.pages();\n for (const p of pages) {\n try {\n if (!p.isClosed()) {\n await p.close();\n }\n }\n catch (e) {\n // ignore\n }\n }\n }\n catch (e) {\n // ignore\n }\n }\n await this.removeBrowserFromPool(id);\n }\n // Ensure minimum instances after cleanup only if browsers were removed\n if (browsersToRemove.length > 0) {\n await this.ensureMinimumInstances();\n }\n }, this.options.healthCheckInterval);\n }\n /**\n * Generate unique browser ID\n */\n generateBrowserId() {\n return `browser_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n }\n}\n// Global browser pool instance\nlet globalBrowserPool = null;\nfunction getBrowserPool() {\n if (!globalBrowserPool) {\n globalBrowserPool = new BrowserPoolService();\n }\n return globalBrowserPool;\n}\nasync function cleanupBrowserPool() {\n if (globalBrowserPool) {\n await globalBrowserPool.cleanup();\n globalBrowserPool = null;\n }\n}\n\n;// ./src/core/browser/browser.manager.ts\n/**\n * Browser Manager for XHS Operations\n */\n\n\n\n\n\n\n\nclass BrowserManager {\n config;\n browser = null;\n browserPool = null;\n usePool = false;\n poolOptions;\n trackedPages = new Set();\n maxTrackedPages = 10;\n constructor(config, usePool = false, poolOptions) {\n this.config = config || (0,shared_config/* getConfig */.zj)();\n this.usePool = usePool;\n this.poolOptions = poolOptions;\n if (this.usePool) {\n this.browserPool = new BrowserPoolService(this.config, poolOptions);\n }\n }\n async createPage(headless, executablePath, shouldLoadCookies = true) {\n try {\n // Use browser pool if enabled\n if (this.usePool && this.browserPool) {\n return await this.createPageFromPool(shouldLoadCookies);\n }\n // Fallback to traditional browser management\n // Launch browser if not already launched\n if (!this.browser) {\n this.browser = await this.launchBrowser(headless, executablePath);\n }\n // Create new page\n const page = await this.browser.newPage();\n // Track page for cleanup\n this.trackedPages.add(page);\n page.once('close', () => {\n this.trackedPages.delete(page);\n });\n // Auto-cleanup if too many pages are open (leak detection)\n if (this.trackedPages.size > this.maxTrackedPages) {\n logger/* logger */.v.warn(`Tracked pages (${this.trackedPages.size}) exceeds threshold (${this.maxTrackedPages}), forcing cleanup`);\n await this.closeAllPages();\n }\n // Configure page timeouts\n page.setDefaultTimeout(this.config.browser.defaultTimeout);\n page.setDefaultNavigationTimeout(this.config.browser.navigationTimeout);\n // Load cookies if requested\n if (shouldLoadCookies) {\n await this.loadCookiesIntoPage(page);\n }\n return page;\n }\n catch (error) {\n logger/* logger */.v.error(`Browser page creation error: ${error}`);\n throw this.handlePuppeteerError(error, 'create_page');\n }\n }\n /**\n * Create a page using the browser pool\n */\n async createPageFromPool(shouldLoadCookies = true) {\n if (!this.browserPool) {\n throw new errors/* XHSError */.a_('Browser pool not initialized', 'BrowserPoolError');\n }\n const managedBrowser = await this.browserPool.acquireBrowser();\n try {\n // Create new page from the managed browser context\n const page = await managedBrowser.context.newPage();\n // Configure page timeouts\n page.setDefaultTimeout(this.config.browser.defaultTimeout);\n page.setDefaultNavigationTimeout(this.config.browser.navigationTimeout);\n // Load cookies if requested\n if (shouldLoadCookies) {\n await this.loadCookiesIntoPage(page);\n }\n // Store reference to managed browser for cleanup\n page._managedBrowser = managedBrowser;\n // Set up page close handler to release browser back to pool\n let released = false;\n const releaseBrowser = async () => {\n if (released)\n return;\n released = true;\n try {\n await this.browserPool.releaseBrowser(managedBrowser);\n }\n catch (error) {\n logger/* logger */.v.warn(`Error releasing browser back to pool: ${error}`);\n }\n };\n page.once('close', releaseBrowser);\n return page;\n }\n catch (error) {\n // Release browser back to pool on error\n try {\n await this.browserPool.releaseBrowser(managedBrowser);\n }\n catch (releaseError) {\n logger/* logger */.v.warn(`Error releasing browser after page creation failure: ${releaseError}`);\n }\n throw error;\n }\n }\n async launchBrowser(headless, executablePath) {\n const isHeadless = headless ?? this.config.browser.headlessDefault;\n try {\n const launchOptions = {\n headless: isHeadless,\n slowMo: this.config.browser.slowmo,\n args: [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-dev-shm-usage',\n '--disable-accelerated-2d-canvas',\n '--no-first-run',\n '--no-zygote',\n '--disable-gpu',\n ],\n };\n if (executablePath) {\n launchOptions.executablePath = executablePath;\n }\n const browser = await external_puppeteer_default().launch(launchOptions);\n return browser;\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to launch browser: ${error}`);\n throw new errors/* BrowserLaunchError */.EE(`Failed to launch browser: ${error}`, { headless: isHeadless, executablePath }, error);\n }\n }\n async loadCookiesIntoPage(page) {\n try {\n const cookies = (0,shared_cookies/* loadCookies */.O4)();\n if (!cookies) {\n return false;\n }\n // Convert our cookie format to Puppeteer format\n const puppeteerCookies = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain,\n path: cookie.path,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite,\n }));\n await page.setCookie(...puppeteerCookies);\n return true;\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to load cookies: ${error}`);\n return false;\n }\n }\n async saveCookiesFromPage(page) {\n try {\n const cookies = await page.cookies();\n // Convert Puppeteer cookie format to app format\n const appCookies = cookies.map((cookie) => ({\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain,\n path: cookie.path,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite,\n }));\n (0,shared_cookies/* saveCookies */.XM)(appCookies);\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to save cookies: ${error}`);\n throw this.handlePuppeteerError(error, 'save_cookies');\n }\n }\n async navigateWithRetry(page, url, waitUntil = 'load', maxRetries) {\n const retries = maxRetries || this.config.xhs.maxRetries;\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n await page.goto(url, {\n waitUntil,\n timeout: this.config.browser.navigationTimeout,\n });\n return;\n }\n catch (error) {\n if (error instanceof Error && error.name === 'TimeoutError') {\n if (attempt === retries) {\n throw new errors/* BrowserNavigationError */.Jk(`Failed to navigate to ${url} after ${retries + 1} attempts`, { url, attempts: attempt + 1 }, error);\n }\n await (0,utils/* sleep */.yy)(this.config.xhs.retryDelay * 1000);\n }\n else {\n throw error;\n }\n }\n }\n }\n async tryWaitForSelector(page, selector, timeout, visible = true) {\n try {\n await page.waitForSelector(selector, {\n timeout: timeout || this.config.browser.defaultTimeout,\n visible,\n });\n return true;\n }\n catch (error) {\n if (error instanceof Error && error.name === 'TimeoutError') {\n return false;\n }\n throw error;\n }\n }\n async waitForSelectorVisible(page, selector, timeout) {\n return this.tryWaitForSelector(page, selector, timeout, true);\n }\n async waitForSelectorHidden(page, selector, timeout) {\n return this.tryWaitForSelector(page, selector, timeout, false);\n }\n async cleanup() {\n // Cleanup browser pool if using it\n if (this.usePool && this.browserPool) {\n try {\n await this.browserPool.cleanup();\n }\n catch (error) {\n logger/* logger */.v.warn(`Error cleaning up browser pool: ${error}`);\n }\n finally {\n this.browserPool = null;\n }\n }\n // Close all tracked pages before closing browser\n await this.closeAllPages();\n // Cleanup traditional browser instance\n if (this.browser) {\n try {\n await this.browser.close();\n }\n catch (error) {\n logger/* logger */.v.warn(`Error closing browser: ${error}`);\n }\n finally {\n this.browser = null;\n }\n }\n }\n /**\n * Close all tracked pages that are still open\n */\n async closeAllPages() {\n const closePromises = [];\n for (const page of this.trackedPages) {\n if (!page.isClosed()) {\n closePromises.push(page.close().catch((error) => {\n logger/* logger */.v.warn(`Error closing tracked page: ${error}`);\n }));\n }\n }\n await Promise.allSettled(closePromises);\n this.trackedPages.clear();\n }\n /**\n * Get browser pool statistics (if using pool)\n */\n getBrowserPoolStats() {\n if (this.usePool && this.browserPool) {\n return this.browserPool.getPoolStats();\n }\n return null;\n }\n /**\n * Get the number of tracked pages (for monitoring leaks)\n */\n getTrackedPageCount() {\n return this.trackedPages.size;\n }\n /**\n * Enable browser pooling\n */\n enableBrowserPool() {\n if (!this.usePool) {\n this.usePool = true;\n this.browserPool = new BrowserPoolService(this.config, this.poolOptions);\n }\n }\n /**\n * Disable browser pooling\n */\n async disableBrowserPool() {\n if (this.usePool && this.browserPool) {\n await this.browserPool.cleanup();\n this.browserPool = null;\n this.usePool = false;\n }\n }\n handlePuppeteerError(error, operationName) {\n const context = { operationName };\n if (error.name === 'TimeoutError') {\n if (operationName.toLowerCase().includes('login')) {\n return new errors/* XHSError */.a_(`Login operation timed out during ${operationName}`, 'LoginTimeoutError', context, error);\n }\n else {\n return new errors/* XHSError */.a_(`Browser operation timed out: ${operationName}`, 'BrowserError', context, error);\n }\n }\n else {\n if (error.message.toLowerCase().includes('navigation')) {\n return new errors/* BrowserNavigationError */.Jk(`Navigation failed during ${operationName}: ${error.message}`, context, error);\n }\n else {\n return new errors/* XHSError */.a_(`Browser error during ${operationName}: ${error.message}`, 'BrowserError', context, error);\n }\n }\n }\n}\n// Global browser manager instance\nlet globalBrowserManager = null;\nfunction getBrowserManager(usePool = false) {\n if (!globalBrowserManager) {\n globalBrowserManager = new BrowserManager(undefined, usePool);\n }\n return globalBrowserManager;\n}\nfunction getPooledBrowserManager() {\n return getBrowserManager(true);\n}\nasync function cleanupGlobalBrowserManager() {\n if (globalBrowserManager) {\n await globalBrowserManager.cleanup();\n globalBrowserManager = null;\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LElBQUksQ0FBQztJQUM5QixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9icm93c2VyL2Jyb3dzZXItcG9vbC5zZXJ2aWNlLnRzPzRjNTQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyLnRzPzRjMGYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCcm93c2VyIFBvb2wgU2VydmljZSBmb3IgWEhTIE9wZXJhdGlvbnNcbiAqIE1hbmFnZXMgYnJvd3NlciBpbnN0YW5jZSBsaWZlY3ljbGUgd2l0aCBwb29saW5nLCBoZWFsdGggbW9uaXRvcmluZywgYW5kIGF1dG9tYXRpYyBjbGVhbnVwXG4gKi9cblxuaW1wb3J0IHB1cHBldGVlciwgeyBCcm93c2VyLCBCcm93c2VyQ29udGV4dCwgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgQnJvd3NlckxhdW5jaEVycm9yLCBYSFNFcnJvciB9IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgZ2V0Q29uZmlnIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2NvbmZpZyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBNYW5hZ2VkQnJvd3NlciB7XG4gIGJyb3dzZXI6IEJyb3dzZXI7XG4gIGNvbnRleHQ6IEJyb3dzZXJDb250ZXh0O1xuICBpZDogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIGxhc3RVc2VkOiBEYXRlO1xuICBpc0F2YWlsYWJsZTogYm9vbGVhbjtcbiAgaXNIZWFsdGh5OiBib29sZWFuO1xuICB1c2FnZUNvdW50OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnJvd3NlclBvb2xTdGF0cyB7XG4gIHRvdGFsSW5zdGFuY2VzOiBudW1iZXI7XG4gIGF2YWlsYWJsZUluc3RhbmNlczogbnVtYmVyO1xuICBidXN5SW5zdGFuY2VzOiBudW1iZXI7XG4gIHVuaGVhbHRoeUluc3RhbmNlczogbnVtYmVyO1xuICB0b3RhbFVzYWdlOiBudW1iZXI7XG4gIGF2ZXJhZ2VBZ2U6IG51bWJlcjtcbiAgb2xkZXN0SW5zdGFuY2U6IERhdGUgfCBudWxsO1xuICBuZXdlc3RJbnN0YW5jZTogRGF0ZSB8IG51bGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnJvd3NlclBvb2xPcHRpb25zIHtcbiAgbWluSW5zdGFuY2VzPzogbnVtYmVyO1xuICBtYXhJbnN0YW5jZXM/OiBudW1iZXI7XG4gIGlkbGVUaW1lb3V0PzogbnVtYmVyO1xuICBtYXhBZ2U/OiBudW1iZXI7XG4gIGhlYWx0aENoZWNrSW50ZXJ2YWw/OiBudW1iZXI7XG4gIG1heFVzYWdlQ291bnQ/OiBudW1iZXI7XG4gIHN0dWNrVGltZW91dD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNsYXNzIEJyb3dzZXJQb29sU2VydmljZSB7XG4gIHByaXZhdGUgY29uZmlnOiBDb25maWc7XG4gIHByaXZhdGUgcG9vbDogTWFwPHN0cmluZywgTWFuYWdlZEJyb3dzZXI+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIG9wdGlvbnM6IFJlcXVpcmVkPEJyb3dzZXJQb29sT3B0aW9ucz47XG4gIHByaXZhdGUgaGVhbHRoQ2hlY2tUaW1lcjogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjbGVhbnVwVGltZXI6IE5vZGVKUy5UaW1lb3V0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaXNTaHV0dGluZ0Rvd24gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc/OiBDb25maWcsIG9wdGlvbnM/OiBCcm93c2VyUG9vbE9wdGlvbnMpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCBnZXRDb25maWcoKTtcblxuICAgIC8vIFNldCBkZWZhdWx0IG9wdGlvbnMgd2l0aCBjb25maWd1cmF0aW9uIGZyb20gZW52aXJvbm1lbnQgb3IgZGVmYXVsdHNcbiAgICBjb25zdCBpZGxlVGltZW91dCA9IG9wdGlvbnM/LmlkbGVUaW1lb3V0ID8/IDMwMDAwMDtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBtaW5JbnN0YW5jZXM6IG9wdGlvbnM/Lm1pbkluc3RhbmNlcyA/PyAyLFxuICAgICAgbWF4SW5zdGFuY2VzOiBvcHRpb25zPy5tYXhJbnN0YW5jZXMgPz8gNSxcbiAgICAgIGlkbGVUaW1lb3V0LFxuICAgICAgbWF4QWdlOiBvcHRpb25zPy5tYXhBZ2UgPz8gMTgwMDAwMCwgLy8gMzAgbWludXRlc1xuICAgICAgaGVhbHRoQ2hlY2tJbnRlcnZhbDogb3B0aW9ucz8uaGVhbHRoQ2hlY2tJbnRlcnZhbCA/PyA2MDAwMCwgLy8gMSBtaW51dGVcbiAgICAgIG1heFVzYWdlQ291bnQ6IG9wdGlvbnM/Lm1heFVzYWdlQ291bnQgPz8gMTAwLFxuICAgICAgc3R1Y2tUaW1lb3V0OiBvcHRpb25zPy5zdHVja1RpbWVvdXQgPz8gNjAwMDAwLCAvLyAxMCBtaW51dGVzXG4gICAgfTtcblxuICAgIHRoaXMuc3RhcnRIZWFsdGhNb25pdG9yaW5nKCk7XG4gICAgdGhpcy5zdGFydENsZWFudXBNb25pdG9yaW5nKCk7XG4gIH1cblxuICAvKipcbiAgICogQWNxdWlyZSBhIGJyb3dzZXIgaW5zdGFuY2UgZnJvbSB0aGUgcG9vbFxuICAgKi9cbiAgYXN5bmMgYWNxdWlyZUJyb3dzZXIob3B0aW9ucz86IHsgdGltZW91dD86IG51bWJlciB9KTogUHJvbWlzZTxNYW5hZ2VkQnJvd3Nlcj4ge1xuICAgIGlmICh0aGlzLmlzU2h1dHRpbmdEb3duKSB7XG4gICAgICB0aHJvdyBuZXcgWEhTRXJyb3IoJ0Jyb3dzZXIgcG9vbCBpcyBzaHV0dGluZyBkb3duJywgJ0Jyb3dzZXJQb29sRXJyb3InKTtcbiAgICB9XG5cbiAgICBjb25zdCB0aW1lb3V0ID0gb3B0aW9ucz8udGltZW91dCA/PyAzMDAwMDtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCB0aW1lb3V0KSB7XG4gICAgICAvLyBUcnkgdG8gZmluZCBhbiBhdmFpbGFibGUgaGVhbHRoeSBicm93c2VyXG4gICAgICBjb25zdCBhdmFpbGFibGVCcm93c2VyID0gdGhpcy5maW5kQXZhaWxhYmxlQnJvd3NlcigpO1xuICAgICAgaWYgKGF2YWlsYWJsZUJyb3dzZXIpIHtcbiAgICAgICAgYXZhaWxhYmxlQnJvd3Nlci5pc0F2YWlsYWJsZSA9IGZhbHNlO1xuICAgICAgICBhdmFpbGFibGVCcm93c2VyLmxhc3RVc2VkID0gbmV3IERhdGUoKTtcbiAgICAgICAgYXZhaWxhYmxlQnJvd3Nlci51c2FnZUNvdW50Kys7XG5cbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBBY3F1aXJlZCBicm93c2VyICR7YXZhaWxhYmxlQnJvd3Nlci5pZH0gZnJvbSBwb29sYCk7XG4gICAgICAgIHJldHVybiBhdmFpbGFibGVCcm93c2VyO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBubyBhdmFpbGFibGUgYnJvd3NlciBhbmQgd2UgY2FuIGNyZWF0ZSBtb3JlLCBjcmVhdGUgb25lXG4gICAgICBpZiAodGhpcy5wb29sLnNpemUgPCB0aGlzLm9wdGlvbnMubWF4SW5zdGFuY2VzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgbmV3QnJvd3NlciA9IGF3YWl0IHRoaXMuY3JlYXRlQnJvd3Nlckluc3RhbmNlKCk7XG4gICAgICAgICAgbmV3QnJvd3Nlci5pc0F2YWlsYWJsZSA9IGZhbHNlO1xuICAgICAgICAgIG5ld0Jyb3dzZXIubGFzdFVzZWQgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgIG5ld0Jyb3dzZXIudXNhZ2VDb3VudCsrO1xuXG4gICAgICAgICAgbG9nZ2VyLmluZm8oYENyZWF0ZWQgbmV3IGJyb3dzZXIgJHtuZXdCcm93c2VyLmlkfSBmb3IgcG9vbGApO1xuICAgICAgICAgIHJldHVybiBuZXdCcm93c2VyO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBuZXcgYnJvd3NlciBpbnN0YW5jZTogJHtlcnJvcn1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBXYWl0IGEgYml0IGJlZm9yZSByZXRyeWluZ1xuICAgICAgYXdhaXQgc2xlZXAoMTAwKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgWEhTRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIGFjcXVpcmUgYnJvd3NlciB3aXRoaW4gJHt0aW1lb3V0fW1zIHRpbWVvdXRgLFxuICAgICAgJ0Jyb3dzZXJQb29sVGltZW91dCcsXG4gICAgICB7IHRpbWVvdXQsIHBvb2xTaXplOiB0aGlzLnBvb2wuc2l6ZSwgYXZhaWxhYmxlQ291bnQ6IHRoaXMuZ2V0QXZhaWxhYmxlQ291bnQoKSB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxlYXNlIGEgYnJvd3NlciBpbnN0YW5jZSBiYWNrIHRvIHRoZSBwb29sXG4gICAqL1xuICBhc3luYyByZWxlYXNlQnJvd3Nlcihicm93c2VyOiBNYW5hZ2VkQnJvd3Nlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1hbmFnZWRCcm93c2VyID0gdGhpcy5wb29sLmdldChicm93c2VyLmlkKTtcbiAgICBpZiAoIW1hbmFnZWRCcm93c2VyKSB7XG4gICAgICBsb2dnZXIud2FybihgQXR0ZW1wdGVkIHRvIHJlbGVhc2UgdW5rbm93biBicm93c2VyICR7YnJvd3Nlci5pZH1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiBpZGxlVGltZW91dCA8PSAwLCBjbG9zZSBicm93c2VyIGltbWVkaWF0ZWx5IGluc3RlYWQgb2YgcmV0dXJuaW5nIHRvIHBvb2xcbiAgICBpZiAodGhpcy5vcHRpb25zLmlkbGVUaW1lb3V0IDw9IDApIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQnJvd3NlciAke2Jyb3dzZXIuaWR9IHJlbGVhc2VkIHdpdGggaWRsZVRpbWVvdXQ9MCwgY2xvc2luZyBpbW1lZGlhdGVseWApO1xuICAgICAgYXdhaXQgdGhpcy5yZW1vdmVCcm93c2VyRnJvbVBvb2woYnJvd3Nlci5pZCk7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBicm93c2VyIHNob3VsZCBiZSByZXRpcmVkIGR1ZSB0byBhZ2Ugb3IgdXNhZ2VcbiAgICBjb25zdCBzaG91bGRSZXRpcmUgPSB0aGlzLnNob3VsZFJldGlyZUJyb3dzZXIobWFuYWdlZEJyb3dzZXIpO1xuICAgIGlmIChzaG91bGRSZXRpcmUpIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBSZXRpcmluZyBicm93c2VyICR7YnJvd3Nlci5pZH0gZHVlIHRvICR7c2hvdWxkUmV0aXJlfWApO1xuICAgICAgYXdhaXQgdGhpcy5yZW1vdmVCcm93c2VyRnJvbVBvb2woYnJvd3Nlci5pZCk7XG5cbiAgICAgIC8vIEVuc3VyZSB3ZSBtYWludGFpbiBtaW5pbXVtIGluc3RhbmNlc1xuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVNaW5pbXVtSW5zdGFuY2VzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUGVyZm9ybSBoZWFsdGggY2hlY2sgYmVmb3JlIHJldHVybmluZyB0byBwb29sXG4gICAgY29uc3QgaXNIZWFsdGh5ID0gYXdhaXQgdGhpcy5jaGVja0Jyb3dzZXJIZWFsdGgobWFuYWdlZEJyb3dzZXIpO1xuICAgIGlmICghaXNIZWFsdGh5KSB7XG4gICAgICBsb2dnZXIud2FybihgQnJvd3NlciAke2Jyb3dzZXIuaWR9IGZhaWxlZCBoZWFsdGggY2hlY2ssIHJlbW92aW5nIGZyb20gcG9vbGApO1xuICAgICAgYXdhaXQgdGhpcy5yZW1vdmVCcm93c2VyRnJvbVBvb2woYnJvd3Nlci5pZCk7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gdG8gcG9vbFxuICAgIG1hbmFnZWRCcm93c2VyLmlzQXZhaWxhYmxlID0gdHJ1ZTtcbiAgICBtYW5hZ2VkQnJvd3Nlci5pc0hlYWx0aHkgPSB0cnVlO1xuXG4gICAgbG9nZ2VyLmRlYnVnKGBSZWxlYXNlZCBicm93c2VyICR7YnJvd3Nlci5pZH0gYmFjayB0byBwb29sYCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgcG9vbCBzdGF0aXN0aWNzXG4gICAqL1xuICBnZXRQb29sU3RhdHMoKTogQnJvd3NlclBvb2xTdGF0cyB7XG4gICAgY29uc3QgaW5zdGFuY2VzID0gQXJyYXkuZnJvbSh0aGlzLnBvb2wudmFsdWVzKCkpO1xuICAgIGNvbnN0IGF2YWlsYWJsZUluc3RhbmNlcyA9IGluc3RhbmNlcy5maWx0ZXIoKGIpID0+IGIuaXNBdmFpbGFibGUgJiYgYi5pc0hlYWx0aHkpLmxlbmd0aDtcbiAgICBjb25zdCBidXN5SW5zdGFuY2VzID0gaW5zdGFuY2VzLmZpbHRlcigoYikgPT4gIWIuaXNBdmFpbGFibGUpLmxlbmd0aDtcbiAgICBjb25zdCB1bmhlYWx0aHlJbnN0YW5jZXMgPSBpbnN0YW5jZXMuZmlsdGVyKChiKSA9PiAhYi5pc0hlYWx0aHkpLmxlbmd0aDtcbiAgICBjb25zdCB0b3RhbFVzYWdlID0gaW5zdGFuY2VzLnJlZHVjZSgoc3VtLCBiKSA9PiBzdW0gKyBiLnVzYWdlQ291bnQsIDApO1xuXG4gICAgY29uc3QgYWdlcyA9IGluc3RhbmNlcy5tYXAoKGIpID0+IERhdGUubm93KCkgLSBiLmNyZWF0ZWRBdC5nZXRUaW1lKCkpO1xuICAgIGNvbnN0IGF2ZXJhZ2VBZ2UgPSBhZ2VzLmxlbmd0aCA+IDAgPyBhZ2VzLnJlZHVjZSgoc3VtLCBhZ2UpID0+IHN1bSArIGFnZSwgMCkgLyBhZ2VzLmxlbmd0aCA6IDA7XG5cbiAgICBjb25zdCBvbGRlc3RJbnN0YW5jZSA9XG4gICAgICBpbnN0YW5jZXMubGVuZ3RoID4gMFxuICAgICAgICA/IGluc3RhbmNlcy5yZWR1Y2UoKG9sZGVzdCwgY3VycmVudCkgPT5cbiAgICAgICAgICAgIGN1cnJlbnQuY3JlYXRlZEF0IDwgb2xkZXN0LmNyZWF0ZWRBdCA/IGN1cnJlbnQgOiBvbGRlc3RcbiAgICAgICAgICApLmNyZWF0ZWRBdFxuICAgICAgICA6IG51bGw7XG5cbiAgICBjb25zdCBuZXdlc3RJbnN0YW5jZSA9XG4gICAgICBpbnN0YW5jZXMubGVuZ3RoID4gMFxuICAgICAgICA/IGluc3RhbmNlcy5yZWR1Y2UoKG5ld2VzdCwgY3VycmVudCkgPT5cbiAgICAgICAgICAgIGN1cnJlbnQuY3JlYXRlZEF0ID4gbmV3ZXN0LmNyZWF0ZWRBdCA/IGN1cnJlbnQgOiBuZXdlc3RcbiAgICAgICAgICApLmNyZWF0ZWRBdFxuICAgICAgICA6IG51bGw7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG90YWxJbnN0YW5jZXM6IGluc3RhbmNlcy5sZW5ndGgsXG4gICAgICBhdmFpbGFibGVJbnN0YW5jZXMsXG4gICAgICBidXN5SW5zdGFuY2VzLFxuICAgICAgdW5oZWFsdGh5SW5zdGFuY2VzLFxuICAgICAgdG90YWxVc2FnZSxcbiAgICAgIGF2ZXJhZ2VBZ2UsXG4gICAgICBvbGRlc3RJbnN0YW5jZSxcbiAgICAgIG5ld2VzdEluc3RhbmNlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW51cCBhbmQgc2h1dGRvd24gdGhlIGJyb3dzZXIgcG9vbFxuICAgKi9cbiAgYXN5bmMgY2xlYW51cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmlzU2h1dHRpbmdEb3duID0gdHJ1ZTtcblxuICAgIC8vIFN0b3AgbW9uaXRvcmluZyB0aW1lcnNcbiAgICBpZiAodGhpcy5oZWFsdGhDaGVja1RpbWVyKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMuaGVhbHRoQ2hlY2tUaW1lcik7XG4gICAgICB0aGlzLmhlYWx0aENoZWNrVGltZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNsZWFudXBUaW1lcikge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmNsZWFudXBUaW1lcik7XG4gICAgICB0aGlzLmNsZWFudXBUaW1lciA9IG51bGw7XG4gICAgfVxuXG4gICAgLy8gQ2xvc2UgYWxsIGJyb3dzZXJzXG4gICAgY29uc3QgY2xvc2VQcm9taXNlcyA9IEFycmF5LmZyb20odGhpcy5wb29sLnZhbHVlcygpKS5tYXAoYXN5bmMgKG1hbmFnZWRCcm93c2VyKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBtYW5hZ2VkQnJvd3Nlci5icm93c2VyLmNsb3NlKCk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgQ2xvc2VkIGJyb3dzZXIgJHttYW5hZ2VkQnJvd3Nlci5pZH1gKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBFcnJvciBjbG9zaW5nIGJyb3dzZXIgJHttYW5hZ2VkQnJvd3Nlci5pZH06ICR7ZXJyb3J9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoY2xvc2VQcm9taXNlcyk7XG4gICAgdGhpcy5wb29sLmNsZWFyKCk7XG5cbiAgICBsb2dnZXIuaW5mbygnQnJvd3NlciBwb29sIGNsZWFudXAgY29tcGxldGVkJyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGJyb3dzZXIgaW5zdGFuY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY3JlYXRlQnJvd3Nlckluc3RhbmNlKCk6IFByb21pc2U8TWFuYWdlZEJyb3dzZXI+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbGF1bmNoT3B0aW9uczogYW55ID0ge1xuICAgICAgICBoZWFkbGVzczogdGhpcy5jb25maWcuYnJvd3Nlci5oZWFkbGVzc0RlZmF1bHQsXG4gICAgICAgIHNsb3dNbzogdGhpcy5jb25maWcuYnJvd3Nlci5zbG93bW8sXG4gICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICAnLS1uby1zYW5kYm94JyxcbiAgICAgICAgICAnLS1kaXNhYmxlLXNldHVpZC1zYW5kYm94JyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWRldi1zaG0tdXNhZ2UnLFxuICAgICAgICAgICctLWRpc2FibGUtYWNjZWxlcmF0ZWQtMmQtY2FudmFzJyxcbiAgICAgICAgICAnLS1uby1maXJzdC1ydW4nLFxuICAgICAgICAgICctLW5vLXp5Z290ZScsXG4gICAgICAgICAgJy0tZGlzYWJsZS1ncHUnLFxuICAgICAgICAgICctLWRpc2FibGUtYmFja2dyb3VuZC10aW1lci10aHJvdHRsaW5nJyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWJhY2tncm91bmRpbmctb2NjbHVkZWQtd2luZG93cycsXG4gICAgICAgICAgJy0tZGlzYWJsZS1yZW5kZXJlci1iYWNrZ3JvdW5kaW5nJyxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGJyb3dzZXIgPSBhd2FpdCBwdXBwZXRlZXIubGF1bmNoKGxhdW5jaE9wdGlvbnMpO1xuICAgICAgY29uc3QgY29udGV4dCA9IGF3YWl0IGJyb3dzZXIuY3JlYXRlQnJvd3NlckNvbnRleHQoKTtcblxuICAgICAgY29uc3QgaWQgPSB0aGlzLmdlbmVyYXRlQnJvd3NlcklkKCk7XG4gICAgICBjb25zdCBtYW5hZ2VkQnJvd3NlcjogTWFuYWdlZEJyb3dzZXIgPSB7XG4gICAgICAgIGJyb3dzZXIsXG4gICAgICAgIGNvbnRleHQsXG4gICAgICAgIGlkLFxuICAgICAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIGxhc3RVc2VkOiBuZXcgRGF0ZSgpLFxuICAgICAgICBpc0F2YWlsYWJsZTogdHJ1ZSxcbiAgICAgICAgaXNIZWFsdGh5OiB0cnVlLFxuICAgICAgICB1c2FnZUNvdW50OiAwLFxuICAgICAgfTtcblxuICAgICAgdGhpcy5wb29sLnNldChpZCwgbWFuYWdlZEJyb3dzZXIpO1xuXG4gICAgICAvLyBTZXQgdXAgYnJvd3NlciBldmVudCBoYW5kbGVyc1xuICAgICAgYnJvd3Nlci5vbignZGlzY29ubmVjdGVkJywgKCkgPT4ge1xuICAgICAgICBsb2dnZXIud2FybihgQnJvd3NlciAke2lkfSBkaXNjb25uZWN0ZWQgdW5leHBlY3RlZGx5YCk7XG4gICAgICAgIHRoaXMuaGFuZGxlQnJvd3NlckRpc2Nvbm5lY3Rpb24oaWQpO1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBtYW5hZ2VkQnJvd3NlcjtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGJyb3dzZXIgaW5zdGFuY2U6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgQnJvd3NlckxhdW5jaEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGNyZWF0ZSBicm93c2VyIGluc3RhbmNlOiAke2Vycm9yfWAsXG4gICAgICAgIHsgcG9vbFNpemU6IHRoaXMucG9vbC5zaXplIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGFuIGF2YWlsYWJsZSBoZWFsdGh5IGJyb3dzZXIgaW4gdGhlIHBvb2xcbiAgICovXG4gIHByaXZhdGUgZmluZEF2YWlsYWJsZUJyb3dzZXIoKTogTWFuYWdlZEJyb3dzZXIgfCBudWxsIHtcbiAgICBmb3IgKGNvbnN0IGJyb3dzZXIgb2YgdGhpcy5wb29sLnZhbHVlcygpKSB7XG4gICAgICBpZiAoYnJvd3Nlci5pc0F2YWlsYWJsZSAmJiBicm93c2VyLmlzSGVhbHRoeSkge1xuICAgICAgICByZXR1cm4gYnJvd3NlcjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBicm93c2VyIHNob3VsZCBiZSByZXRpcmVkXG4gICAqL1xuICBwcml2YXRlIHNob3VsZFJldGlyZUJyb3dzZXIoYnJvd3NlcjogTWFuYWdlZEJyb3dzZXIpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBjb25zdCBhZ2UgPSBEYXRlLm5vdygpIC0gYnJvd3Nlci5jcmVhdGVkQXQuZ2V0VGltZSgpO1xuXG4gICAgaWYgKGFnZSA+IHRoaXMub3B0aW9ucy5tYXhBZ2UpIHtcbiAgICAgIHJldHVybiAnbWF4IGFnZSBleGNlZWRlZCc7XG4gICAgfVxuXG4gICAgaWYgKGJyb3dzZXIudXNhZ2VDb3VudCA+PSB0aGlzLm9wdGlvbnMubWF4VXNhZ2VDb3VudCkge1xuICAgICAgcmV0dXJuICdtYXggdXNhZ2UgY291bnQgZXhjZWVkZWQnO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gaGVhbHRoIGNoZWNrIG9uIGEgYnJvd3NlciBpbnN0YW5jZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjaGVja0Jyb3dzZXJIZWFsdGgoYnJvd3NlcjogTWFuYWdlZEJyb3dzZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0cnkge1xuICAgICAgLy8gQ2hlY2sgaWYgYnJvd3NlciBpcyBjb25uZWN0ZWRcbiAgICAgIGlmICghYnJvd3Nlci5icm93c2VyLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBUcnkgdG8gY3JlYXRlIGFuZCBjbG9zZSBhIHRlc3QgcGFnZVxuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IGJyb3dzZXIuY29udGV4dC5uZXdQYWdlKCk7XG4gICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZGVidWcoYEJyb3dzZXIgJHticm93c2VyLmlkfSBoZWFsdGggY2hlY2sgZmFpbGVkOiAke2Vycm9yfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYSBicm93c2VyIGZyb20gdGhlIHBvb2xcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVtb3ZlQnJvd3NlckZyb21Qb29sKGJyb3dzZXJJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYnJvd3NlciA9IHRoaXMucG9vbC5nZXQoYnJvd3NlcklkKTtcbiAgICBpZiAoIWJyb3dzZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgYnJvd3Nlci5icm93c2VyLmNsb3NlKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBFcnJvciBjbG9zaW5nIGJyb3dzZXIgJHticm93c2VySWR9OiAke2Vycm9yfWApO1xuICAgIH1cblxuICAgIHRoaXMucG9vbC5kZWxldGUoYnJvd3NlcklkKTtcbiAgICBsb2dnZXIuZGVidWcoYFJlbW92ZWQgYnJvd3NlciAke2Jyb3dzZXJJZH0gZnJvbSBwb29sYCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIGJyb3dzZXIgZGlzY29ubmVjdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVCcm93c2VyRGlzY29ubmVjdGlvbihicm93c2VySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJyb3dzZXIgPSB0aGlzLnBvb2wuZ2V0KGJyb3dzZXJJZCk7XG4gICAgaWYgKGJyb3dzZXIpIHtcbiAgICAgIGJyb3dzZXIuaXNIZWFsdGh5ID0gZmFsc2U7XG4gICAgICBicm93c2VyLmlzQXZhaWxhYmxlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIHRoZSBkaXNjb25uZWN0ZWQgYnJvd3NlciBhbmQgZW5zdXJlIG1pbmltdW0gaW5zdGFuY2VzXG4gICAgYXdhaXQgdGhpcy5yZW1vdmVCcm93c2VyRnJvbVBvb2woYnJvd3NlcklkKTtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZU1pbmltdW1JbnN0YW5jZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmUgbWluaW11bSBudW1iZXIgb2YgaW5zdGFuY2VzIGFyZSBhdmFpbGFibGVcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlTWluaW11bUluc3RhbmNlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pc1NodXR0aW5nRG93bikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhlYWx0aHlDb3VudCA9IEFycmF5LmZyb20odGhpcy5wb29sLnZhbHVlcygpKS5maWx0ZXIoKGIpID0+IGIuaXNIZWFsdGh5KS5sZW5ndGg7XG5cbiAgICBjb25zdCBuZWVkZWQgPSB0aGlzLm9wdGlvbnMubWluSW5zdGFuY2VzIC0gaGVhbHRoeUNvdW50O1xuXG4gICAgaWYgKG5lZWRlZCA+IDApIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBDcmVhdGluZyAke25lZWRlZH0gYnJvd3NlciBpbnN0YW5jZXMgdG8gbWFpbnRhaW4gbWluaW11bSBwb29sIHNpemVgKTtcblxuICAgICAgY29uc3QgY3JlYXRlUHJvbWlzZXMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBuZWVkZWQgfSwgKCkgPT5cbiAgICAgICAgdGhpcy5jcmVhdGVCcm93c2VySW5zdGFuY2UoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgYnJvd3NlciBmb3IgbWluaW11bSBpbnN0YW5jZXM6ICR7ZXJyb3J9YCk7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoY3JlYXRlUHJvbWlzZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY291bnQgb2YgYXZhaWxhYmxlIGJyb3dzZXJzXG4gICAqL1xuICBwcml2YXRlIGdldEF2YWlsYWJsZUNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5wb29sLnZhbHVlcygpKS5maWx0ZXIoKGIpID0+IGIuaXNBdmFpbGFibGUgJiYgYi5pc0hlYWx0aHkpLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBoZWFsdGggbW9uaXRvcmluZ1xuICAgKi9cbiAgcHJpdmF0ZSBzdGFydEhlYWx0aE1vbml0b3JpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5oZWFsdGhDaGVja1RpbWVyID0gc2V0SW50ZXJ2YWwoYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNTaHV0dGluZ0Rvd24pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB1bmhlYWx0aHlCcm93c2Vyczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBbaWQsIGJyb3dzZXJdIG9mIHRoaXMucG9vbC5lbnRyaWVzKCkpIHtcbiAgICAgICAgaWYgKCFicm93c2VyLmlzQXZhaWxhYmxlKSB7XG4gICAgICAgICAgY29udGludWU7IC8vIFNraXAgYnJvd3NlcnMgY3VycmVudGx5IGluIHVzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNIZWFsdGh5ID0gYXdhaXQgdGhpcy5jaGVja0Jyb3dzZXJIZWFsdGgoYnJvd3Nlcik7XG4gICAgICAgIGlmICghaXNIZWFsdGh5KSB7XG4gICAgICAgICAgdW5oZWFsdGh5QnJvd3NlcnMucHVzaChpZCk7XG4gICAgICAgICAgYnJvd3Nlci5pc0hlYWx0aHkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBSZW1vdmUgdW5oZWFsdGh5IGJyb3dzZXJzXG4gICAgICBmb3IgKGNvbnN0IGlkIG9mIHVuaGVhbHRoeUJyb3dzZXJzKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBSZW1vdmluZyB1bmhlYWx0aHkgYnJvd3NlciAke2lkfSBkdXJpbmcgaGVhbHRoIGNoZWNrYCk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGlkKTtcbiAgICAgIH1cblxuICAgICAgLy8gRW5zdXJlIG1pbmltdW0gaW5zdGFuY2VzIGFmdGVyIGNsZWFudXBcbiAgICAgIGlmICh1bmhlYWx0aHlCcm93c2Vycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZW5zdXJlTWluaW11bUluc3RhbmNlcygpO1xuICAgICAgfVxuICAgIH0sIHRoaXMub3B0aW9ucy5oZWFsdGhDaGVja0ludGVydmFsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBjbGVhbnVwIG1vbml0b3JpbmcgZm9yIGlkbGUgYW5kIHN0dWNrIGJyb3dzZXJzXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0Q2xlYW51cE1vbml0b3JpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhbnVwVGltZXIgPSBzZXRJbnRlcnZhbChhc3luYyAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5pc1NodXR0aW5nRG93bikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBjb25zdCBicm93c2Vyc1RvUmVtb3ZlOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IFtpZCwgYnJvd3Nlcl0gb2YgdGhpcy5wb29sLmVudHJpZXMoKSkge1xuICAgICAgICBjb25zdCBpZGxlVGltZSA9IG5vdyAtIGJyb3dzZXIubGFzdFVzZWQuZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCBzaG91bGRSZXRpcmUgPSB0aGlzLnNob3VsZFJldGlyZUJyb3dzZXIoYnJvd3Nlcik7XG5cbiAgICAgICAgLy8gQWxzbyBjaGVjayBzdHVjayBicm93c2VycyAoYnVzeSBidXQgc3R1Y2sgdGltZW91dCBleGNlZWRlZClcbiAgICAgICAgLy8gVGhlc2UgYXJlIHVzdWFsbHkgY2F1c2VkIGJ5IHVuaGFuZGxlZCBleGNlcHRpb25zIHByZXZlbnRpbmcgcmVsZWFzZUJyb3dzZXIgZnJvbSBiZWluZyBjYWxsZWRcbiAgICAgICAgY29uc3QgaXNTdHVjayA9ICFicm93c2VyLmlzQXZhaWxhYmxlICYmIGlkbGVUaW1lID4gdGhpcy5vcHRpb25zLnN0dWNrVGltZW91dDtcblxuICAgICAgICBpZiAoaWRsZVRpbWUgPiB0aGlzLm9wdGlvbnMuaWRsZVRpbWVvdXQgfHwgc2hvdWxkUmV0aXJlIHx8IGlzU3R1Y2spIHtcbiAgICAgICAgICBjb25zdCBoZWFsdGh5Q291bnQgPSBBcnJheS5mcm9tKHRoaXMucG9vbC52YWx1ZXMoKSkuZmlsdGVyKChiKSA9PiBiLmlzSGVhbHRoeSkubGVuZ3RoO1xuXG4gICAgICAgICAgLy8gRm9yY2UgcmVtb3ZhbCBmb3Igc3R1Y2sgYnJvd3NlcnMgKGRvbid0IGNoZWNrIG1pbmltdW0gaW5zdGFuY2UgY291bnQpXG4gICAgICAgICAgLy8gT3RoZXJ3aXNlIG9ubHkgcmVtb3ZlIGlmIGFib3ZlIG1pbmltdW0gaW5zdGFuY2VzXG4gICAgICAgICAgaWYgKGlzU3R1Y2sgfHwgaGVhbHRoeUNvdW50ID4gdGhpcy5vcHRpb25zLm1pbkluc3RhbmNlcykge1xuICAgICAgICAgICAgYnJvd3NlcnNUb1JlbW92ZS5wdXNoKGlkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gUmVtb3ZlIGlkbGUvb2xkL3N0dWNrIGJyb3dzZXJzXG4gICAgICBmb3IgKGNvbnN0IGlkIG9mIGJyb3dzZXJzVG9SZW1vdmUpIHtcbiAgICAgICAgY29uc3QgYnJvd3NlciA9IHRoaXMucG9vbC5nZXQoaWQpO1xuICAgICAgICBjb25zdCBpc1N0dWNrID0gYnJvd3NlciAmJiAhYnJvd3Nlci5pc0F2YWlsYWJsZTtcbiAgICAgICAgY29uc3QgcmVhc29uID0gdGhpcy5zaG91bGRSZXRpcmVCcm93c2VyKGJyb3dzZXIhKSB8fCAoaXNTdHVjayA/ICdzdHVjayBicm93c2VyIHRpbWVvdXQnIDogJ2lkbGUgdGltZW91dCcpO1xuICAgICAgICBsb2dnZXIuaW5mbyhgUmVtb3ZpbmcgYnJvd3NlciAke2lkfSBkdWUgdG8gJHtyZWFzb259YCk7XG5cbiAgICAgICAgLy8gRm9yIHN0dWNrIGJyb3dzZXJzLCB0cnkgdG8gY2xvc2UgYW55IG9wZW4gcGFnZXMgZmlyc3RcbiAgICAgICAgaWYgKGlzU3R1Y2sgJiYgYnJvd3Nlcikge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwYWdlcyA9IGF3YWl0IGJyb3dzZXIuY29udGV4dC5wYWdlcygpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBwIG9mIHBhZ2VzKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKCFwLmlzQ2xvc2VkKCkpIHtcbiAgICAgICAgICAgICAgICAgIGF3YWl0IHAuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBpZ25vcmVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIGlnbm9yZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlQnJvd3NlckZyb21Qb29sKGlkKTtcbiAgICAgIH1cblxuICAgICAgLy8gRW5zdXJlIG1pbmltdW0gaW5zdGFuY2VzIGFmdGVyIGNsZWFudXAgb25seSBpZiBicm93c2VycyB3ZXJlIHJlbW92ZWRcbiAgICAgIGlmIChicm93c2Vyc1RvUmVtb3ZlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5lbnN1cmVNaW5pbXVtSW5zdGFuY2VzKCk7XG4gICAgICB9XG4gICAgfSwgdGhpcy5vcHRpb25zLmhlYWx0aENoZWNrSW50ZXJ2YWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHVuaXF1ZSBicm93c2VyIElEXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlQnJvd3NlcklkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBicm93c2VyXyR7RGF0ZS5ub3coKX1fJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMiwgMTEpfWA7XG4gIH1cbn1cblxuLy8gR2xvYmFsIGJyb3dzZXIgcG9vbCBpbnN0YW5jZVxubGV0IGdsb2JhbEJyb3dzZXJQb29sOiBCcm93c2VyUG9vbFNlcnZpY2UgfCBudWxsID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJyb3dzZXJQb29sKCk6IEJyb3dzZXJQb29sU2VydmljZSB7XG4gIGlmICghZ2xvYmFsQnJvd3NlclBvb2wpIHtcbiAgICBnbG9iYWxCcm93c2VyUG9vbCA9IG5ldyBCcm93c2VyUG9vbFNlcnZpY2UoKTtcbiAgfVxuICByZXR1cm4gZ2xvYmFsQnJvd3NlclBvb2w7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbGVhbnVwQnJvd3NlclBvb2woKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChnbG9iYWxCcm93c2VyUG9vbCkge1xuICAgIGF3YWl0IGdsb2JhbEJyb3dzZXJQb29sLmNsZWFudXAoKTtcbiAgICBnbG9iYWxCcm93c2VyUG9vbCA9IG51bGw7XG4gIH1cbn1cbiIsIi8qKlxuICogQnJvd3NlciBNYW5hZ2VyIGZvciBYSFMgT3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCBwdXBwZXRlZXIsIHsgQnJvd3NlciwgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBDb25maWcsIENvb2tpZSB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBCcm93c2VyTGF1bmNoRXJyb3IsIEJyb3dzZXJOYXZpZ2F0aW9uRXJyb3IsIFhIU0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IGxvYWRDb29raWVzLCBzYXZlQ29va2llcyB9IGZyb20gJy4uLy4uL3NoYXJlZC9jb29raWVzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgQnJvd3NlclBvb2xTZXJ2aWNlLCBNYW5hZ2VkQnJvd3NlciwgQnJvd3NlclBvb2xPcHRpb25zIH0gZnJvbSAnLi9icm93c2VyLXBvb2wuc2VydmljZSc7XG5cbmV4cG9ydCBjbGFzcyBCcm93c2VyTWFuYWdlciB7XG4gIHByaXZhdGUgY29uZmlnOiBDb25maWc7XG4gIHByaXZhdGUgYnJvd3NlcjogQnJvd3NlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGJyb3dzZXJQb29sOiBCcm93c2VyUG9vbFNlcnZpY2UgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB1c2VQb29sOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgcG9vbE9wdGlvbnM/OiBCcm93c2VyUG9vbE9wdGlvbnM7XG4gIHByaXZhdGUgdHJhY2tlZFBhZ2VzOiBTZXQ8UGFnZT4gPSBuZXcgU2V0KCk7XG4gIHByaXZhdGUgbWF4VHJhY2tlZFBhZ2VzOiBudW1iZXIgPSAxMDtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc/OiBDb25maWcsIHVzZVBvb2w6IGJvb2xlYW4gPSBmYWxzZSwgcG9vbE9wdGlvbnM/OiBCcm93c2VyUG9vbE9wdGlvbnMpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCBnZXRDb25maWcoKTtcbiAgICB0aGlzLnVzZVBvb2wgPSB1c2VQb29sO1xuICAgIHRoaXMucG9vbE9wdGlvbnMgPSBwb29sT3B0aW9ucztcblxuICAgIGlmICh0aGlzLnVzZVBvb2wpIHtcbiAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBuZXcgQnJvd3NlclBvb2xTZXJ2aWNlKHRoaXMuY29uZmlnLCBwb29sT3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY3JlYXRlUGFnZShcbiAgICBoZWFkbGVzcz86IGJvb2xlYW4sXG4gICAgZXhlY3V0YWJsZVBhdGg/OiBzdHJpbmcsXG4gICAgc2hvdWxkTG9hZENvb2tpZXM6IGJvb2xlYW4gPSB0cnVlXG4gICk6IFByb21pc2U8UGFnZT4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBVc2UgYnJvd3NlciBwb29sIGlmIGVuYWJsZWRcbiAgICAgIGlmICh0aGlzLnVzZVBvb2wgJiYgdGhpcy5icm93c2VyUG9vbCkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jcmVhdGVQYWdlRnJvbVBvb2woc2hvdWxkTG9hZENvb2tpZXMpO1xuICAgICAgfVxuXG4gICAgICAvLyBGYWxsYmFjayB0byB0cmFkaXRpb25hbCBicm93c2VyIG1hbmFnZW1lbnRcbiAgICAgIC8vIExhdW5jaCBicm93c2VyIGlmIG5vdCBhbHJlYWR5IGxhdW5jaGVkXG4gICAgICBpZiAoIXRoaXMuYnJvd3Nlcikge1xuICAgICAgICB0aGlzLmJyb3dzZXIgPSBhd2FpdCB0aGlzLmxhdW5jaEJyb3dzZXIoaGVhZGxlc3MsIGV4ZWN1dGFibGVQYXRoKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ3JlYXRlIG5ldyBwYWdlXG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5icm93c2VyLm5ld1BhZ2UoKTtcblxuICAgICAgLy8gVHJhY2sgcGFnZSBmb3IgY2xlYW51cFxuICAgICAgdGhpcy50cmFja2VkUGFnZXMuYWRkKHBhZ2UpO1xuICAgICAgcGFnZS5vbmNlKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgdGhpcy50cmFja2VkUGFnZXMuZGVsZXRlKHBhZ2UpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEF1dG8tY2xlYW51cCBpZiB0b28gbWFueSBwYWdlcyBhcmUgb3BlbiAobGVhayBkZXRlY3Rpb24pXG4gICAgICBpZiAodGhpcy50cmFja2VkUGFnZXMuc2l6ZSA+IHRoaXMubWF4VHJhY2tlZFBhZ2VzKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBUcmFja2VkIHBhZ2VzICgke3RoaXMudHJhY2tlZFBhZ2VzLnNpemV9KSBleGNlZWRzIHRocmVzaG9sZCAoJHt0aGlzLm1heFRyYWNrZWRQYWdlc30pLCBmb3JjaW5nIGNsZWFudXBgKTtcbiAgICAgICAgYXdhaXQgdGhpcy5jbG9zZUFsbFBhZ2VzKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIENvbmZpZ3VyZSBwYWdlIHRpbWVvdXRzXG4gICAgICBwYWdlLnNldERlZmF1bHRUaW1lb3V0KHRoaXMuY29uZmlnLmJyb3dzZXIuZGVmYXVsdFRpbWVvdXQpO1xuICAgICAgcGFnZS5zZXREZWZhdWx0TmF2aWdhdGlvblRpbWVvdXQodGhpcy5jb25maWcuYnJvd3Nlci5uYXZpZ2F0aW9uVGltZW91dCk7XG5cbiAgICAgIC8vIExvYWQgY29va2llcyBpZiByZXF1ZXN0ZWRcbiAgICAgIGlmIChzaG91bGRMb2FkQ29va2llcykge1xuICAgICAgICBhd2FpdCB0aGlzLmxvYWRDb29raWVzSW50b1BhZ2UocGFnZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYWdlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEJyb3dzZXIgcGFnZSBjcmVhdGlvbiBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IHRoaXMuaGFuZGxlUHVwcGV0ZWVyRXJyb3IoZXJyb3IgYXMgRXJyb3IsICdjcmVhdGVfcGFnZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBwYWdlIHVzaW5nIHRoZSBicm93c2VyIHBvb2xcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY3JlYXRlUGFnZUZyb21Qb29sKHNob3VsZExvYWRDb29raWVzOiBib29sZWFuID0gdHJ1ZSk6IFByb21pc2U8UGFnZT4ge1xuICAgIGlmICghdGhpcy5icm93c2VyUG9vbCkge1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKCdCcm93c2VyIHBvb2wgbm90IGluaXRpYWxpemVkJywgJ0Jyb3dzZXJQb29sRXJyb3InKTtcbiAgICB9XG5cbiAgICBjb25zdCBtYW5hZ2VkQnJvd3NlciA9IGF3YWl0IHRoaXMuYnJvd3NlclBvb2wuYWNxdWlyZUJyb3dzZXIoKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBDcmVhdGUgbmV3IHBhZ2UgZnJvbSB0aGUgbWFuYWdlZCBicm93c2VyIGNvbnRleHRcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBtYW5hZ2VkQnJvd3Nlci5jb250ZXh0Lm5ld1BhZ2UoKTtcblxuICAgICAgLy8gQ29uZmlndXJlIHBhZ2UgdGltZW91dHNcbiAgICAgIHBhZ2Uuc2V0RGVmYXVsdFRpbWVvdXQodGhpcy5jb25maWcuYnJvd3Nlci5kZWZhdWx0VGltZW91dCk7XG4gICAgICBwYWdlLnNldERlZmF1bHROYXZpZ2F0aW9uVGltZW91dCh0aGlzLmNvbmZpZy5icm93c2VyLm5hdmlnYXRpb25UaW1lb3V0KTtcblxuICAgICAgLy8gTG9hZCBjb29raWVzIGlmIHJlcXVlc3RlZFxuICAgICAgaWYgKHNob3VsZExvYWRDb29raWVzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMubG9hZENvb2tpZXNJbnRvUGFnZShwYWdlKTtcbiAgICAgIH1cblxuICAgICAgLy8gU3RvcmUgcmVmZXJlbmNlIHRvIG1hbmFnZWQgYnJvd3NlciBmb3IgY2xlYW51cFxuICAgICAgKHBhZ2UgYXMgUGFnZSAmIHsgX21hbmFnZWRCcm93c2VyPzogTWFuYWdlZEJyb3dzZXIgfSkuX21hbmFnZWRCcm93c2VyID0gbWFuYWdlZEJyb3dzZXI7XG5cbiAgICAgIC8vIFNldCB1cCBwYWdlIGNsb3NlIGhhbmRsZXIgdG8gcmVsZWFzZSBicm93c2VyIGJhY2sgdG8gcG9vbFxuICAgICAgbGV0IHJlbGVhc2VkID0gZmFsc2U7XG4gICAgICBjb25zdCByZWxlYXNlQnJvd3NlciA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKHJlbGVhc2VkKSByZXR1cm47XG4gICAgICAgIHJlbGVhc2VkID0gdHJ1ZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmJyb3dzZXJQb29sIS5yZWxlYXNlQnJvd3NlcihtYW5hZ2VkQnJvd3Nlcik7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIHJlbGVhc2luZyBicm93c2VyIGJhY2sgdG8gcG9vbDogJHtlcnJvcn1gKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgcGFnZS5vbmNlKCdjbG9zZScsIHJlbGVhc2VCcm93c2VyKTtcblxuICAgICAgcmV0dXJuIHBhZ2U7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIFJlbGVhc2UgYnJvd3NlciBiYWNrIHRvIHBvb2wgb24gZXJyb3JcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYnJvd3NlclBvb2wucmVsZWFzZUJyb3dzZXIobWFuYWdlZEJyb3dzZXIpO1xuICAgICAgfSBjYXRjaCAocmVsZWFzZUVycm9yKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBFcnJvciByZWxlYXNpbmcgYnJvd3NlciBhZnRlciBwYWdlIGNyZWF0aW9uIGZhaWx1cmU6ICR7cmVsZWFzZUVycm9yfWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBsYXVuY2hCcm93c2VyKGhlYWRsZXNzPzogYm9vbGVhbiwgZXhlY3V0YWJsZVBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPEJyb3dzZXI+IHtcbiAgICBjb25zdCBpc0hlYWRsZXNzID0gaGVhZGxlc3MgPz8gdGhpcy5jb25maWcuYnJvd3Nlci5oZWFkbGVzc0RlZmF1bHQ7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbGF1bmNoT3B0aW9uczogYW55ID0ge1xuICAgICAgICBoZWFkbGVzczogaXNIZWFkbGVzcyxcbiAgICAgICAgc2xvd01vOiB0aGlzLmNvbmZpZy5icm93c2VyLnNsb3dtbyxcbiAgICAgICAgYXJnczogW1xuICAgICAgICAgICctLW5vLXNhbmRib3gnLFxuICAgICAgICAgICctLWRpc2FibGUtc2V0dWlkLXNhbmRib3gnLFxuICAgICAgICAgICctLWRpc2FibGUtZGV2LXNobS11c2FnZScsXG4gICAgICAgICAgJy0tZGlzYWJsZS1hY2NlbGVyYXRlZC0yZC1jYW52YXMnLFxuICAgICAgICAgICctLW5vLWZpcnN0LXJ1bicsXG4gICAgICAgICAgJy0tbm8tenlnb3RlJyxcbiAgICAgICAgICAnLS1kaXNhYmxlLWdwdScsXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBpZiAoZXhlY3V0YWJsZVBhdGgpIHtcbiAgICAgICAgbGF1bmNoT3B0aW9ucy5leGVjdXRhYmxlUGF0aCA9IGV4ZWN1dGFibGVQYXRoO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaChsYXVuY2hPcHRpb25zKTtcblxuICAgICAgcmV0dXJuIGJyb3dzZXI7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGxhdW5jaCBicm93c2VyOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IEJyb3dzZXJMYXVuY2hFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBsYXVuY2ggYnJvd3NlcjogJHtlcnJvcn1gLFxuICAgICAgICB7IGhlYWRsZXNzOiBpc0hlYWRsZXNzLCBleGVjdXRhYmxlUGF0aCB9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRDb29raWVzSW50b1BhZ2UocGFnZTogUGFnZSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb29raWVzID0gbG9hZENvb2tpZXMoKTtcblxuICAgICAgaWYgKCFjb29raWVzKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gQ29udmVydCBvdXIgY29va2llIGZvcm1hdCB0byBQdXBwZXRlZXIgZm9ybWF0XG4gICAgICBjb25zdCBwdXBwZXRlZXJDb29raWVzID0gY29va2llcy5tYXAoKGNvb2tpZSkgPT4gKHtcbiAgICAgICAgbmFtZTogY29va2llLm5hbWUsXG4gICAgICAgIHZhbHVlOiBjb29raWUudmFsdWUsXG4gICAgICAgIGRvbWFpbjogY29va2llLmRvbWFpbixcbiAgICAgICAgcGF0aDogY29va2llLnBhdGgsXG4gICAgICAgIGV4cGlyZXM6IGNvb2tpZS5leHBpcmVzLFxuICAgICAgICBodHRwT25seTogY29va2llLmh0dHBPbmx5LFxuICAgICAgICBzZWN1cmU6IGNvb2tpZS5zZWN1cmUsXG4gICAgICAgIHNhbWVTaXRlOiBjb29raWUuc2FtZVNpdGUgYXMgJ1N0cmljdCcgfCAnTGF4JyB8ICdOb25lJyB8IHVuZGVmaW5lZCxcbiAgICAgIH0pKTtcblxuICAgICAgYXdhaXQgcGFnZS5zZXRDb29raWUoLi4ucHVwcGV0ZWVyQ29va2llcyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBsb2FkIGNvb2tpZXM6ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc2F2ZUNvb2tpZXNGcm9tUGFnZShwYWdlOiBQYWdlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvb2tpZXMgPSBhd2FpdCBwYWdlLmNvb2tpZXMoKTtcblxuICAgICAgLy8gQ29udmVydCBQdXBwZXRlZXIgY29va2llIGZvcm1hdCB0byBhcHAgZm9ybWF0XG4gICAgICBjb25zdCBhcHBDb29raWVzOiBDb29raWVbXSA9IGNvb2tpZXMubWFwKChjb29raWUpID0+ICh7XG4gICAgICAgIG5hbWU6IGNvb2tpZS5uYW1lLFxuICAgICAgICB2YWx1ZTogY29va2llLnZhbHVlLFxuICAgICAgICBkb21haW46IGNvb2tpZS5kb21haW4sXG4gICAgICAgIHBhdGg6IGNvb2tpZS5wYXRoLFxuICAgICAgICBleHBpcmVzOiBjb29raWUuZXhwaXJlcyxcbiAgICAgICAgaHR0cE9ubHk6IGNvb2tpZS5odHRwT25seSxcbiAgICAgICAgc2VjdXJlOiBjb29raWUuc2VjdXJlLFxuICAgICAgICBzYW1lU2l0ZTogY29va2llLnNhbWVTaXRlIGFzICdTdHJpY3QnIHwgJ0xheCcgfCAnTm9uZScsXG4gICAgICB9KSk7XG5cbiAgICAgIHNhdmVDb29raWVzKGFwcENvb2tpZXMpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBzYXZlIGNvb2tpZXM6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyB0aGlzLmhhbmRsZVB1cHBldGVlckVycm9yKGVycm9yIGFzIEVycm9yLCAnc2F2ZV9jb29raWVzJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbmF2aWdhdGVXaXRoUmV0cnkoXG4gICAgcGFnZTogUGFnZSxcbiAgICB1cmw6IHN0cmluZyxcbiAgICB3YWl0VW50aWw6ICdsb2FkJyB8ICdkb21jb250ZW50bG9hZGVkJyB8ICduZXR3b3JraWRsZTAnIHwgJ25ldHdvcmtpZGxlMicgPSAnbG9hZCcsXG4gICAgbWF4UmV0cmllcz86IG51bWJlclxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZXRyaWVzID0gbWF4UmV0cmllcyB8fCB0aGlzLmNvbmZpZy54aHMubWF4UmV0cmllcztcblxuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDw9IHJldHJpZXM7IGF0dGVtcHQrKykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5nb3RvKHVybCwge1xuICAgICAgICAgIHdhaXRVbnRpbCxcbiAgICAgICAgICB0aW1lb3V0OiB0aGlzLmNvbmZpZy5icm93c2VyLm5hdmlnYXRpb25UaW1lb3V0LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubmFtZSA9PT0gJ1RpbWVvdXRFcnJvcicpIHtcbiAgICAgICAgICBpZiAoYXR0ZW1wdCA9PT0gcmV0cmllcykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEJyb3dzZXJOYXZpZ2F0aW9uRXJyb3IoXG4gICAgICAgICAgICAgIGBGYWlsZWQgdG8gbmF2aWdhdGUgdG8gJHt1cmx9IGFmdGVyICR7cmV0cmllcyArIDF9IGF0dGVtcHRzYCxcbiAgICAgICAgICAgICAgeyB1cmwsIGF0dGVtcHRzOiBhdHRlbXB0ICsgMSB9LFxuICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhd2FpdCBzbGVlcCh0aGlzLmNvbmZpZy54aHMucmV0cnlEZWxheSAqIDEwMDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgdHJ5V2FpdEZvclNlbGVjdG9yKFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgc2VsZWN0b3I6IHN0cmluZyxcbiAgICB0aW1lb3V0PzogbnVtYmVyLFxuICAgIHZpc2libGU6IGJvb2xlYW4gPSB0cnVlXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBwYWdlLndhaXRGb3JTZWxlY3RvcihzZWxlY3Rvciwge1xuICAgICAgICB0aW1lb3V0OiB0aW1lb3V0IHx8IHRoaXMuY29uZmlnLmJyb3dzZXIuZGVmYXVsdFRpbWVvdXQsXG4gICAgICAgIHZpc2libGUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5uYW1lID09PSAnVGltZW91dEVycm9yJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBhc3luYyB3YWl0Rm9yU2VsZWN0b3JWaXNpYmxlKHBhZ2U6IFBhZ2UsIHNlbGVjdG9yOiBzdHJpbmcsIHRpbWVvdXQ/OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy50cnlXYWl0Rm9yU2VsZWN0b3IocGFnZSwgc2VsZWN0b3IsIHRpbWVvdXQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgd2FpdEZvclNlbGVjdG9ySGlkZGVuKHBhZ2U6IFBhZ2UsIHNlbGVjdG9yOiBzdHJpbmcsIHRpbWVvdXQ/OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy50cnlXYWl0Rm9yU2VsZWN0b3IocGFnZSwgc2VsZWN0b3IsIHRpbWVvdXQsIGZhbHNlKTtcbiAgfVxuXG4gIGFzeW5jIGNsZWFudXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQ2xlYW51cCBicm93c2VyIHBvb2wgaWYgdXNpbmcgaXRcbiAgICBpZiAodGhpcy51c2VQb29sICYmIHRoaXMuYnJvd3NlclBvb2wpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYnJvd3NlclBvb2wuY2xlYW51cCgpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIGNsZWFuaW5nIHVwIGJyb3dzZXIgcG9vbDogJHtlcnJvcn1gKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENsb3NlIGFsbCB0cmFja2VkIHBhZ2VzIGJlZm9yZSBjbG9zaW5nIGJyb3dzZXJcbiAgICBhd2FpdCB0aGlzLmNsb3NlQWxsUGFnZXMoKTtcblxuICAgIC8vIENsZWFudXAgdHJhZGl0aW9uYWwgYnJvd3NlciBpbnN0YW5jZVxuICAgIGlmICh0aGlzLmJyb3dzZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5jbG9zZSgpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIGNsb3NpbmcgYnJvd3NlcjogJHtlcnJvcn1gKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRoaXMuYnJvd3NlciA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIGFsbCB0cmFja2VkIHBhZ2VzIHRoYXQgYXJlIHN0aWxsIG9wZW5cbiAgICovXG4gIGFzeW5jIGNsb3NlQWxsUGFnZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2xvc2VQcm9taXNlczogUHJvbWlzZTx2b2lkPltdID0gW107XG4gICAgZm9yIChjb25zdCBwYWdlIG9mIHRoaXMudHJhY2tlZFBhZ2VzKSB7XG4gICAgICBpZiAoIXBhZ2UuaXNDbG9zZWQoKSkge1xuICAgICAgICBjbG9zZVByb21pc2VzLnB1c2goXG4gICAgICAgICAgcGFnZS5jbG9zZSgpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oYEVycm9yIGNsb3NpbmcgdHJhY2tlZCBwYWdlOiAke2Vycm9yfWApO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChjbG9zZVByb21pc2VzKTtcbiAgICB0aGlzLnRyYWNrZWRQYWdlcy5jbGVhcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBicm93c2VyIHBvb2wgc3RhdGlzdGljcyAoaWYgdXNpbmcgcG9vbClcbiAgICovXG4gIGdldEJyb3dzZXJQb29sU3RhdHMoKSB7XG4gICAgaWYgKHRoaXMudXNlUG9vbCAmJiB0aGlzLmJyb3dzZXJQb29sKSB7XG4gICAgICByZXR1cm4gdGhpcy5icm93c2VyUG9vbC5nZXRQb29sU3RhdHMoKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2YgdHJhY2tlZCBwYWdlcyAoZm9yIG1vbml0b3JpbmcgbGVha3MpXG4gICAqL1xuICBnZXRUcmFja2VkUGFnZUNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudHJhY2tlZFBhZ2VzLnNpemU7XG4gIH1cblxuICAvKipcbiAgICogRW5hYmxlIGJyb3dzZXIgcG9vbGluZ1xuICAgKi9cbiAgZW5hYmxlQnJvd3NlclBvb2woKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnVzZVBvb2wpIHtcbiAgICAgIHRoaXMudXNlUG9vbCA9IHRydWU7XG4gICAgICB0aGlzLmJyb3dzZXJQb29sID0gbmV3IEJyb3dzZXJQb29sU2VydmljZSh0aGlzLmNvbmZpZywgdGhpcy5wb29sT3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERpc2FibGUgYnJvd3NlciBwb29saW5nXG4gICAqL1xuICBhc3luYyBkaXNhYmxlQnJvd3NlclBvb2woKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMudXNlUG9vbCAmJiB0aGlzLmJyb3dzZXJQb29sKSB7XG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXJQb29sLmNsZWFudXAoKTtcbiAgICAgIHRoaXMuYnJvd3NlclBvb2wgPSBudWxsO1xuICAgICAgdGhpcy51c2VQb29sID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVQdXBwZXRlZXJFcnJvcihlcnJvcjogRXJyb3IsIG9wZXJhdGlvbk5hbWU6IHN0cmluZyk6IFhIU0Vycm9yIHtcbiAgICBjb25zdCBjb250ZXh0ID0geyBvcGVyYXRpb25OYW1lIH07XG5cbiAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ1RpbWVvdXRFcnJvcicpIHtcbiAgICAgIGlmIChvcGVyYXRpb25OYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2xvZ2luJykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBYSFNFcnJvcihcbiAgICAgICAgICBgTG9naW4gb3BlcmF0aW9uIHRpbWVkIG91dCBkdXJpbmcgJHtvcGVyYXRpb25OYW1lfWAsXG4gICAgICAgICAgJ0xvZ2luVGltZW91dEVycm9yJyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IFhIU0Vycm9yKFxuICAgICAgICAgIGBCcm93c2VyIG9wZXJhdGlvbiB0aW1lZCBvdXQ6ICR7b3BlcmF0aW9uTmFtZX1gLFxuICAgICAgICAgICdCcm93c2VyRXJyb3InLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnbmF2aWdhdGlvbicpKSB7XG4gICAgICAgIHJldHVybiBuZXcgQnJvd3Nlck5hdmlnYXRpb25FcnJvcihcbiAgICAgICAgICBgTmF2aWdhdGlvbiBmYWlsZWQgZHVyaW5nICR7b3BlcmF0aW9uTmFtZX06ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgWEhTRXJyb3IoXG4gICAgICAgICAgYEJyb3dzZXIgZXJyb3IgZHVyaW5nICR7b3BlcmF0aW9uTmFtZX06ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgICdCcm93c2VyRXJyb3InLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gR2xvYmFsIGJyb3dzZXIgbWFuYWdlciBpbnN0YW5jZVxubGV0IGdsb2JhbEJyb3dzZXJNYW5hZ2VyOiBCcm93c2VyTWFuYWdlciB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QnJvd3Nlck1hbmFnZXIodXNlUG9vbDogYm9vbGVhbiA9IGZhbHNlKTogQnJvd3Nlck1hbmFnZXIge1xuICBpZiAoIWdsb2JhbEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgZ2xvYmFsQnJvd3Nlck1hbmFnZXIgPSBuZXcgQnJvd3Nlck1hbmFnZXIodW5kZWZpbmVkLCB1c2VQb29sKTtcbiAgfVxuICByZXR1cm4gZ2xvYmFsQnJvd3Nlck1hbmFnZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb29sZWRCcm93c2VyTWFuYWdlcigpOiBCcm93c2VyTWFuYWdlciB7XG4gIHJldHVybiBnZXRCcm93c2VyTWFuYWdlcih0cnVlKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFudXBHbG9iYWxCcm93c2VyTWFuYWdlcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGdsb2JhbEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgYXdhaXQgZ2xvYmFsQnJvd3Nlck1hbmFnZXIuY2xlYW51cCgpO1xuICAgIGdsb2JhbEJyb3dzZXJNYW5hZ2VyID0gbnVsbDtcbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3977\n\n}");
74
81
 
75
82
  /***/ }),
76
83
 
@@ -84,7 +91,7 @@ eval("{/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* har
84
91
  /***/ 5582:
85
92
  /***/ ((__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) => {
86
93
 
87
- eval("{\n;// external \"commander\"\nconst external_commander_namespaceObject = require(\"commander\");\n// EXTERNAL MODULE: ./src/shared/config.ts + 1 modules\nvar shared_config = __webpack_require__(2207);\n// EXTERNAL MODULE: ./src/shared/errors.ts\nvar shared_errors = __webpack_require__(7636);\n// EXTERNAL MODULE: ./src/shared/base.service.ts + 2 modules\nvar base_service = __webpack_require__(3100);\n// EXTERNAL MODULE: ./src/shared/cookies.ts\nvar cookies = __webpack_require__(4760);\n// EXTERNAL MODULE: ./src/shared/logger.ts\nvar logger = __webpack_require__(9135);\n;// ./src/shared/xhs.utils.ts\n/**\n * Utility functions for XHS operations\n */\n\nconst XHS_HOME_URL = 'https://www.xiaohongshu.com';\nconst XHS_EXPLORE_URL = `${XHS_HOME_URL}/explore`;\nconst XHS_SEARCH_URL = `${XHS_HOME_URL}/search_result`;\nconst XHS_CREATOR_PUBLISH_URL = 'https://creator.xiaohongshu.com/publish/publish?source=official';\nconst LOGIN_OK_SELECTOR = '.main-container .user .link-wrapper .channel';\nfunction makeSearchUrl(keyword) {\n const params = new URLSearchParams({\n keyword,\n source: 'web_explore_feed',\n });\n return `${XHS_SEARCH_URL}?${params.toString()}`;\n}\nfunction makeFeedDetailUrl(feedId, xsecToken) {\n const params = new URLSearchParams({\n xsec_token: xsecToken,\n xsec_source: 'pc_feed',\n });\n return `${XHS_EXPLORE_URL}/${feedId}?${params.toString()}`;\n}\nasync function extractInitialState(page) {\n try {\n // Wait for page to be fully loaded - Puppeteer doesn't have waitForLoadState\n // We'll just wait a bit for the page to settle\n await new Promise((resolve) => globalThis.setTimeout(resolve, 1000));\n }\n catch {\n // Ignore load state errors\n }\n try {\n const result = await page.evaluate(`\n (() => {\n // Try multiple possible state objects\n const possibleStates = [\n window.__INITIAL_STATE__,\n window.__INITIAL_SSR_STATE__,\n window.__NEXT_DATA__,\n window.__NUXT__,\n window.__VUE__,\n window.__REACT_QUERY_STATE__\n ];\n\n for (const state of possibleStates) {\n if (state && typeof state === 'object') {\n try {\n // Use a more robust JSON serialization that handles circular references\n const seen = new WeakSet();\n return JSON.stringify(state, (key, val) => {\n if (val != null && typeof val === \"object\") {\n if (seen.has(val)) {\n return \"[Circular]\";\n }\n seen.add(val);\n }\n return val;\n });\n } catch (e) {\n logger.warn('JSON.stringify failed for state:', e.message);\n continue;\n }\n }\n }\n\n // If no state found, try to find any global state\n const globalKeys = Object.keys(window).filter(key =>\n key.includes('STATE') || key.includes('DATA') || key.includes('INITIAL')\n );\n\n for (const key of globalKeys) {\n const value = window[key];\n if (value && typeof value === 'object') {\n try {\n const seen = new WeakSet();\n return JSON.stringify(value, (key, val) => {\n if (val != null && typeof val === \"object\") {\n if (seen.has(val)) {\n return \"[Circular]\";\n }\n seen.add(val);\n }\n return val;\n });\n } catch (e) {\n logger.warn('JSON.stringify failed for global key:', key, e.message);\n continue;\n }\n }\n }\n\n return '';\n })()\n `);\n if (!result) {\n return null;\n }\n return JSON.parse(result);\n }\n catch {\n return null;\n }\n}\nasync function isLoggedIn(page) {\n try {\n const elements = await page.$$(LOGIN_OK_SELECTOR);\n return elements.length > 0;\n }\n catch {\n return false;\n }\n}\nasync function getLoginStatusWithProfile(page) {\n try {\n // First check if logged in using the existing method\n const elements = await page.$$(LOGIN_OK_SELECTOR);\n const isLoggedIn = elements.length > 0;\n if (!isLoggedIn) {\n return { isLoggedIn: false };\n }\n // If logged in, try to extract profile information from current page\n let profileData = {};\n try {\n profileData = await page.evaluate(() => {\n const profile = {};\n // Extract user ID from URL if on profile page\n // eslint-disable-next-line no-undef\n const urlMatch = window.location.href.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (urlMatch) {\n profile.userId = urlMatch[1];\n }\n // Try to find user nickname\n // eslint-disable-next-line no-undef\n const nameElement = document.querySelector('.user-name, [class*=\"user-name\"], [class*=\"nickname\"]');\n if (nameElement) {\n profile.nickname = nameElement.textContent?.trim();\n }\n // Try to find user info text that might contain stats\n // eslint-disable-next-line no-undef\n const infoElement = document.querySelector('.user-info, [class*=\"user-info\"]');\n if (infoElement) {\n const infoText = infoElement.textContent || '';\n profile.infoText = infoText;\n // Try to extract numbers from the info text (followers, following, likes)\n const numbers = infoText.match(/\\d+/g);\n if (numbers && numbers.length >= 3) {\n // Common pattern: followers, following, likes\n profile.following = parseInt(numbers[0]) || 0;\n profile.followers = parseInt(numbers[1]) || 0;\n profile.likes = parseInt(numbers[2]) || 0;\n }\n // Extract 小红书号 (XHS number)\n const xhsMatch = infoText.match(/小红书号:(\\d+)/);\n if (xhsMatch) {\n profile.xhsNumber = xhsMatch[1];\n }\n // Extract IP属地 (IP location)\n const ipMatch = infoText.match(/IP属地:([^0-9]+)/);\n if (ipMatch) {\n profile.ipLocation = ipMatch[1].trim();\n }\n }\n // Try to find avatar\n // eslint-disable-next-line no-undef\n const avatarElement = document.querySelector('img[class*=\"avatar\"], img[class*=\"profile\"], .avatar img, .profile img');\n if (avatarElement) {\n profile.avatar = avatarElement.src;\n }\n return profile;\n });\n }\n catch {\n logger/* logger */.v.error('Error in page.evaluate');\n profileData = {};\n }\n return {\n isLoggedIn: true,\n profile: Object.keys(profileData).length > 0 ? profileData : undefined,\n };\n }\n catch {\n // If there's an error, fall back to basic login check\n try {\n const elements = await page.$$(LOGIN_OK_SELECTOR);\n return { isLoggedIn: elements.length > 0 };\n }\n catch {\n return { isLoggedIn: false };\n }\n }\n}\n\n// EXTERNAL MODULE: ./src/shared/utils.ts\nvar utils = __webpack_require__(2094);\n;// ./src/core/auth/auth.service.ts\n/**\n * Authentication service for XHS MCP Server\n */\n\n\n\n\n\n\nclass AuthService extends base_service/* BaseService */.d {\n constructor(config) {\n super(config);\n }\n async login(browserPath, timeout = 300) {\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n // Navigate to explore page\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.exploreUrl);\n // Check if already logged in\n if (await isLoggedIn(page)) {\n // Get profile information if already logged in\n let profile = undefined;\n try {\n // Find current user's profile link and extract user ID from URL\n const profileUrl = await page.evaluate(() => {\n const userLinks = Array.from(document.querySelectorAll('a[href*=\"/user/profile/\"]'));\n const currentUserLink = userLinks.find((link) => {\n const text = link.textContent?.trim();\n return (text === '我' ||\n (text && text.includes('profile')) ||\n (text && text.includes('用户')));\n });\n return currentUserLink ? currentUserLink.href : null;\n });\n if (profileUrl) {\n // Extract user ID from profile URL\n const userIdMatch = profileUrl.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (userIdMatch) {\n profile = {\n userId: userIdMatch[1],\n profileUrl: profileUrl,\n };\n }\n }\n // Also try to get additional profile info from current page\n const loginStatus = await getLoginStatusWithProfile(page);\n if (loginStatus.profile) {\n profile = { ...profile, ...loginStatus.profile };\n }\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get profile information:', profileError);\n // Continue without profile info\n }\n return {\n success: true,\n message: 'Already logged in',\n status: 'logged_in',\n action: 'none',\n profile,\n };\n }\n // Wait for login completion\n const checkInterval = 5; // Check every 5 seconds\n const maxChecks = timeout / checkInterval;\n for (let checkCount = 0; checkCount < maxChecks; checkCount++) {\n try {\n // Check if login completed with short timeout\n await page.waitForSelector(this.getConfig().xhs.loginOkSelector, {\n timeout: checkInterval * 1000,\n });\n // Login completed successfully\n break;\n }\n catch (error) {\n // Login not yet complete, continue checking\n const elapsed = (checkCount + 1) * checkInterval;\n const remaining = timeout - elapsed;\n if (checkCount === maxChecks - 1) {\n // Final timeout reached\n throw new shared_errors/* LoginTimeoutError */.H7(`Login timed out after ${timeout} seconds. Please complete QR code scanning or manual login in the browser window.`, {\n timeout,\n url: this.getConfig().xhs.exploreUrl,\n elapsedTime: elapsed,\n suggestion: 'Increase timeout parameter or complete login faster',\n });\n }\n }\n }\n // Save cookies after successful login\n await this.getBrowserManager().saveCookiesFromPage(page);\n // Verify login success and get profile information\n await (0,utils/* sleep */.yy)(1000); // Brief wait for page to update\n const loginStatus = await getLoginStatusWithProfile(page);\n if (loginStatus.isLoggedIn) {\n // Try to get additional profile information\n let profile = loginStatus.profile;\n try {\n // Find current user's profile link and extract user ID from URL\n const profileUrl = await page.evaluate(() => {\n const userLinks = Array.from(document.querySelectorAll('a[href*=\"/user/profile/\"]'));\n const currentUserLink = userLinks.find((link) => {\n const text = link.textContent?.trim();\n return (text === '我' ||\n (text && text.includes('profile')) ||\n (text && text.includes('用户')));\n });\n return currentUserLink ? currentUserLink.href : null;\n });\n if (profileUrl) {\n // Extract user ID from profile URL\n const userIdMatch = profileUrl.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (userIdMatch) {\n profile = {\n ...profile,\n userId: userIdMatch[1],\n profileUrl: profileUrl,\n };\n }\n }\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get additional profile information:', profileError);\n // Continue with existing profile info\n }\n return {\n success: true,\n message: 'Login successful',\n status: 'logged_in',\n action: 'logged_in',\n profile,\n };\n }\n else {\n throw new shared_errors/* LoginFailedError */.f6('Login process completed but authentication verification failed');\n }\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* LoginTimeoutError */.H7 || error instanceof shared_errors/* LoginFailedError */.f6) {\n throw error;\n }\n logger/* logger */.v.error(`Login failed with unexpected error: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Login failed: ${error}`, 'LoginError', { timeout }, error);\n }\n }\n async logout() {\n try {\n const success = (0,cookies/* deleteCookiesFile */.ZR)();\n if (success) {\n return {\n success: true,\n message: 'Logged out successfully (cookies deleted)',\n status: 'logged_out',\n action: 'logged_out',\n };\n }\n else {\n return {\n success: false,\n message: 'Failed to delete cookies file',\n status: 'logged_out',\n action: 'none',\n };\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Logout failed: ${error}`);\n return {\n success: false,\n message: `Logout failed: ${error}`,\n status: 'logged_out',\n action: 'none',\n };\n }\n }\n async checkStatus(browserPath) {\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.exploreUrl);\n await (0,utils/* sleep */.yy)(1000); // Wait for page to load\n // First check if logged in\n const loggedIn = await isLoggedIn(page);\n if (!loggedIn) {\n return {\n success: true,\n loggedIn: false,\n status: 'logged_out',\n urlChecked: this.getConfig().xhs.exploreUrl,\n };\n }\n // If logged in, try to get profile information\n let profile = undefined;\n try {\n // Find current user's profile link and extract user ID from URL\n const profileUrl = await page.evaluate(() => {\n const userLinks = Array.from(document.querySelectorAll('a[href*=\"/user/profile/\"]'));\n const currentUserLink = userLinks.find((link) => {\n const text = link.textContent?.trim();\n return (text === '我' ||\n (text && text.includes('profile')) ||\n (text && text.includes('用户')));\n });\n return currentUserLink ? currentUserLink.href : null;\n });\n if (profileUrl) {\n // Extract user ID from profile URL\n const userIdMatch = profileUrl.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (userIdMatch) {\n profile = {\n userId: userIdMatch[1],\n profileUrl: profileUrl,\n };\n }\n }\n }\n catch (profileError) {\n console.error('❌ Failed to get profile information:', profileError);\n // Continue without profile info\n }\n return {\n success: true,\n loggedIn: true,\n status: 'logged_in',\n urlChecked: this.getConfig().xhs.exploreUrl,\n profile,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Status check failed: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Status check failed: ${error}`, 'StatusCheckError', {}, error);\n }\n }\n}\n\n// EXTERNAL MODULE: external \"puppeteer\"\nvar external_puppeteer_ = __webpack_require__(9916);\nvar external_puppeteer_default = /*#__PURE__*/__webpack_require__.n(external_puppeteer_);\n;// external \"node:child_process\"\nconst external_node_child_process_namespaceObject = require(\"node:child_process\");\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js + 1 modules\nvar esm_server = __webpack_require__(2028);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js + 1 modules\nvar stdio = __webpack_require__(7862);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/types.js + 7 modules\nvar types = __webpack_require__(2780);\n;// ./src/core/feeds/feed.service.ts\n/**\n * Feed operations service for XHS MCP Server\n */\n\n\n\n\n\nclass FeedService extends base_service/* BaseService */.d {\n constructor(config) {\n super(config);\n }\n async getFeedList(browserPath) {\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.homeUrl);\n await (0,utils/* sleep */.yy)(1000);\n // Check if logged in\n if (!(await isLoggedIn(page))) {\n throw new shared_errors/* NotLoggedInError */.bG('Must be logged in to access feed list', {\n operation: 'get_feed_list',\n });\n }\n // Extract feed data using a more targeted approach\n let feedData = null;\n let attempts = 0;\n const maxAttempts = 10;\n while (attempts < maxAttempts && !feedData) {\n await (0,utils/* sleep */.yy)(2000); // Wait 2 seconds between attempts\n attempts++;\n feedData = (await page.evaluate(`\n (() => {\n if (window.__INITIAL_STATE__ && window.__INITIAL_STATE__.feed && window.__INITIAL_STATE__.feed.feeds && window.__INITIAL_STATE__.feed.feeds._value) {\n try {\n // Try to serialize just the feeds data to avoid circular reference issues\n const feedsData = window.__INITIAL_STATE__.feed.feeds._value;\n return JSON.stringify(feedsData);\n } catch (e) {\n logger.warn('Failed to serialize feeds data:', e.message);\n return null;\n }\n }\n return null;\n })()\n `));\n if (feedData) {\n logger/* logger */.v.info(`Feed results loaded after ${attempts} attempts`);\n break;\n }\n }\n if (!feedData) {\n throw new shared_errors/* FeedParsingError */.TG(`Could not extract feed data after ${maxAttempts} attempts. The page may not be fully loaded or the state structure has changed.`, {\n url: this.getConfig().xhs.homeUrl,\n suggestion: 'Try logging in first using xhs_auth_login tool',\n });\n }\n const feedsValue = JSON.parse(feedData);\n return {\n success: true,\n feeds: feedsValue,\n count: feedsValue.length,\n source: 'home_page',\n url: this.getConfig().xhs.homeUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* NotLoggedInError */.bG || error instanceof shared_errors/* FeedParsingError */.TG) {\n throw error;\n }\n logger/* logger */.v.error(`Failed to get feed list: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Failed to get feed list: ${error}`, 'GetFeedListError', {}, error);\n }\n }\n async searchFeeds(keyword, browserPath) {\n if (!keyword || !keyword.trim()) {\n throw new shared_errors/* FeedError */.lS('Search keyword cannot be empty');\n }\n const trimmedKeyword = keyword.trim();\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n const searchUrl = makeSearchUrl(trimmedKeyword);\n await this.getBrowserManager().navigateWithRetry(page, searchUrl);\n // Wait for search results to load with multiple attempts\n let searchData = null;\n let attempts = 0;\n const maxAttempts = 10;\n while (attempts < maxAttempts && !searchData) {\n await (0,utils/* sleep */.yy)(2000); // Wait 2 seconds between attempts\n attempts++;\n searchData = (await page.evaluate(`\n (() => {\n if (window.__INITIAL_STATE__ && window.__INITIAL_STATE__.search && window.__INITIAL_STATE__.search.feeds && window.__INITIAL_STATE__.search.feeds._value) {\n try {\n // Try to serialize just the feeds data to avoid circular reference issues\n const feedsData = window.__INITIAL_STATE__.search.feeds._value;\n return JSON.stringify(feedsData);\n } catch (e) {\n logger.warn('Failed to serialize feeds data:', e.message);\n return null;\n }\n }\n return null;\n })()\n `));\n if (searchData) {\n logger/* logger */.v.info(`Search results loaded after ${attempts} attempts`);\n break;\n }\n }\n if (!searchData) {\n throw new shared_errors/* FeedParsingError */.TG(`Could not extract search results for keyword: ${trimmedKeyword} after ${maxAttempts} attempts`, {\n keyword: trimmedKeyword,\n url: searchUrl,\n });\n }\n const feedsValue = JSON.parse(searchData);\n return {\n success: true,\n keyword: trimmedKeyword,\n feeds: feedsValue,\n count: feedsValue.length,\n searchUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* FeedError */.lS) {\n throw error;\n }\n logger/* logger */.v.error(`Feed search failed for keyword '${trimmedKeyword}': ${error}`);\n throw new shared_errors/* XHSError */.a_(`Feed search failed: ${error}`, 'SearchFeedsError', { keyword: trimmedKeyword }, error);\n }\n }\n async getFeedDetail(feedId, xsecToken, browserPath) {\n if (!feedId || !xsecToken) {\n throw new shared_errors/* FeedError */.lS('Both feed_id and xsec_token are required');\n }\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n const detailUrl = makeFeedDetailUrl(feedId, xsecToken);\n await this.getBrowserManager().navigateWithRetry(page, detailUrl);\n await (0,utils/* sleep */.yy)(1000);\n const state = await extractInitialState(page);\n const noteData = state?.note;\n if (!state || !noteData || !noteData.noteDetailMap) {\n throw new shared_errors/* FeedParsingError */.TG(`Could not extract note details for feed: ${feedId}`, {\n feedId,\n url: detailUrl,\n });\n }\n const noteDetailMap = noteData.noteDetailMap;\n if (!(feedId in noteDetailMap)) {\n throw new shared_errors/* FeedNotFoundError */.aW(`Feed ${feedId} not found in note details`, {\n feedId,\n availableFeeds: Object.keys(noteDetailMap),\n });\n }\n const detail = noteDetailMap[feedId];\n return {\n success: true,\n feedId,\n detail,\n url: detailUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* FeedError */.lS ||\n error instanceof shared_errors/* FeedNotFoundError */.aW ||\n error instanceof shared_errors/* FeedParsingError */.TG) {\n throw error;\n }\n logger/* logger */.v.error(`Failed to get feed detail for ${feedId}: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Failed to get feed detail: ${error}`, 'GetFeedDetailError', { feedId }, error);\n }\n }\n async commentOnFeed(feedId, xsecToken, note, browserPath) {\n if (!feedId || !xsecToken || !note) {\n throw new shared_errors/* FeedError */.lS('feed_id, xsec_token, and note are all required');\n }\n if (note.trim().length === 0) {\n throw new shared_errors/* FeedError */.lS('Comment note cannot be empty');\n }\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n const detailUrl = makeFeedDetailUrl(feedId, xsecToken);\n await this.getBrowserManager().navigateWithRetry(page, detailUrl);\n await (0,utils/* sleep */.yy)(1000);\n // Check if logged in\n if (!(await isLoggedIn(page))) {\n throw new shared_errors/* NotLoggedInError */.bG('Must be logged in to comment on feeds', {\n operation: 'comment_on_feed',\n feedId,\n });\n }\n // Click on comment input\n const commentInputSelector = 'div.input-box div.content-edit span';\n if (!(await this.getBrowserManager().tryWaitForSelector(page, commentInputSelector))) {\n throw new shared_errors/* FeedError */.lS('Comment input not found on page', {\n feedId,\n selector: commentInputSelector,\n });\n }\n const commentInput = await page.$(commentInputSelector);\n if (commentInput) {\n await commentInput.click();\n }\n // Fill comment note\n const editorSelector = 'div.input-box div.content-edit p.content-input';\n const editor = await page.$(editorSelector);\n if (editor) {\n await editor.click();\n await editor.type(note, { delay: 30 });\n }\n await (0,utils/* sleep */.yy)(1000);\n // Submit comment\n const submitSelector = 'div.bottom button.submit';\n const submitButton = await page.$(submitSelector);\n if (submitButton) {\n await submitButton.click();\n }\n await (0,utils/* sleep */.yy)(2000); // Wait for submission\n return {\n success: true,\n message: 'Comment submitted successfully',\n feedId,\n note,\n url: detailUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* FeedError */.lS || error instanceof shared_errors/* NotLoggedInError */.bG) {\n throw error;\n }\n logger/* logger */.v.error(`Failed to comment on feed ${feedId}: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Failed to comment on feed: ${error}`, 'CommentOnFeedError', { feedId }, error);\n }\n }\n}\n\n// EXTERNAL MODULE: ./node_modules/string-width/index.js + 4 modules\nvar string_width = __webpack_require__(6904);\n;// ./src/shared/title-validator.ts\n/**\n * Title validation utility for XHS MCP Server\n * Validates title width according to XiaoHongShu's display width rules\n *\n * XHS Rules:\n * - Max width: 40 units\n * - CJK characters (Chinese/Japanese/Korean): 2 units each\n * - Other characters (English/Numbers): 1 unit each\n */\n\n\n/**\n * XiaoHongShu title constraints\n */\nconst XHS_TITLE_CONSTRAINTS = {\n MAX_WIDTH: 40, // Maximum display width in units\n MAX_LENGTH: 20, // Approximate max character count (for reference)\n};\n/**\n * Validate title width according to XHS display rules\n *\n * @param title - The title to validate\n * @returns Validation result with width information\n *\n * @example\n * ```typescript\n * const result = validateTitleWidth('Hello世界');\n * console.log(result.width); // 10 (5 + 2*2 + 1 = 10)\n * console.log(result.valid); // true\n * ```\n */\nfunction validateTitleWidth(title) {\n if (!title) {\n return {\n valid: false,\n width: 0,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n message: 'Title cannot be empty',\n suggestion: 'Please provide a valid title',\n };\n }\n // Calculate display width using string-width\n // This correctly handles CJK characters, emoji, and other Unicode\n const width = (0,string_width/* default */.A)(title);\n if (width > XHS_TITLE_CONSTRAINTS.MAX_WIDTH) {\n return {\n valid: false,\n width,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n message: `Title width exceeds limit: ${width} units (max: ${XHS_TITLE_CONSTRAINTS.MAX_WIDTH} units)`,\n suggestion: `Current title is too long. CJK characters count as 2 units, English/numbers as 1 unit. Please shorten your title.`,\n };\n }\n return {\n valid: true,\n width,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n };\n}\n/**\n * Validate and throw error if title width is invalid\n *\n * @param title - The title to validate\n * @throws PublishError if title width is invalid\n *\n * @example\n * ```typescript\n * try {\n * assertTitleWidthValid('很长很长的标题'.repeat(10));\n * } catch (error) {\n * console.error(error.message);\n * }\n * ```\n */\nfunction assertTitleWidthValid(title) {\n const result = validateTitleWidth(title);\n if (!result.valid) {\n throw new shared_errors/* PublishError */.S1(result.message, {\n title,\n width: result.width,\n maxWidth: result.maxWidth,\n suggestion: result.suggestion,\n details: {\n titleLength: title.length,\n displayWidth: result.width,\n maxDisplayWidth: result.maxWidth,\n exceeded: result.width - result.maxWidth,\n },\n });\n }\n}\n/**\n * Get the display width of a title\n *\n * @param title - The title to measure\n * @returns Display width in units\n *\n * @example\n * ```typescript\n * console.log(getTitleWidth('Hello')); // 5\n * console.log(getTitleWidth('你好')); // 4 (2*2)\n * console.log(getTitleWidth('Hello世界')); // 10 (5 + 2*2 + 1)\n * console.log(getTitleWidth('👋Hello')); // 7 (2 + 5)\n * ```\n */\nfunction getTitleWidth(title) {\n return (0,string_width/* default */.A)(title);\n}\n/**\n * Calculate how many characters can be added to the title\n *\n * @param title - Current title\n * @returns Remaining width units available\n *\n * @example\n * ```typescript\n * const remaining = getRemainingTitleWidth('Hello'); // 35\n * console.log(`You can add ${remaining} more units`);\n * ```\n */\nfunction calculateRemainingTitleWidth(title) {\n const currentWidth = getTitleWidth(title);\n return Math.max(0, XHS_TITLE_CONSTRAINTS.MAX_WIDTH - currentWidth);\n}\n/**\n * Truncate title to fit within width limit\n *\n * @param title - The title to truncate\n * @param maxWidth - Maximum width (default: XHS_TITLE_CONSTRAINTS.MAX_WIDTH)\n * @returns Truncated title that fits within width limit\n *\n * @example\n * ```typescript\n * const long = '这是一个很长很长的标题'.repeat(5);\n * const truncated = truncateTitleToWidth(long);\n * console.log(getTitleWidth(truncated)); // <= 40\n * ```\n */\nfunction truncateTitleToWidth(title, maxWidth = XHS_TITLE_CONSTRAINTS.MAX_WIDTH) {\n if (getTitleWidth(title) <= maxWidth) {\n return title;\n }\n let truncated = '';\n let currentWidth = 0;\n for (const char of title) {\n const charWidth = stringWidth(char);\n if (currentWidth + charWidth > maxWidth) {\n break;\n }\n truncated += char;\n currentWidth += charWidth;\n }\n return truncated;\n}\n/**\n * Get human-readable width breakdown\n * Useful for debugging and user feedback\n *\n * @param title - The title to analyze\n * @returns Width breakdown information\n */\nfunction getTitleWidthBreakdown(title) {\n const totalWidth = getTitleWidth(title);\n const breakdown = [];\n for (const char of title) {\n const charWidth = stringWidth(char);\n let type = 'Other';\n const code = char.charCodeAt(0);\n if (char.match(/[\\u4e00-\\u9fff\\u3400-\\u4dbf\\uf900-\\ufaff]/)) {\n type = 'CJK';\n }\n else if (code < 128) {\n type = 'ASCII';\n }\n else if (char.match(/[\\u{1F300}-\\u{1F9FF}]/u)) {\n type = 'Emoji';\n }\n breakdown.push({ char, width: charWidth, type });\n }\n return {\n title,\n totalWidth,\n totalChars: title.length,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n remaining: calculateRemainingTitleWidth(title),\n valid: totalWidth <= XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n breakdown,\n };\n}\n\n// EXTERNAL MODULE: external \"fs\"\nvar external_fs_ = __webpack_require__(9896);\n// EXTERNAL MODULE: external \"path\"\nvar external_path_ = __webpack_require__(6928);\n;// external \"crypto\"\nconst external_crypto_namespaceObject = require(\"crypto\");\n;// external \"node-fetch\"\nconst external_node_fetch_namespaceObject = require(\"node-fetch\");\nvar external_node_fetch_default = /*#__PURE__*/__webpack_require__.n(external_node_fetch_namespaceObject);\n;// ./src/shared/image-downloader.ts\n/**\n * Image downloader utility for XHS MCP Server\n * Supports downloading images from HTTP/HTTPS URLs\n */\n\n\n\n\n\n\nclass ImageDownloader {\n saveDir;\n timeout;\n maxFileSize;\n constructor(saveDir = './temp_images', timeout = 30000, maxFileSize = 10 * 1024 * 1024 // 10MB default\n ) {\n this.saveDir = saveDir;\n this.timeout = timeout;\n this.maxFileSize = maxFileSize;\n // Ensure save directory exists\n if (!(0,external_fs_.existsSync)(this.saveDir)) {\n (0,external_fs_.mkdirSync)(this.saveDir, { recursive: true });\n }\n }\n /**\n * Check if a string is a valid HTTP/HTTPS URL\n */\n static isImageUrl(path) {\n if (!path)\n return false;\n const lowerPath = path.toLowerCase().trim();\n return lowerPath.startsWith('http://') || lowerPath.startsWith('https://');\n }\n /**\n * Generate a unique filename for an image URL\n * Uses only URL hash for consistent caching\n */\n generateFileName(imageUrl) {\n // Use SHA256 hash of URL for uniqueness\n const hash = (0,external_crypto_namespaceObject.createHash)('sha256').update(imageUrl).digest('hex');\n const shortHash = hash.substring(0, 16);\n // Try to extract extension from URL\n let extension = 'jpg'; // default\n try {\n const url = new URL(imageUrl);\n const pathname = url.pathname.toLowerCase();\n const match = pathname.match(/\\.(jpg|jpeg|png|gif|webp|bmp)$/i);\n if (match) {\n extension = match[1];\n }\n }\n catch {\n // Use default extension\n }\n // Fixed filename for proper caching (no timestamp)\n return `img_${shortHash}.${extension}`;\n }\n /**\n * Validate that downloaded data is actually an image\n */\n validateImageData(buffer) {\n // Check file signatures (magic numbers)\n if (buffer.length < 12) {\n return { isValid: false, extension: '' };\n }\n // JPEG\n if (buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff) {\n return { isValid: true, extension: 'jpg' };\n }\n // PNG\n if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47) {\n return { isValid: true, extension: 'png' };\n }\n // GIF\n if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46) {\n return { isValid: true, extension: 'gif' };\n }\n // WebP\n if (buffer[0] === 0x52 &&\n buffer[1] === 0x49 &&\n buffer[2] === 0x46 &&\n buffer[3] === 0x46 &&\n buffer[8] === 0x57 &&\n buffer[9] === 0x45 &&\n buffer[10] === 0x42 &&\n buffer[11] === 0x50) {\n return { isValid: true, extension: 'webp' };\n }\n // BMP\n if (buffer[0] === 0x42 && buffer[1] === 0x4d) {\n return { isValid: true, extension: 'bmp' };\n }\n return { isValid: false, extension: '' };\n }\n /**\n * Download a single image from URL\n */\n async downloadImage(imageUrl) {\n // Validate URL format\n if (!ImageDownloader.isImageUrl(imageUrl)) {\n throw new shared_errors/* InvalidImageError */.TD(`Invalid image URL format: ${imageUrl}`, {\n url: imageUrl,\n suggestion: 'URL must start with http:// or https://',\n });\n }\n // Generate filename and path\n const fileName = this.generateFileName(imageUrl);\n const localPath = (0,external_path_.join)(this.saveDir, fileName);\n // Check if file already exists (cache)\n if ((0,external_fs_.existsSync)(localPath)) {\n const stats = (0,external_fs_.statSync)(localPath);\n logger/* logger */.v.debug(`Using cached image: ${localPath}`);\n return {\n originalUrl: imageUrl,\n localPath,\n cached: true,\n fileSize: stats.size,\n };\n }\n logger/* logger */.v.debug(`Downloading image from: ${imageUrl}`);\n try {\n // Download image with timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n const response = await external_node_fetch_default()(imageUrl, {\n signal: controller.signal,\n headers: {\n 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',\n },\n });\n clearTimeout(timeoutId);\n if (!response.ok) {\n throw new shared_errors/* InvalidImageError */.TD(`Failed to download image: HTTP ${response.status} ${response.statusText}`, {\n url: imageUrl,\n statusCode: response.status,\n statusText: response.statusText,\n });\n }\n // Check Content-Length if available\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength) > this.maxFileSize) {\n throw new shared_errors/* InvalidImageError */.TD(`Image file too large: ${(parseInt(contentLength) / 1024 / 1024).toFixed(2)}MB (max: ${(this.maxFileSize / 1024 / 1024).toFixed(2)}MB)`, {\n url: imageUrl,\n fileSize: parseInt(contentLength),\n maxSize: this.maxFileSize,\n suggestion: 'Try using a smaller image or increase maxFileSize',\n });\n }\n // Get image data\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n // Verify actual size\n if (buffer.length > this.maxFileSize) {\n throw new shared_errors/* InvalidImageError */.TD(`Downloaded file too large: ${(buffer.length / 1024 / 1024).toFixed(2)}MB (max: ${(this.maxFileSize /\n 1024 /\n 1024).toFixed(2)}MB)`, {\n url: imageUrl,\n fileSize: buffer.length,\n maxSize: this.maxFileSize,\n });\n }\n // Validate it's actually an image\n const validation = this.validateImageData(buffer);\n if (!validation.isValid) {\n throw new shared_errors/* InvalidImageError */.TD(`Downloaded file is not a valid image: ${imageUrl}`, {\n url: imageUrl,\n suggestion: 'Make sure the URL points to an actual image file',\n });\n }\n // Save to file\n (0,external_fs_.writeFileSync)(localPath, buffer);\n logger/* logger */.v.debug(`Image downloaded successfully: ${localPath} (${buffer.length} bytes)`);\n return {\n originalUrl: imageUrl,\n localPath,\n cached: false,\n fileSize: buffer.length,\n };\n }\n catch (error) {\n if (error instanceof shared_errors/* InvalidImageError */.TD) {\n throw error;\n }\n // Handle abort error\n if (error instanceof Error && error.name === 'AbortError') {\n throw new shared_errors/* InvalidImageError */.TD(`Image download timeout after ${this.timeout}ms: ${imageUrl}`, {\n url: imageUrl,\n timeout: this.timeout,\n suggestion: 'The image may be too large or the network is slow',\n }, error);\n }\n throw new shared_errors/* InvalidImageError */.TD(`Failed to download image: ${imageUrl}`, {\n url: imageUrl,\n }, error);\n }\n }\n /**\n * Download multiple images from URLs (parallel download for better performance)\n */\n async downloadImages(imageUrls) {\n // Download all images in parallel\n const downloadPromises = imageUrls.map((url) => this.downloadImage(url).catch((error) => ({ error, url })));\n const results = await Promise.all(downloadPromises);\n const successResults = [];\n const errors = [];\n results.forEach((result) => {\n if ('error' in result) {\n errors.push({ url: result.url, error: result.error });\n }\n else {\n successResults.push(result);\n }\n });\n // If any downloads failed, throw an error with details\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => `${e.url}: ${e.error.message}`).join('\\n');\n throw new shared_errors/* InvalidImageError */.TD(`Failed to download ${errors.length} of ${imageUrls.length} images:\\n${errorMessages}`, {\n totalCount: imageUrls.length,\n failedCount: errors.length,\n successCount: successResults.length,\n failedUrls: errors.map((e) => e.url),\n });\n }\n return successResults;\n }\n /**\n * Process a list of image paths - download URLs and keep local paths as-is\n */\n async processImagePaths(imagePaths) {\n const localPaths = [];\n const urlsToDownload = [];\n // Separate URLs from local paths\n for (const path of imagePaths) {\n if (ImageDownloader.isImageUrl(path)) {\n urlsToDownload.push(path);\n }\n else {\n // Validate local path exists\n if (!(0,external_fs_.existsSync)(path)) {\n throw new shared_errors/* InvalidImageError */.TD(`Local image file not found: ${path}`, {\n path,\n suggestion: 'Make sure the file path is correct and the file exists',\n });\n }\n localPaths.push(path);\n }\n }\n // Download URLs if any\n if (urlsToDownload.length > 0) {\n logger/* logger */.v.debug(`Downloading ${urlsToDownload.length} images from URLs...`);\n const downloadResults = await this.downloadImages(urlsToDownload);\n const downloadedPaths = downloadResults.map((r) => r.localPath);\n localPaths.push(...downloadedPaths);\n // Log download summary\n const cachedCount = downloadResults.filter((r) => r.cached).length;\n const newCount = downloadResults.filter((r) => !r.cached).length;\n logger/* logger */.v.debug(`Downloaded ${newCount} new images, used ${cachedCount} cached images`);\n }\n if (localPaths.length === 0) {\n throw new shared_errors/* InvalidImageError */.TD('No valid images found', {\n providedPaths: imagePaths.length,\n suggestion: 'Provide at least one valid image URL or local file path',\n });\n }\n return localPaths;\n }\n /**\n * Get the save directory path\n */\n getSaveDir() {\n return this.saveDir;\n }\n}\n// Export a default instance\nlet defaultDownloader = null;\nfunction getImageDownloader(saveDir) {\n if (!defaultDownloader || (saveDir && defaultDownloader.getSaveDir() !== saveDir)) {\n defaultDownloader = new ImageDownloader(saveDir);\n }\n return defaultDownloader;\n}\n\n// EXTERNAL MODULE: ./src/shared/selectors.ts\nvar selectors = __webpack_require__(805);\n;// ./src/core/publishing/publish-base.service.ts\n/**\n * Publishing service for XHS MCP Server\n */\n\n\n\n\n\n\n// Constants for video publishing\nconst VIDEO_TIMEOUTS = {\n PAGE_LOAD: 3000,\n TAB_SWITCH: 2000,\n VIDEO_PROCESSING: 10000,\n CONTENT_WAIT: 1000,\n UPLOAD_READY: 1000,\n UPLOAD_START: 3000,\n PROCESSING_CHECK: 3000,\n COMPLETION_CHECK: 2000,\n PROCESSING_TIMEOUT: 120000, // 2 minutes\n COMPLETION_TIMEOUT: 300000, // 5 minutes\n};\nconst SELECTORS = {\n FILE_INPUT: selectors/* COMMON_FILE_SELECTORS */.mR.FILE_INPUT,\n SUCCESS_INDICATORS: selectors/* COMMON_STATUS_SELECTORS */.aB.SUCCESS,\n ERROR_INDICATORS: selectors/* COMMON_STATUS_SELECTORS */.aB.ERROR,\n PROCESSING_INDICATORS: selectors/* COMMON_STATUS_SELECTORS */.aB.PROCESSING,\n COMPLETION_INDICATORS: [\n '.upload-complete',\n '.processing-complete',\n '.video-ready',\n '[class*=\"complete\"]',\n '[class*=\"ready\"]',\n ],\n TOAST_SELECTORS: selectors/* COMMON_STATUS_SELECTORS */.aB.TOAST,\n PUBLISH_PAGE_INDICATORS: [\n 'div.upload-content',\n 'div.submit',\n '.creator-editor',\n '.video-upload-container',\n 'input[type=\"file\"]',\n ],\n};\nconst TEXT_PATTERNS = selectors/* COMMON_TEXT_PATTERNS */.mu;\nclass PublishBaseService extends base_service/* BaseService */.d {\n imageDownloader;\n constructor(config) {\n super(config);\n this.imageDownloader = new ImageDownloader('./temp_images');\n }\n // Helper methods for element detection and text matching\n async findElementBySelectors(page, selectors) {\n for (const selector of selectors) {\n const element = await page.$(selector);\n if (element) {\n logger/* logger */.v.debug(`Found element with selector: ${selector}`);\n return element;\n }\n }\n return null;\n }\n async getElementText(element) {\n try {\n return await element.page().evaluate((el) => el.textContent, element);\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to get element text: ${error}`);\n return null;\n }\n }\n async checkTextPatterns(text, patterns) {\n if (!text)\n return false;\n return patterns.some((pattern) => text.includes(pattern));\n }\n async checkElementForPatterns(page, selectors, patterns) {\n for (const selector of selectors) {\n const element = await page.$(selector);\n if (element) {\n const text = await this.getElementText(element);\n if (text && (await this.checkTextPatterns(text, patterns))) {\n return { found: true, text, element };\n }\n }\n }\n return { found: false };\n }\n async waitForCondition(condition, timeout, checkInterval = 1000, errorMessage) {\n const startTime = Date.now();\n while (Date.now() - startTime < timeout) {\n if (await condition()) {\n return;\n }\n await (0,utils/* sleep */.yy)(checkInterval);\n }\n throw new shared_errors/* PublishError */.S1(errorMessage);\n }\n async fillTitle(page, title) {\n // Wait for a likely title input to appear\n try {\n await page.waitForSelector('input.c-input_inner, input.c-input, input[placeholder*=\"标题\"], .title-input input, input[class*=\"title\"]', { timeout: 10000 });\n }\n catch (error) {\n // Continue without waiting if not found purely by selector\n }\n const titleSelectors = [\n 'input.c-input_inner', // specific for recent Xiaohongshu creator UI\n 'input.c-input',\n 'input[placeholder*=\"标题\"]',\n 'input[placeholder*=\"填写标题会有更多赞哦\"]',\n 'input[placeholder*=\"title\"]',\n 'input[data-placeholder*=\"标题\"]',\n '.title-input input',\n 'input[placeholder*=\"请输入标题\"]',\n 'input[name=\"title\"]',\n 'input[id*=\"title\"]',\n 'input[class*=\"title\"]',\n 'input[type=\"text\"]', // Fallbacks\n 'div[contenteditable=\"true\"]',\n 'textarea[placeholder*=\"标题\"]',\n 'textarea[placeholder*=\"title\"]',\n ];\n for (const selector of titleSelectors) {\n try {\n const titleInput = await page.$(selector);\n if (titleInput) {\n // Scroll into view just in case it's off screen\n await page.evaluate((el) => {\n if (el && typeof el.scrollIntoView === 'function') {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n }, titleInput);\n await (0,utils/* sleep */.yy)(500);\n const isVisible = await titleInput.isIntersectingViewport();\n if (isVisible) {\n await titleInput.click();\n await (0,utils/* sleep */.yy)(500); // Wait for focus\n // clear existing input if any\n await titleInput.click({ clickCount: 3 });\n await titleInput.press('Backspace');\n await titleInput.type(title);\n return;\n }\n }\n }\n catch (error) {\n // Continue to next selector\n }\n }\n // If no specific input found, try to find any visible input or textarea on the page\n try {\n const allInputs = await page.$$('input, textarea');\n for (let i = 0; i < allInputs.length; i++) {\n const input = allInputs[i];\n try {\n const type = await page.evaluate((el) => el.getAttribute('type'), input);\n // avoid file inputs or hidden inputs\n if (type !== 'file' && type !== 'hidden') {\n await page.evaluate((el) => {\n if (el && typeof el.scrollIntoView === 'function') {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n }, input);\n await (0,utils/* sleep */.yy)(500);\n const isVisible = await input.isIntersectingViewport();\n if (isVisible) {\n await input.click();\n await (0,utils/* sleep */.yy)(500);\n // clear existing input if any\n await input.click({ clickCount: 3 });\n await input.press('Backspace');\n await input.type(title);\n return;\n }\n }\n }\n catch (error) {\n // Continue to next input\n }\n }\n }\n catch (error) {\n // Fall through to error\n }\n throw new shared_errors/* PublishError */.S1('Could not find title input field');\n }\n async findContentElement(page) {\n try {\n // Strategy 1: Try div[contenteditable=\"true\"] (simple and direct)\n const contentEditable = await page.$('div[contenteditable=\"true\"]');\n if (contentEditable) {\n const isVisible = await contentEditable.isIntersectingViewport();\n if (isVisible) {\n return contentEditable;\n }\n }\n // Strategy 2: Try div.tiptap.ProseMirror (primary selector for creator platform)\n const tiptapEditor = await page.$('div.tiptap.ProseMirror');\n if (tiptapEditor) {\n const isVisible = await tiptapEditor.isIntersectingViewport();\n if (isVisible) {\n return tiptapEditor;\n }\n }\n // Strategy 3: Try div[role=\"textbox\"][contenteditable=\"true\"] (specific selector)\n const roleTextbox = await page.$('div[role=\"textbox\"][contenteditable=\"true\"]');\n if (roleTextbox) {\n const isVisible = await roleTextbox.isIntersectingViewport();\n if (isVisible) {\n return roleTextbox;\n }\n }\n // Strategy 4: Try div.ql-editor (legacy selector)\n const qlEditor = await page.$('div.ql-editor');\n if (qlEditor) {\n return qlEditor;\n }\n // Strategy 5: Try to find textarea or contenteditable\n const contentSelectors = [\n '.tiptap.ProseMirror',\n 'textarea[placeholder*=\"正文\"]',\n 'textarea[multiline]',\n 'div[data-placeholder*=\"正文\"]',\n '.content-editor',\n 'div[role=\"textbox\"]',\n 'textbox[role=\"textbox\"]',\n 'textbox[multiline]',\n ];\n for (const selector of contentSelectors) {\n const element = await page.$(selector);\n if (element) {\n return element;\n }\n }\n // Strategy 6: Try to find any multiline textbox (fallback)\n const multilineTextboxes = await page.$$('textbox[multiline]');\n for (const element of multilineTextboxes) {\n const isVisible = await element.isIntersectingViewport();\n if (isVisible) {\n return element;\n }\n }\n return null;\n }\n catch (error) {\n return null;\n }\n }\n async findTextboxByPlaceholder(page) {\n try {\n // Find all p elements\n const pElements = await page.$$('p');\n // Look for element with data-placeholder containing \"输入正文描述\"\n for (const p of pElements) {\n const placeholder = await page.evaluate((el) => el.getAttribute('data-placeholder'), p);\n if (placeholder?.includes('输入正文描述')) {\n return p;\n }\n }\n return null;\n }\n catch (error) {\n return null;\n }\n }\n async findTextboxParent(page, element) {\n try {\n return await page.evaluateHandle((el) => el.parentElement, element);\n }\n catch (error) {\n return null;\n }\n }\n async fillContent(page, content) {\n // Wait for content area to appear\n try {\n await page.waitForSelector('div[role=\"textbox\"][contenteditable=\"true\"], .tiptap.ProseMirror, div[contenteditable=\"true\"], textarea, [role=\"textbox\"], .ql-editor, textbox[multiline]', { timeout: 10000 });\n }\n catch (error) {\n // Continue without waiting\n }\n let contentElement = await this.findContentElement(page);\n if (!contentElement) {\n // Try alternative approach\n const textboxElement = await this.findTextboxByPlaceholder(page);\n if (textboxElement) {\n contentElement = await this.findTextboxParent(page, textboxElement);\n }\n }\n if (!contentElement) {\n // Try to find any contenteditable or textarea element\n try {\n const allContentElements = await page.$$('div[role=\"textbox\"][contenteditable=\"true\"], .tiptap.ProseMirror, div[contenteditable=\"true\"], textarea, [role=\"textbox\"], .ql-editor, p[contenteditable=\"true\"], textbox[multiline]');\n for (let i = 0; i < allContentElements.length; i++) {\n const element = allContentElements[i];\n try {\n const isVisible = await element.isIntersectingViewport();\n const tagName = await page.evaluate((el) => el.tagName, element);\n const contentEditable = await page.evaluate((el) => el.getAttribute('contenteditable'), element);\n const role = await page.evaluate((el) => el.getAttribute('role'), element);\n const className = await page.evaluate((el) => el.className, element);\n const multiline = await page.evaluate((el) => el.getAttribute('multiline'), element);\n if (isVisible &&\n (contentEditable === 'true' ||\n tagName === 'TEXTAREA' ||\n role === 'textbox' ||\n className.includes('ql-editor') ||\n className.includes('tiptap') ||\n multiline === '')) {\n contentElement = element;\n break;\n }\n }\n catch (error) {\n // Continue to next element\n }\n }\n }\n catch (error) {\n // Continue to next strategy\n }\n }\n if (!contentElement) {\n // Last resort: try to find any element that might be for content\n try {\n const allElements = await page.$$('*');\n for (let i = 0; i < Math.min(allElements.length, 50); i++) {\n // Limit to first 50 elements\n const element = allElements[i];\n try {\n const isVisible = await element.isIntersectingViewport();\n const tagName = await page.evaluate((el) => el.tagName, element);\n const contentEditable = await page.evaluate((el) => el.getAttribute('contenteditable'), element);\n const className = await page.evaluate((el) => el.className, element);\n const placeholder = await page.evaluate((el) => el.getAttribute('placeholder'), element);\n if (isVisible &&\n (contentEditable === 'true' ||\n tagName === 'TEXTAREA' ||\n className.includes('content') ||\n className.includes('editor') ||\n placeholder?.includes('内容') ||\n placeholder?.includes('正文'))) {\n contentElement = element;\n break;\n }\n }\n catch (error) {\n // Ignore errors for individual elements\n }\n }\n }\n catch (error) {\n // Fall through to error\n }\n }\n if (!contentElement) {\n throw new shared_errors/* PublishError */.S1('Could not find content input field');\n }\n try {\n await contentElement.click();\n await (0,utils/* sleep */.yy)(500); // Wait for focus\n await contentElement.type(content);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to fill content: ${error}`);\n }\n }\n async inputTags(page, contentElement, tags) {\n const tagList = tags\n .split(',')\n .map((tag) => tag.trim())\n .filter((tag) => tag.length > 0);\n for (const tag of tagList) {\n await this.inputTag(page, contentElement, tag);\n }\n }\n async inputTag(page, contentElement, tag) {\n try {\n // Type the tag\n await contentElement.type(`#${tag}`);\n await (0,utils/* sleep */.yy)(1000);\n // Try to find topic suggestion container\n const topicContainer = await page.$('#creator-editor-topic-container');\n if (topicContainer) {\n const firstItem = await topicContainer.$('.item');\n if (firstItem) {\n await firstItem.click();\n await (0,utils/* sleep */.yy)(500);\n }\n }\n else {\n // Press Enter to confirm the tag\n await contentElement.press('Enter');\n await (0,utils/* sleep */.yy)(500);\n // Press Space to separate tags\n await contentElement.press('Space');\n await (0,utils/* sleep */.yy)(200);\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to add tag ${tag}: ${error}`);\n }\n }\n async addTags(page, tags) {\n try {\n const contentElement = await this.findContentElement(page);\n if (contentElement) {\n await this.inputTags(page, contentElement, tags);\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to add tags: ${error}`);\n }\n }\n async submitPost(page) {\n try {\n // Find the submit button by text \"发布\"\n const buttons = await page.$$('button');\n let submitButton = null;\n for (const btn of buttons) {\n const text = await btn.evaluate(el => el.textContent?.trim());\n if (text === '发布') {\n submitButton = btn;\n break;\n }\n }\n if (!submitButton) {\n // Try span or div as fallback\n const submitSelector = 'div.submit, .submit-btn, .publish-btn';\n submitButton = await page.$(submitSelector);\n if (!submitButton) {\n throw new shared_errors/* PublishError */.S1('Could not find submit button');\n }\n }\n await submitButton.click();\n logger/* logger */.v.debug('Clicked submit button natively');\n await (0,utils/* sleep */.yy)(2000);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to click submit button: ${error}`);\n }\n }\n async isElementVisible(element) {\n try {\n return await element.isIntersectingViewport();\n }\n catch (error) {\n return false;\n }\n }\n async waitForPublishCompletion(page) {\n const maxWaitTime = 60000; // 60 seconds\n const startTime = Date.now();\n while (Date.now() - startTime < maxWaitTime) {\n // Check for success indicators\n const successIndicators = [\n '.success-message',\n '.publish-success',\n '[data-testid=\"publish-success\"]',\n '.toast-success',\n ];\n for (const selector of successIndicators) {\n const element = await page.$(selector);\n if (element) {\n await (0,utils/* sleep */.yy)(2000); // Wait a bit more for any final processing\n return await this.extractNoteIdFromPage(page);\n }\n }\n // Check for error indicators\n const errorIndicators = [\n '.error-message',\n '.publish-error',\n '[data-testid=\"publish-error\"]',\n '.toast-error',\n '.error-toast',\n ];\n for (const selector of errorIndicators) {\n const element = await page.$(selector);\n if (element) {\n const errorText = await page.evaluate((el) => el.textContent, element);\n throw new shared_errors/* PublishError */.S1(`Publish failed with error: ${errorText}`);\n }\n }\n // Check if we're still on the publish page\n const publishPageIndicators = ['div.upload-content', 'div.submit', '.creator-editor'];\n let stillOnPublishPage = false;\n for (const selector of publishPageIndicators) {\n const element = await page.$(selector);\n if (element) {\n stillOnPublishPage = true;\n break;\n }\n }\n if (!stillOnPublishPage) {\n // We've left the publish page, likely successful\n logger/* logger */.v.debug('Left publish page, assuming success');\n return await this.extractNoteIdFromPage(page);\n }\n // Check for toast messages\n const toastSelectors = ['.toast', '.message', '.notification', '[role=\"alert\"]'];\n for (const selector of toastSelectors) {\n const element = await page.$(selector);\n if (element) {\n const toastText = await page.evaluate((el) => el.textContent, element);\n if (toastText) {\n if (toastText.includes('成功') || toastText.includes('success')) {\n logger/* logger */.v.debug(`Found success toast: ${toastText}`);\n return await this.extractNoteIdFromPage(page);\n }\n else if (toastText.includes('失败') ||\n toastText.includes('error') ||\n toastText.includes('错误')) {\n throw new shared_errors/* PublishError */.S1(`Publish failed: ${toastText}`);\n }\n }\n }\n }\n await (0,utils/* sleep */.yy)(1000); // Wait before next check\n }\n throw new shared_errors/* PublishError */.S1('Publish completion timeout - could not determine result');\n }\n async extractNoteIdFromPage(page) {\n try {\n // Method 1: Try to extract from URL if redirected to note page\n const currentUrl = page.url();\n logger/* logger */.v.debug(`Current URL after publish: ${currentUrl}`);\n // Check if we're on a note page (URL contains /explore/ or /discovery/)\n const noteIdMatch = currentUrl.match(/\\/explore\\/([a-f0-9]+)/i) ||\n currentUrl.match(/\\/discovery\\/([a-f0-9]+)/i);\n if (noteIdMatch && noteIdMatch[1]) {\n const noteId = noteIdMatch[1];\n logger/* logger */.v.debug(`Extracted note ID from URL: ${noteId}`);\n return noteId;\n }\n // Method 2: Try to find note ID in page content or data attributes\n const noteIdFromPage = await page.evaluate(() => {\n // Look for data attributes that might contain note ID\n const elementsWithData = document.querySelectorAll('[data-note-id], [data-id], [data-impression]');\n for (let i = 0; i < elementsWithData.length; i++) {\n const element = elementsWithData[i];\n const noteId = element.getAttribute('data-note-id') ||\n element.getAttribute('data-id') ||\n element.getAttribute('data-impression');\n if (noteId && noteId.length > 10) { // Note IDs are typically long\n return noteId;\n }\n }\n // Look for links to note pages\n const noteLinks = document.querySelectorAll('a[href*=\"/explore/\"], a[href*=\"/discovery/\"]');\n for (let i = 0; i < noteLinks.length; i++) {\n const link = noteLinks[i];\n const href = link.getAttribute('href');\n if (href) {\n const match = href.match(/\\/explore\\/([a-f0-9]+)/i) ||\n href.match(/\\/discovery\\/([a-f0-9]+)/i);\n if (match && match[1]) {\n return match[1];\n }\n }\n }\n // Look for any text that looks like a note ID (long hex string)\n const textContent = document.body.textContent || '';\n const noteIdPattern = /[a-f0-9]{20,}/gi;\n const matches = textContent.match(noteIdPattern);\n if (matches && matches.length > 0) {\n // Return the first long hex string found\n return matches[0];\n }\n return null;\n });\n if (noteIdFromPage) {\n logger/* logger */.v.debug(`Extracted note ID from page content: ${noteIdFromPage}`);\n return noteIdFromPage;\n }\n // Method 3: Try to get the latest note ID using NoteService (fallback)\n logger/* logger */.v.debug('Could not extract note ID from page, trying fallback method');\n try {\n // Wait a bit for the note to be processed\n await (0,utils/* sleep */.yy)(5000);\n // Use NoteService to get the latest note ID\n const { NoteService } = await Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 7482));\n const noteService = new NoteService(this.getConfig());\n const userNotes = await noteService.getUserNotes(1); // Get only the latest note\n if (userNotes.success && userNotes.data && userNotes.data.length > 0) {\n const latestNoteId = userNotes.data[0].id;\n logger/* logger */.v.debug(`Extracted note ID from NoteService: ${latestNoteId}`);\n return latestNoteId;\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Fallback note ID extraction failed: ${error}`);\n }\n logger/* logger */.v.debug('Could not extract note ID from any method');\n return null;\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to extract note ID: ${error}`);\n return null;\n }\n }\n validateContentInputs(type, title, content, mediaPaths) {\n if (!title?.trim()) {\n throw new shared_errors/* PublishError */.S1(`${type === 'image' ? 'Image' : 'Video'} title cannot be empty`);\n }\n if (!content?.trim()) {\n throw new shared_errors/* PublishError */.S1(`${type === 'image' ? 'Image' : 'Video'} content cannot be empty`);\n }\n if (!mediaPaths || mediaPaths.length === 0) {\n throw new shared_errors/* PublishError */.S1(`${type === 'image' ? 'Image' : 'Video'} paths are required`);\n }\n if (type === 'image' && mediaPaths.length > 18) {\n throw new shared_errors/* PublishError */.S1('Maximum 18 images allowed for image posts');\n }\n if (type === 'video' && mediaPaths.length !== 1) {\n throw new shared_errors/* PublishError */.S1('Video publishing requires exactly one video file');\n }\n }\n}\n\n;// ./src/core/publishing/publish-image.service.ts\n\n\n\n\n\n\n\nclass ImagePublishService extends PublishBaseService {\n async publishNote(title, content, imagePaths, tags = '', browserPath) {\n // Validate inputs\n if (!title?.trim()) {\n throw new shared_errors/* PublishError */.S1('Note title cannot be empty');\n }\n // Validate title width (CJK characters count as 2 units, ASCII as 1)\n assertTitleWidthValid(title);\n logger/* logger */.v.debug(`Title width validation passed: \"${title}\" (${getTitleWidth(title)} units)`);\n if (!content?.trim()) {\n throw new shared_errors/* PublishError */.S1('Note content cannot be empty');\n }\n if (!imagePaths || imagePaths.length === 0) {\n throw new shared_errors/* PublishError */.S1('At least one image is required');\n }\n // Process image paths - download URLs and validate local paths\n const resolvedPaths = await this.validateAndResolveImagePaths(imagePaths);\n // Wait for upload container selector\n const uploadSelector = 'div.upload-content';\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.creatorPublishUrl);\n // Wait for page to load\n await (0,utils/* sleep */.yy)(3000);\n // First, try to switch to the image/text upload tab\n await this.clickUploadTab(page);\n // Wait for tab switch to complete\n await (0,utils/* sleep */.yy)(3000);\n // Check if tab switch was successful and retry if needed\n const pageState = await page.evaluate(() => {\n return {\n buttonTexts: Array.from(document.querySelectorAll('button, div[role=\"button\"]'))\n .map((el) => el.textContent?.trim())\n .filter((t) => t),\n };\n });\n // If still showing video upload, try clicking the tab again\n if (pageState.buttonTexts.includes('上传视频') &&\n !pageState.buttonTexts.includes('上传图文')) {\n await this.clickUploadTab(page);\n await (0,utils/* sleep */.yy)(3000);\n }\n let hasUploadContainer = await this.getBrowserManager().tryWaitForSelector(page, uploadSelector, 30000);\n if (!hasUploadContainer) {\n // Try alternative selectors for upload container\n const alternativeSelectors = [\n 'div.upload-content',\n '.upload-content',\n 'div[class*=\"upload\"]',\n 'div[class*=\"image\"]',\n 'input[type=\"file\"]',\n ];\n for (const selector of alternativeSelectors) {\n hasUploadContainer = await this.getBrowserManager().tryWaitForSelector(page, selector, 10000);\n if (hasUploadContainer) {\n break;\n }\n }\n }\n if (!hasUploadContainer) {\n throw new shared_errors/* PublishError */.S1('Could not find upload container on publish page');\n }\n // Upload images\n await this.uploadImages(page, resolvedPaths);\n // Wait for images to be processed (large files need more time on XHS)\n logger/* logger */.v.debug('Waiting 15 seconds for images to be uploaded and processed...');\n await (0,utils/* sleep */.yy)(15000);\n // Wait for page to transition to edit mode (check for title or content input)\n try {\n await page.waitForSelector('input[placeholder*=\"标题\"], div[contenteditable=\"true\"], .tiptap.ProseMirror', { timeout: 15000 });\n }\n catch (error) {\n // Continue without waiting\n }\n // Wait a bit for the page to settle after image upload\n await (0,utils/* sleep */.yy)(2000);\n // Fill in title\n await this.fillTitle(page, title);\n // Wait a bit more for content area to appear\n await (0,utils/* sleep */.yy)(2000);\n // Fill in content\n await this.fillContent(page, content);\n // Add tags if provided\n if (tags) {\n await this.addTags(page, tags);\n }\n // Submit the note\n await this.submitPost(page);\n // Wait for completion and check result\n const noteId = await this.waitForPublishCompletion(page);\n // Save cookies\n await this.getBrowserManager().saveCookiesFromPage(page);\n return {\n success: true,\n message: 'Note published successfully',\n title,\n content,\n imageCount: resolvedPaths.length,\n tags,\n url: this.getConfig().xhs.creatorPublishUrl,\n noteId: noteId || undefined,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Publish error: ${error}`);\n throw error;\n }\n }\n /**\n * Process image paths - download URLs and validate local paths\n */\n async validateAndResolveImagePaths(imagePaths) {\n // Use ImageDownloader to process paths (downloads URLs, validates local paths)\n const resolvedPaths = await this.imageDownloader.processImagePaths(imagePaths);\n // Validate resolved paths\n for (const resolvedPath of resolvedPaths) {\n // For local paths that aren't absolute, resolve them\n const fullPath = resolvedPath.startsWith('/') || resolvedPath.match(/^[a-zA-Z]:/)\n ? resolvedPath\n : (0,external_path_.join)(process.cwd(), resolvedPath);\n if (!(0,external_fs_.existsSync)(fullPath)) {\n throw new shared_errors/* InvalidImageError */.TD(`Image file not found: ${resolvedPath}`);\n }\n const stats = (0,external_fs_.statSync)(fullPath);\n if (!stats.isFile()) {\n throw new shared_errors/* InvalidImageError */.TD(`Path is not a file: ${resolvedPath}`);\n }\n // Check file extension\n const ext = resolvedPath.toLowerCase().split('.').pop();\n const allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'];\n if (!ext || !allowedExtensions.includes(ext)) {\n throw new shared_errors/* InvalidImageError */.TD(`Unsupported image format: ${resolvedPath}. Supported: ${allowedExtensions.join(', ')}`);\n }\n }\n if (resolvedPaths.length > 18) {\n throw new shared_errors/* PublishError */.S1('Maximum 18 images allowed');\n }\n return resolvedPaths;\n }\n async clickUploadTab(page) {\n try {\n logger/* logger */.v.debug('Attempting to switch to \"上传图文\" tab using Puppeteer outer native click');\n // Wait for tabs to render\n await page.waitForSelector('.creator-tab', { timeout: 10000 });\n const tabs = await page.$$('.creator-tab');\n let clicked = false;\n for (const tab of tabs) {\n const text = await tab.evaluate(el => el.textContent);\n if (text && (text.includes('上传图文') || text.includes('图文'))) {\n const isVisible = await tab.isIntersectingViewport();\n if (!isVisible) {\n logger/* logger */.v.debug('Found a matching tab, but it is not visible in the viewport. Skipping...');\n continue; // Skip hidden elements\n }\n // Try native click first\n try {\n await tab.click({ delay: 150 });\n logger/* logger */.v.debug('Native Puppeteer click succeeded on tab.');\n }\n catch (e) {\n logger/* logger */.v.debug(`Puppeteer native click failed on visible tab: ${e}`);\n }\n await (0,utils/* sleep */.yy)(500);\n // Force a secondary click on the text itself via evaluate just in case hit area missed\n await tab.evaluate((el) => {\n const span = el.querySelector('span') || el;\n span.click();\n });\n clicked = true;\n logger/* logger */.v.debug('Successfully clicked image tab text match.');\n break;\n }\n }\n if (!clicked) {\n logger/* logger */.v.warn('Could not find visible image tab via textual matching.');\n }\n await (0,utils/* sleep */.yy)(2000);\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to click upload tab: ${error}`);\n }\n }\n async uploadImages(page, imagePaths) {\n try {\n logger/* logger */.v.debug('Uploading images using direct input element targeting');\n const fileInput = await page.$('input[type=\"file\"]');\n if (!fileInput) {\n throw new shared_errors/* PublishError */.S1('Could not find file upload input on page');\n }\n // Ensure the input accepts multiple files and any type to avoid frontend blocks\n await page.evaluate((el) => {\n if (el) {\n el.setAttribute('multiple', 'multiple');\n el.removeAttribute('accept');\n }\n }, fileInput);\n logger/* logger */.v.debug(`Submitting ${imagePaths.length} image paths to file input element`);\n await fileInput.uploadFile(...imagePaths);\n // Dispatch a change event manually in case the framework missed it\n await page.evaluate((el) => {\n if (el) {\n el.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }, fileInput);\n await (0,utils/* sleep */.yy)(15000);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to upload images: ${error}`);\n }\n }\n}\n\n;// ./src/core/publishing/publish-video.service.ts\n\n\n\n\n\n\n\n\nclass VideoPublishService extends PublishBaseService {\n async waitForVideoPublishCompletion(page) {\n logger/* logger */.v.debug('Waiting for video publish completion...');\n let isProcessing = false;\n await this.waitForCondition(async () => {\n // Check for success indicators\n const successResult = await this.checkElementForPatterns(page, SELECTORS.SUCCESS_INDICATORS, TEXT_PATTERNS.SUCCESS);\n if (successResult.found) {\n logger/* logger */.v.debug(`Found success indicator: ${successResult.text}`);\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.COMPLETION_CHECK);\n return true;\n }\n // Check for error indicators\n const errorResult = await this.checkElementForPatterns(page, SELECTORS.ERROR_INDICATORS, TEXT_PATTERNS.ERROR);\n if (errorResult.found) {\n throw new shared_errors/* PublishError */.S1(`Video publish failed with error: ${errorResult.text}`);\n }\n // Check if we've left the publish page (likely success)\n const stillOnPage = await this.findElementBySelectors(page, SELECTORS.PUBLISH_PAGE_INDICATORS);\n if (!stillOnPage) {\n logger/* logger */.v.debug('Left publish page, assuming video publish success');\n return true;\n }\n // Check for processing status\n const processingResult = await this.checkElementForPatterns(page, SELECTORS.PROCESSING_INDICATORS, TEXT_PATTERNS.PROCESSING);\n isProcessing = processingResult.found;\n if (isProcessing) {\n logger/* logger */.v.debug(`Video still processing: ${processingResult.text}`);\n }\n // Check for toast messages\n const toastResult = await this.checkElementForPatterns(page, SELECTORS.TOAST_SELECTORS, TEXT_PATTERNS.SUCCESS);\n if (toastResult.found) {\n logger/* logger */.v.debug(`Found success toast: ${toastResult.text}`);\n return true;\n }\n const errorToastResult = await this.checkElementForPatterns(page, SELECTORS.TOAST_SELECTORS, TEXT_PATTERNS.ERROR);\n if (errorToastResult.found) {\n throw new shared_errors/* PublishError */.S1(`Video publish failed: ${errorToastResult.text}`);\n }\n return false;\n }, VIDEO_TIMEOUTS.COMPLETION_TIMEOUT, isProcessing ? 5000 : VIDEO_TIMEOUTS.COMPLETION_CHECK, 'Video publish completion timeout - could not determine result after 5 minutes');\n // Extract note ID after successful completion\n return await this.extractNoteIdFromPage(page);\n }\n async publishVideo(title, content, videoPath, tags = '', browserPath) {\n // Validate inputs\n this.validateVideoInputs(title, content, videoPath);\n // Validate and resolve video path\n const resolvedVideoPath = this.validateAndResolveVideoPath(videoPath);\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n const noteId = await this.executeVideoPublishWorkflow(page, title, content, resolvedVideoPath, tags);\n // Save cookies\n await this.getBrowserManager().saveCookiesFromPage(page);\n return {\n success: true,\n message: 'Video published successfully',\n title,\n content,\n imageCount: 0, // Videos don't have image count\n tags,\n url: this.getConfig().xhs.creatorVideoPublishUrl,\n noteId: noteId || undefined,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Video publish error: ${error}`);\n throw error;\n }\n }\n validateVideoInputs(title, content, videoPath) {\n if (!title?.trim()) {\n throw new shared_errors/* PublishError */.S1('Video title cannot be empty');\n }\n // Validate title width for video posts too\n assertTitleWidthValid(title);\n logger/* logger */.v.debug(`Video title width validation passed: \"${title}\" (${getTitleWidth(title)} units)`);\n if (!content?.trim()) {\n throw new shared_errors/* PublishError */.S1('Video content cannot be empty');\n }\n if (!videoPath?.trim()) {\n throw new shared_errors/* PublishError */.S1('Video path is required');\n }\n }\n async executeVideoPublishWorkflow(page, title, content, videoPath, tags) {\n // Navigate to video upload page\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.creatorVideoPublishUrl);\n // Wait for page to load\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.PAGE_LOAD);\n // Switch to video upload tab if needed\n await this.clickVideoUploadTab(page);\n // Wait for tab switch to complete\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.TAB_SWITCH);\n // Upload video\n await this.uploadVideo(page, videoPath);\n // Wait for video to be processed (videos take longer than images)\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.VIDEO_PROCESSING);\n // Fill in title\n await this.fillTitle(page, title);\n // Wait a bit for content area to appear\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.CONTENT_WAIT);\n // Fill in content\n await this.fillContent(page, content);\n // Add tags if provided\n if (tags) {\n await this.addTags(page, tags);\n }\n // Submit the video\n await this.submitPost(page);\n // Wait for completion and check result (videos need longer timeout)\n return await this.waitForVideoPublishCompletion(page);\n }\n validateAndResolveVideoPath(videoPath) {\n const resolvedPath = (0,external_path_.join)(process.cwd(), videoPath);\n if (!(0,external_fs_.existsSync)(resolvedPath)) {\n throw new shared_errors/* PublishError */.S1(`Video file not found: ${videoPath}`);\n }\n const stats = (0,external_fs_.statSync)(resolvedPath);\n if (!stats.isFile()) {\n throw new shared_errors/* PublishError */.S1(`Path is not a file: ${videoPath}`);\n }\n // Check file extension\n const ext = videoPath.toLowerCase().split('.').pop();\n const allowedExtensions = ['mp4', 'mov', 'avi', 'mkv', 'webm', 'flv', 'wmv'];\n if (!ext || !allowedExtensions.includes(ext)) {\n throw new shared_errors/* PublishError */.S1(`Unsupported video format: ${videoPath}. Supported: ${allowedExtensions.join(', ')}`);\n }\n // Check file size (XHS typically has limits)\n const maxSizeInMB = 500; // 500MB limit\n const fileSizeInMB = stats.size / (1024 * 1024);\n if (fileSizeInMB > maxSizeInMB) {\n throw new shared_errors/* PublishError */.S1(`Video file too large: ${fileSizeInMB.toFixed(2)}MB. Maximum allowed: ${maxSizeInMB}MB`);\n }\n return resolvedPath;\n }\n async clickVideoUploadTab(page) {\n try {\n // Try multiple selectors for video tab\n const videoTabSelectors = [\n 'div.creator-tab',\n '.creator-tab',\n '[role=\"tab\"]',\n '.tab',\n 'div[class*=\"tab\"]',\n ];\n let tabs = [];\n for (const selector of videoTabSelectors) {\n const foundTabs = await page.$$(selector);\n if (foundTabs.length > 0) {\n tabs = foundTabs;\n break;\n }\n }\n if (tabs.length === 0) {\n logger/* logger */.v.warn('No tabs found for video upload');\n return;\n }\n // Look for the video upload tab specifically\n let videoTab = null;\n for (let i = 0; i < tabs.length; i++) {\n const tab = tabs[i];\n try {\n const isVisible = await tab.isIntersectingViewport();\n if (!isVisible)\n continue;\n const text = await page.evaluate((el) => el.textContent, tab);\n // Check if this is the video upload tab\n if (text &&\n (text.includes('上传视频') || text.includes('视频') || text.includes('video'))) {\n videoTab = tab;\n break;\n }\n }\n catch (error) {\n // Ignore individual tab errors\n }\n }\n if (videoTab) {\n await videoTab.click();\n await (0,utils/* sleep */.yy)(2000); // Wait for tab switch\n }\n else {\n // Fallback: click the first tab (usually video upload)\n const visibleTabs = [];\n for (const tab of tabs) {\n const isVisible = await tab.isIntersectingViewport();\n if (isVisible) {\n visibleTabs.push(tab);\n }\n }\n if (visibleTabs.length > 0) {\n await visibleTabs[0].click(); // Usually the first tab is video upload\n await (0,utils/* sleep */.yy)(2000);\n }\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to click video upload tab: ${error}`);\n }\n }\n async uploadVideo(page, videoPath) {\n logger/* logger */.v.debug(`Uploading video: ${videoPath}`);\n // Find file input element\n const fileInput = await this.findElementBySelectors(page, SELECTORS.FILE_INPUT);\n if (!fileInput) {\n throw new shared_errors/* PublishError */.S1('Could not find file upload input on video upload page');\n }\n try {\n // Wait for the input to be ready\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.UPLOAD_READY);\n // Upload the video file\n await fileInput.uploadFile(videoPath);\n logger/* logger */.v.debug('Video file uploaded, waiting for processing...');\n // Wait for upload to start and show progress\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.UPLOAD_START);\n // Wait for video processing to complete (this can take a while)\n await this.waitForVideoProcessing(page);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to upload video ${videoPath}: ${error}`);\n }\n }\n async waitForVideoProcessing(page) {\n logger/* logger */.v.debug('Waiting for video processing to complete...');\n try {\n await this.waitForCondition(async () => {\n // Check if processing is complete\n const completeResult = await this.checkElementForPatterns(page, SELECTORS.COMPLETION_INDICATORS, TEXT_PATTERNS.SUCCESS);\n if (completeResult.found) {\n logger/* logger */.v.debug(`Video processing complete: ${completeResult.text}`);\n return true;\n }\n // Check if still processing\n const processingResult = await this.checkElementForPatterns(page, SELECTORS.PROCESSING_INDICATORS, TEXT_PATTERNS.PROCESSING);\n if (processingResult.found) {\n logger/* logger */.v.debug(`Video processing: ${processingResult.text}`);\n return false; // Still processing, continue waiting\n }\n // If not processing and no completion indicator, assume it's done\n logger/* logger */.v.debug('No processing indicators found, assuming video processing complete');\n return true;\n }, VIDEO_TIMEOUTS.PROCESSING_TIMEOUT, VIDEO_TIMEOUTS.PROCESSING_CHECK, 'Video processing timeout');\n }\n catch (error) {\n logger/* logger */.v.warn('Video processing timeout, continuing anyway...');\n }\n }\n}\n\n;// ./src/core/publishing/publish.service.ts\n\n\n\nclass PublishService extends base_service/* BaseService */.d {\n imageService;\n videoService;\n constructor(config) {\n super(config);\n this.imageService = new ImagePublishService(config);\n this.videoService = new VideoPublishService(config);\n }\n async publishNote(title, content, imagePaths, tags = '', browserPath) {\n return this.imageService.publishNote(title, content, imagePaths, tags, browserPath);\n }\n async publishVideo(title, content, videoPath, tags = '', browserPath) {\n return this.videoService.publishVideo(title, content, videoPath, tags, browserPath);\n }\n async publishContent(type, title, content, mediaPaths, tags = '', browserPath) {\n if (type === 'image') {\n return this.publishNote(title, content, mediaPaths, tags, browserPath);\n }\n else {\n return this.publishVideo(title, content, mediaPaths[0], tags, browserPath);\n }\n }\n}\n\n// EXTERNAL MODULE: ./src/core/notes/note.service.ts + 1 modules\nvar note_service = __webpack_require__(7482);\n;// ./src/server/handlers/tool.handlers.ts\n/**\n * Tool request handlers for XHS MCP Server\n */\n\n\n\n\n\n\n\n\n\nclass ToolHandlers {\n authService;\n feedService;\n publishService;\n noteService;\n constructor() {\n const config = (0,shared_config/* getConfig */.zj)();\n this.authService = new AuthService(config);\n this.feedService = new FeedService(config);\n this.publishService = new PublishService(config);\n this.noteService = new note_service.NoteService(config);\n }\n async handleAuthLogin(browserPath) {\n // Start login process in background and return immediately\n // This follows the \"instant response\" pattern described in README\n this.authService.login(browserPath).catch((error) => {\n (0,utils/* safeErrorHandler */.ah)(error, 'Background login error', logger/* logger */.v);\n });\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n success: true,\n message: 'Login process started. A browser window will open for you to complete the login.',\n status: 'login_started',\n action: 'browser_opened',\n instructions: [\n '1. Complete the login process in the opened browser window',\n '2. Scan QR code or enter your credentials',\n '3. Login will be automatically verified and cookies saved',\n '4. Use xhs_auth_status to check if login completed',\n ],\n note: 'The login process runs in the background. You can continue using other tools while login completes.',\n }, null, 2),\n },\n ],\n };\n }\n async handleAuthLogout() {\n const result = await this.authService.logout();\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleAuthStatus(browserPath) {\n const result = await this.authService.checkStatus(browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleDiscoverFeeds(browserPath) {\n const result = await this.feedService.getFeedList(browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleSearchNote(keyword, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ keyword }, ['keyword']);\n const result = await this.feedService.searchFeeds(keyword, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleGetNoteDetail(feedId, xsecToken, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ feedId, xsecToken }, ['feedId', 'xsecToken']);\n const result = await this.feedService.getFeedDetail(feedId, xsecToken, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleCommentOnNote(feedId, xsecToken, note, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ feedId, xsecToken, note }, ['feedId', 'xsecToken', 'note']);\n const result = await this.feedService.commentOnFeed(feedId, xsecToken, note, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handlePublishContent(type, title, content, mediaPaths, tags, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ type, title, content, mediaPaths }, [\n 'type',\n 'title',\n 'content',\n 'mediaPaths',\n ]);\n // Validate content type\n if (type !== 'image' && type !== 'video') {\n throw new Error('Content type must be \"image\" or \"video\"');\n }\n // Validate parameter constraints using width-aware title validation\n assertTitleWidthValid(title);\n if (content.length > 1000) {\n throw new Error('Content must be 1000 characters or less');\n }\n // Execute unified publishing process\n const result = await this.publishService.publishContent(type, title, content, mediaPaths, tags, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleGetUserNotes(limit, cursor, browserPath) {\n const result = await this.noteService.getUserNotes(limit, cursor, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleDeleteNote(noteId, lastPublished, browserPath) {\n if (lastPublished) {\n const result = await this.noteService.deleteLastPublishedNote(browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n else if (noteId) {\n const result = await this.noteService.deleteNote(noteId, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n else {\n throw new Error('Either note_id or last_published must be specified');\n }\n }\n async handleToolRequest(name, args = {}) {\n try {\n switch (name) {\n case 'xhs_auth_login':\n return await this.handleAuthLogin(args?.browser_path);\n case 'xhs_auth_logout':\n return await this.handleAuthLogout();\n case 'xhs_auth_status':\n return await this.handleAuthStatus(args?.browser_path);\n case 'xhs_discover_feeds':\n return await this.handleDiscoverFeeds(args?.browser_path);\n case 'xhs_search_note':\n return await this.handleSearchNote(args?.keyword, args?.browser_path);\n case 'xhs_get_note_detail':\n return await this.handleGetNoteDetail(args?.feed_id, args?.xsec_token, args?.browser_path);\n case 'xhs_comment_on_note':\n return await this.handleCommentOnNote(args?.feed_id, args?.xsec_token, args?.note, args?.browser_path);\n case 'xhs_publish_content':\n return await this.handlePublishContent(args?.type, args?.title, args?.content, args?.media_paths, args?.tags, args?.browser_path);\n case 'xhs_get_user_notes':\n return await this.handleGetUserNotes(args?.limit, args?.cursor, args?.browser_path);\n case 'xhs_delete_note':\n return await this.handleDeleteNote(args?.note_id, args?.last_published, args?.browser_path);\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* XHSError */.a_) {\n return (0,utils/* createMcpToolResponse */.q$)(error.toJSON());\n }\n return (0,utils/* createMcpErrorResponse */.mo)(error);\n }\n }\n}\n\n;// ./src/shared/index.ts\n/**\n * Shared utilities, types, and services for XHS MCP Server\n */\n// Configuration and types\n\n\n// Utilities\n\n\n\n\n\n// Error handling and logging\n\n\n// Base service\n\n\n;// ./src/server/handlers/resource.handlers.ts\n/**\n * Resource request handlers for XHS MCP Server\n */\n\n\nclass ResourceHandlers {\n authService;\n constructor() {\n const config = (0,shared_config/* getConfig */.zj)();\n this.authService = new AuthService(config);\n }\n async getCookiesResource() {\n try {\n const cookiesInfo = (0,cookies/* getCookiesInfo */.mL)();\n return JSON.stringify(cookiesInfo, null, 2);\n }\n catch (error) {\n return JSON.stringify({ error: String(error) }, null, 2);\n }\n }\n async getConfigResource() {\n try {\n const configDict = (0,shared_config/* getConfig */.zj)();\n const configWithFramework = {\n ...configDict,\n framework: 'MCP TypeScript',\n version: configDict.server.version,\n };\n return JSON.stringify(configWithFramework, null, 2);\n }\n catch (error) {\n return JSON.stringify({ error: String(error) }, null, 2);\n }\n }\n async getStatusResource() {\n try {\n // Quick status check (but don't fail if it errors)\n let authStatus = { status: 'unknown', error: 'Status check not performed' };\n try {\n authStatus = await this.authService.checkStatus();\n }\n catch (error) {\n authStatus = { status: 'error', error: String(error) };\n }\n const cookiesInfo = (0,cookies/* getCookiesInfo */.mL)();\n const config = (0,shared_config/* getConfig */.zj)();\n const statusData = {\n server: {\n status: 'running',\n name: config.server.name,\n version: config.server.version,\n framework: 'MCP TypeScript',\n },\n authentication: authStatus,\n cookies: {\n fileExists: cookiesInfo.fileExists,\n cookieCount: cookiesInfo.cookieCount,\n },\n capabilities: {\n toolsAvailable: 8,\n promptsAvailable: 0,\n resourcesAvailable: 3,\n },\n };\n return JSON.stringify(statusData, null, 2);\n }\n catch (error) {\n return JSON.stringify({\n server: { status: 'error', error: String(error) },\n framework: 'MCP TypeScript',\n }, null, 2);\n }\n }\n async handleResourceRequest(uri) {\n try {\n let content;\n switch (uri) {\n case 'xhs://cookies':\n content = await this.getCookiesResource();\n break;\n case 'xhs://config':\n content = await this.getConfigResource();\n break;\n case 'xhs://status':\n content = await this.getStatusResource();\n break;\n default:\n throw new Error(`Unknown resource: ${uri}`);\n }\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: content,\n },\n ],\n };\n }\n catch (error) {\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify({ error: String(error) }, null, 2),\n },\n ],\n };\n }\n }\n}\n\n;// ./src/server/schemas/tool.schemas.ts\n/**\n * Tool schemas for XHS MCP Server\n */\nconst XHS_TOOL_SCHEMAS = [\n {\n name: 'xhs_auth_login',\n description: 'Start XiaoHongShu login process.',\n inputSchema: {\n type: 'object',\n properties: {\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_auth_logout',\n description: 'Logout from XiaoHongShu (clears saved cookies).',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n },\n {\n name: 'xhs_auth_status',\n description: 'Check XiaoHongShu login status (fast check with browser).',\n inputSchema: {\n type: 'object',\n properties: {\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_discover_feeds',\n description: 'Get home page feed list.',\n inputSchema: {\n type: 'object',\n properties: {\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_search_note',\n description: 'Search for notes by keyword.',\n inputSchema: {\n type: 'object',\n properties: {\n keyword: {\n type: 'string',\n description: 'Search keyword (required)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['keyword'],\n },\n },\n {\n name: 'xhs_get_note_detail',\n description: 'Get detailed information about a specific note.',\n inputSchema: {\n type: 'object',\n properties: {\n feed_id: {\n type: 'string',\n description: 'Feed ID (required)',\n },\n xsec_token: {\n type: 'string',\n description: 'Security token for the feed (required)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['feed_id', 'xsec_token'],\n },\n },\n {\n name: 'xhs_comment_on_note',\n description: 'Comment on a note.',\n inputSchema: {\n type: 'object',\n properties: {\n feed_id: {\n type: 'string',\n description: 'Feed ID (required)',\n },\n xsec_token: {\n type: 'string',\n description: 'Security token for the feed (required)',\n },\n note: {\n type: 'string',\n description: 'Comment note (required)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['feed_id', 'xsec_token', 'note'],\n },\n },\n {\n name: 'xhs_publish_content',\n description: 'Publish content to XiaoHongShu (supports both images and videos).',\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['image', 'video'],\n description: 'Content type: \"image\" for images, \"video\" for videos (required)',\n },\n title: {\n type: 'string',\n description: 'Content title (required, max 20 characters)',\n maxLength: 20,\n },\n content: {\n type: 'string',\n description: 'Content description (required, max 1000 characters)',\n maxLength: 1000,\n },\n media_paths: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of media file paths (required, non-empty). For images: 1-18 image files. For videos: exactly 1 video file.',\n maxItems: 18,\n },\n tags: {\n type: 'string',\n description: 'Comma-separated tags (optional)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['type', 'title', 'content', 'media_paths'],\n },\n },\n {\n name: 'xhs_get_user_notes',\n description: 'Get current user notes list.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Number of notes to fetch (default: 20)',\n },\n cursor: {\n type: 'string',\n description: 'Pagination cursor for next page',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_delete_note',\n description: 'Delete a user note by ID or delete the last published note.',\n inputSchema: {\n type: 'object',\n properties: {\n note_id: {\n type: 'string',\n description: 'Specific note ID to delete (optional if last_published is true)',\n },\n last_published: {\n type: 'boolean',\n description: 'Delete the last published note (optional if note_id is provided)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n];\nconst XHS_RESOURCE_SCHEMAS = [\n {\n uri: 'xhs://cookies',\n name: 'XHS Authentication Cookies',\n description: 'Current XiaoHongShu authentication cookies and info',\n mimeType: 'application/json',\n },\n {\n uri: 'xhs://config',\n name: 'XHS Server Configuration',\n description: 'XHS MCP server configuration',\n mimeType: 'application/json',\n },\n {\n uri: 'xhs://status',\n name: 'XHS Server Status',\n description: 'Current server and authentication status',\n mimeType: 'application/json',\n },\n];\n\n;// ./src/server/mcp.server.ts\n/**\n * MCP Server for XiaoHongShu Operations\n */\n\n\n\n\n\n\n\nclass XHSMCPServer {\n server;\n toolHandlers;\n resourceHandlers;\n config;\n constructor() {\n this.config = (0,shared_config/* getConfig */.zj)();\n this.toolHandlers = new ToolHandlers();\n this.resourceHandlers = new ResourceHandlers();\n this.server = new esm_server/* Server */.g({\n name: this.config.server.name,\n version: this.config.server.version,\n }, {\n capabilities: {\n tools: {},\n resources: {},\n },\n });\n this.setupToolHandlers();\n this.setupResourceHandlers();\n }\n setupToolHandlers() {\n this.server.setRequestHandler(types/* CallToolRequestSchema */.FT, async (request) => {\n const { name, arguments: args } = request.params;\n return await this.toolHandlers.handleToolRequest(name, args);\n });\n this.server.setRequestHandler(types/* ListToolsRequestSchema */.gW, async () => {\n return {\n tools: XHS_TOOL_SCHEMAS,\n };\n });\n }\n setupResourceHandlers() {\n this.server.setRequestHandler(types/* ListResourcesRequestSchema */.OI, async () => {\n return {\n resources: XHS_RESOURCE_SCHEMAS,\n };\n });\n this.server.setRequestHandler(types/* ReadResourceRequestSchema */.R6, async (request) => {\n const { uri } = request.params;\n return await this.resourceHandlers.handleResourceRequest(uri);\n });\n }\n async start() {\n const transport = new stdio/* StdioServerTransport */.S();\n await this.server.connect(transport);\n // Don't log to stderr in stdio mode to avoid interfering with MCP protocol\n }\n}\n\n;// external \"express\"\nconst external_express_namespaceObject = require(\"express\");\nvar external_express_default = /*#__PURE__*/__webpack_require__.n(external_express_namespaceObject);\n;// external \"cors\"\nconst external_cors_namespaceObject = require(\"cors\");\nvar external_cors_default = /*#__PURE__*/__webpack_require__.n(external_cors_namespaceObject);\n// EXTERNAL MODULE: external \"node:crypto\"\nvar external_node_crypto_ = __webpack_require__(7598);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/sse.js\nvar sse = __webpack_require__(4375);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js\nvar streamableHttp = __webpack_require__(8144);\n;// ./src/server/http.server.ts\n/**\n * HTTP Server with SSE and Streamable HTTP Transport Support\n */\n\n\n\n\n\n\n\n\n\n\n\n\nclass XHSHTTPMCPServer {\n app;\n config;\n toolHandlers;\n resourceHandlers;\n transports = new Map();\n port;\n constructor(port = 3000) {\n this.port = port;\n this.config = (0,shared_config/* getConfig */.zj)();\n this.toolHandlers = new ToolHandlers();\n this.resourceHandlers = new ResourceHandlers();\n this.app = external_express_default()();\n this.setupMiddleware();\n this.setupRoutes();\n }\n setupMiddleware() {\n // Parse JSON bodies\n this.app.use(external_express_default().json());\n // Configure CORS to expose Mcp-Session-Id header for browser-based clients\n this.app.use(external_cors_default()({\n origin: '*', // Allow all origins - adjust as needed for production\n exposedHeaders: ['Mcp-Session-Id'],\n }));\n }\n setupRoutes() {\n // Streamable HTTP Transport (Protocol version 2025-03-26)\n this.app.all('/mcp', this.handleStreamableHTTP.bind(this));\n // Deprecated HTTP+SSE Transport (Protocol version 2024-11-05)\n this.app.get('/sse', this.handleSSEConnection.bind(this));\n this.app.post('/messages', this.handleSSEMessage.bind(this));\n // Health check endpoint\n this.app.get('/health', (req, res) => {\n res.json({\n status: 'healthy',\n server: this.config.server.name,\n version: this.config.server.version,\n transports: ['streamable-http', 'sse'],\n });\n });\n }\n async handleStreamableHTTP(req, res) {\n console.log(`Received ${req.method} request to /mcp`);\n try {\n // Check for existing session ID\n const sessionId = req.headers['mcp-session-id'];\n let transport;\n if (sessionId && this.transports.has(sessionId)) {\n const existingTransport = this.transports.get(sessionId);\n if (existingTransport instanceof streamableHttp/* StreamableHTTPServerTransport */.D) {\n transport = existingTransport;\n }\n else {\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: Session exists but uses a different transport protocol',\n },\n id: null,\n });\n return;\n }\n }\n else if (!sessionId && req.method === 'POST' && (0,types/* isInitializeRequest */.eK)(req.body)) {\n // Create new Streamable HTTP transport\n transport = new streamableHttp/* StreamableHTTPServerTransport */.D({\n sessionIdGenerator: () => (0,external_node_crypto_.randomUUID)(),\n onsessioninitialized: (sessionId) => {\n console.log(`StreamableHTTP session initialized with ID: ${sessionId}`);\n this.transports.set(sessionId, transport);\n },\n onsessionclosed: (sessionId) => {\n console.log(`StreamableHTTP session closed: ${sessionId}`);\n this.transports.delete(sessionId);\n },\n });\n // Set up onclose handler to clean up transport when closed\n transport.onclose = () => {\n const sid = transport.sessionId;\n if (sid && this.transports.has(sid)) {\n console.log(`Transport closed for session ${sid}, removing from transports map`);\n this.transports.delete(sid);\n }\n };\n // Connect the transport to the MCP server\n const server = this.createMCPServer();\n await server.connect(transport);\n }\n else {\n // Invalid request - no session ID or not initialization request\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: No valid session ID provided',\n },\n id: null,\n });\n return;\n }\n // Handle the request with the transport\n await transport.handleRequest(req, res, req.body);\n }\n catch (error) {\n console.error('Error handling Streamable HTTP request:', error);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n async handleSSEConnection(req, res) {\n console.log('Received GET request to /sse (deprecated SSE transport)');\n try {\n const transport = new sse/* SSEServerTransport */.K('/messages', res);\n this.transports.set(transport.sessionId, transport);\n res.on('close', () => {\n this.transports.delete(transport.sessionId);\n });\n const server = this.createMCPServer();\n await server.connect(transport);\n }\n catch (error) {\n console.error('Error handling SSE connection:', error);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n async handleSSEMessage(req, res) {\n const sessionId = req.query.sessionId;\n try {\n const transport = this.transports.get(sessionId);\n if (!transport || !(transport instanceof sse/* SSEServerTransport */.K)) {\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: Session exists but uses a different transport protocol',\n },\n id: null,\n });\n return;\n }\n await transport.handlePostMessage(req, res, req.body);\n }\n catch (error) {\n console.error('Error handling SSE message:', error);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n createMCPServer() {\n const server = new esm_server/* Server */.g({\n name: this.config.server.name,\n version: this.config.server.version,\n }, {\n capabilities: {\n tools: {},\n resources: {},\n },\n });\n // Setup tool handlers\n server.setRequestHandler(types/* CallToolRequestSchema */.FT, async (request) => {\n const { name, arguments: args } = request.params;\n return await this.toolHandlers.handleToolRequest(name, args);\n });\n server.setRequestHandler(types/* ListToolsRequestSchema */.gW, async () => {\n return {\n tools: XHS_TOOL_SCHEMAS,\n };\n });\n // Setup resource handlers\n server.setRequestHandler(types/* ListResourcesRequestSchema */.OI, async () => {\n return {\n resources: XHS_RESOURCE_SCHEMAS,\n };\n });\n server.setRequestHandler(types/* ReadResourceRequestSchema */.R6, async (request) => {\n const { uri } = request.params;\n return await this.resourceHandlers.handleResourceRequest(uri);\n });\n return server;\n }\n async start() {\n return new Promise((resolve, reject) => {\n const server = this.app.listen(this.port, (error) => {\n if (error) {\n console.error('Failed to start HTTP server:', error);\n reject(error);\n return;\n }\n console.log(`XHS MCP HTTP Server listening on port ${this.port}`);\n console.log(`\n==============================================\nSUPPORTED TRANSPORT OPTIONS:\n\n1. Streamable HTTP (Protocol version: 2025-03-26)\n Endpoint: /mcp\n Methods: GET, POST, DELETE\n Usage:\n - Initialize with POST to /mcp\n - Establish SSE stream with GET to /mcp\n - Send requests with POST to /mcp\n - Terminate session with DELETE to /mcp\n\n2. HTTP + SSE (Protocol version: 2024-11-05)\n Endpoints: /sse (GET) and /messages (POST)\n Usage:\n - Establish SSE stream with GET to /sse\n - Send requests with POST to /messages?sessionId=<id>\n\n3. Health Check\n Endpoint: /health\n Method: GET\n Usage: Check server status and supported transports\n==============================================\n`);\n resolve();\n });\n // Handle server shutdown\n process.on('SIGINT', async () => {\n console.log('Shutting down HTTP server...');\n // Close all active transports to properly clean up resources\n for (const [sessionId, transport] of this.transports) {\n try {\n console.log(`Closing transport for session ${sessionId}`);\n await transport.close();\n }\n catch (error) {\n console.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n server.close(() => {\n console.log('HTTP server shutdown complete');\n process.exit(0);\n });\n });\n process.on('SIGTERM', async () => {\n console.log('Shutting down HTTP server...');\n // Close all active transports to properly clean up resources\n for (const [sessionId, transport] of this.transports) {\n try {\n console.log(`Closing transport for session ${sessionId}`);\n await transport.close();\n }\n catch (error) {\n console.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n server.close(() => {\n console.log('HTTP server shutdown complete');\n process.exit(0);\n });\n });\n });\n }\n async stop() {\n // Close all active transports\n for (const [sessionId, transport] of this.transports) {\n try {\n await transport.close();\n }\n catch (error) {\n console.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n }\n}\n\n;// ./src/server/handlers/index.ts\n/**\n * Request handlers for XHS MCP Server\n */\n\n\n\n;// ./src/server/index.ts\n/**\n * Server implementation for XHS MCP Server\n */\n\n\n\n\n;// ./src/cli/cli.ts\n//#!/usr/bin/env node\n/**\n * Unified CLI for XiaoHongShu operations\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * CLI utility functions\n */\nclass CLIUtils {\n program;\n constructor(program) {\n this.program = program;\n }\n formatErrorMessage(error) {\n const raw = error instanceof Error ? (error.stack ?? error.message) : String(error);\n // Handle specific error patterns\n if (/Executable doesn't exist|puppeteer browsers install/i.test(raw)) {\n return 'Chromium is not installed. Run: npx puppeteer browsers install chrome or xhs-mcp browser';\n }\n // For user-facing errors, just return the message without stack trace\n if (error instanceof Error) {\n // Check if it's a known error type that should show just the message\n if (error.message.includes('Either --note-id or --last-published must be specified') ||\n error.message.includes('Please specify either') ||\n error.message.includes('User not logged in') ||\n error.message.includes('Note not found') ||\n error.message.includes('Delete button not found')) {\n return error.message;\n }\n // For other errors, show a cleaner version\n const condensed = raw\n .replace(/[\\s\\S]*?Looks like Puppeteer[\\s\\S]*?Please run the following command to download new browsers:[\\s\\S]*?npx puppeteer browsers install[\\s\\S]*?(Puppeteer Team[\\s\\S]*?)*?/m, '')\n .replace(/[\\u2500-\\u257F]+/g, '') // box-drawing characters\n .replace(/\\s+at\\s+.*$/gm, '') // Remove stack trace lines\n .trim();\n return condensed || error.message;\n }\n return String(error);\n }\n writeJson(output, exitCode = 0) {\n const compact = this.program.getOptionValue?.('compact') === true;\n const json = compact ? JSON.stringify(output) : JSON.stringify(output, null, 2);\n process.stdout.write(`${json}\\n`);\n process.exit(exitCode);\n }\n printSuccess(result, message) {\n // If result already has success field, print it directly\n if (result && typeof result === 'object' && 'success' in result) {\n this.writeJson(result, 0);\n }\n else {\n // Otherwise, wrap it\n const payload = {\n success: true,\n message: message ?? result?.message ?? undefined,\n data: result,\n };\n this.writeJson(payload, 0);\n }\n }\n printError(error, code) {\n const message = this.formatErrorMessage(error);\n const payload = { success: false, message, code: code ?? undefined, status: 'error' };\n this.writeJson(payload, 1);\n }\n printUsageError(command, message) {\n const payload = {\n success: false,\n message,\n status: 'error',\n usage: `Use 'xhs-mcp ${command} --help' for more information`,\n };\n this.writeJson(payload, 1);\n }\n}\nasync function main() {\n const config = (0,shared_config/* getConfig */.zj)();\n const program = new external_commander_namespaceObject.Command();\n const utils = new CLIUtils(program);\n program\n .name('xhs-mcp')\n .description('XiaoHongShu CLI with subcommands')\n .option('--compact', 'Output compact one-line JSON (no pretty print)')\n .showHelpAfterError();\n program\n .command('login')\n .description('Start XiaoHongShu login flow (opens browser, saves cookies)')\n .option('-t, --timeout <seconds>', 'Login timeout in seconds', `${config.browser.loginTimeout}`)\n .action(async (opts) => {\n const browserPath = undefined;\n const timeoutSec = opts.timeout ? parseInt(opts.timeout, 10) : config.browser.loginTimeout;\n const authService = new AuthService(config);\n try {\n const result = await authService.login(browserPath, timeoutSec);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('logout')\n .description('Logout from XiaoHongShu and clear saved cookies')\n .action(async () => {\n const authService = new AuthService(config);\n try {\n const result = await authService.logout();\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('status')\n .description('Check current XiaoHongShu login status')\n .action(async () => {\n const browserPath = undefined;\n const authService = new AuthService(config);\n try {\n const result = await authService.checkStatus(browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('browser')\n .description('Ensure Puppeteer Chromium is installed and launchable; installs if missing')\n .option('--with-deps', 'Install OS-level dependencies as well (may require sudo)')\n .action(async (opts) => {\n async function canLaunchChromium() {\n try {\n // Get the executable path before launching\n const executablePath = external_puppeteer_default().executablePath();\n const browser = await external_puppeteer_default().launch({ headless: true });\n await browser.close();\n return { canLaunch: true, executablePath };\n }\n catch {\n return { canLaunch: false };\n }\n }\n const browserInfo = await canLaunchChromium();\n if (browserInfo.canLaunch) {\n utils.printSuccess({\n installed: true,\n executablePath: browserInfo.executablePath,\n }, 'Chromium is ready');\n return;\n }\n const args = ['puppeteer', 'browsers', 'install', 'chrome'];\n if (opts.withDeps)\n args.push('--with-deps');\n const result = (0,external_node_child_process_namespaceObject.spawnSync)('npx', args, { stdio: 'inherit', env: process.env });\n const afterInstallInfo = await canLaunchChromium();\n if (afterInstallInfo.canLaunch) {\n utils.printSuccess({\n installed: true,\n executablePath: afterInstallInfo.executablePath,\n exitCode: result.status ?? null,\n }, 'Chromium installed and ready');\n }\n else {\n utils.printError(new Error('Failed to install or launch Chromium'));\n }\n });\n // Feeds: discover\n program\n .command('feeds')\n .description('Discover home page feeds')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const feedService = new FeedService(config);\n try {\n const result = await feedService.getFeedList(opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // Feeds: search note\n program\n .command('search')\n .description('Search notes by keyword')\n .requiredOption('-k, --keyword <keyword>', 'Search keyword')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const feedService = new FeedService(config);\n try {\n const result = await feedService.searchFeeds(opts.keyword, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // User Notes: unified command with subcommands\n const userNoteCommand = program\n .command('usernote')\n .description(\"Current user's note management operations\");\n // User Note list subcommand\n userNoteCommand\n .command('list')\n .description(\"List current user's published notes\")\n .option('-l, --limit <number>', 'Maximum number of notes to retrieve', '20')\n .option('-c, --cursor <cursor>', 'Pagination cursor for next page')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const noteService = new note_service.NoteService(config);\n try {\n const limit = parseInt(opts.limit) || 20;\n const result = await noteService.getUserNotes(limit, opts.cursor, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // User Note delete subcommand\n userNoteCommand\n .command('delete')\n .description('Delete user notes')\n .option('--note-id <id>', 'Specific note ID to delete')\n .option('--last-published', 'Delete the last published note')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const noteService = new note_service.NoteService(config);\n try {\n if (opts.lastPublished) {\n const result = await noteService.deleteLastPublishedNote(opts.browserPath);\n utils.printSuccess(result);\n }\n else if (opts.noteId) {\n const result = await noteService.deleteNote(opts.noteId, opts.browserPath);\n utils.printSuccess(result);\n }\n else {\n // Show help instead of JSON error when no arguments provided\n console.log('Usage: xhs-mcp usernote delete [options]\\n');\n console.log('Delete user notes\\n');\n console.log('Options:');\n console.log(' --note-id <id> Specific note ID to delete');\n console.log(' --last-published Delete the last published note');\n console.log(' -b, --browser-path <path> Custom browser binary path');\n console.log(' -h, --help display help for command');\n process.exit(0);\n }\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // Feeds: comment on note\n program\n .command('comment')\n .description('Comment on a note')\n .requiredOption('--feed-id <id>', 'Feed ID')\n .requiredOption('--xsec-token <token>', 'Security token for the feed')\n .requiredOption('-n, --note <text>', 'Comment content')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const feedService = new FeedService(config);\n try {\n const result = await feedService.commentOnFeed(opts.feedId, opts.xsecToken, opts.note, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // Publishing: unified publish command\n program\n .command('publish')\n .description('Publish content to XiaoHongShu (supports both images and videos)')\n .requiredOption('-t, --type <type>', 'Content type: \"image\" for images, \"video\" for videos')\n .requiredOption('--title <title>', 'Content title (<= 20 chars)')\n .requiredOption('--content <content>', 'Content description (<= 1000 chars)')\n .requiredOption('-m, --media <paths>', 'Comma-separated media file paths (1-18 images for image posts, exactly 1 video for videos)')\n .option('--tags <tags>', 'Comma-separated tags')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const publishService = new PublishService(config);\n try {\n if (opts.type !== 'image' && opts.type !== 'video') {\n utils.printError(new Error('Type must be \"image\" or \"video\"'));\n return;\n }\n const mediaPaths = opts.media\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const result = await publishService.publishContent(opts.type, opts.title, opts.content, mediaPaths, opts.tags, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('mcp')\n .description('Start XHS MCP server (stdio or http mode)')\n .option('-m, --mode <mode>', 'Server mode: stdio or http', 'stdio')\n .option('-p, --port <port>', 'HTTP server port (only for http mode)', '3000')\n .action(async (opts) => {\n try {\n if (opts.mode === 'http') {\n const port = opts.port ? parseInt(opts.port, 10) : 3000;\n const httpServer = new XHSHTTPMCPServer(port);\n await httpServer.start();\n }\n else {\n // In stdio mode, we must not output anything to stdout/stderr except MCP protocol messages\n // This prevents interference with MCP communication\n const server = new XHSMCPServer();\n await server.start();\n }\n }\n catch (error) {\n // Only log to stderr if logging is explicitly enabled\n if (process.env.XHS_ENABLE_LOGGING === 'true') {\n process.stderr.write(`Server failed to start: ${error}\\n`);\n }\n process.exit(1);\n }\n });\n // List MCP tools\n program\n .command('tools')\n .description('List available MCP tools')\n .option('-j, --json', 'Output in JSON format')\n .option('-d, --detailed', 'Show detailed tool information')\n .action(async (opts) => {\n try {\n const toolSchemas = XHS_TOOL_SCHEMAS;\n if (opts.json) {\n if (opts.detailed) {\n console.log(JSON.stringify(toolSchemas, null, 2));\n }\n else {\n const toolNames = toolSchemas.map((tool) => ({\n name: tool.name,\n description: tool.description,\n }));\n console.log(JSON.stringify(toolNames, null, 2));\n }\n }\n else {\n console.log('\\n📋 Available MCP Tools:\\n');\n toolSchemas.forEach((tool, index) => {\n console.log(`${index + 1}. ${tool.name}`);\n console.log(` ${tool.description}`);\n if (opts.detailed) {\n const required = tool.inputSchema.required ?? [];\n const properties = tool.inputSchema.properties ?? {};\n if (Object.keys(properties).length > 0) {\n console.log(' Parameters:');\n Object.entries(properties).forEach(([key, prop]) => {\n const requiredMark = required.includes(key) ? ' (required)' : ' (optional)';\n const propDesc = prop.description;\n console.log(` - ${key}: ${propDesc ?? 'No description'}${requiredMark}`);\n });\n }\n }\n console.log('');\n });\n console.log(`Total: ${toolSchemas.length} tools available`);\n console.log('\\nUse --detailed for parameter information');\n console.log('Use --json for machine-readable output');\n }\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program.parseAsync(process.argv);\n}\n// Handle graceful shutdown for MCP server mode\nprocess.on('SIGINT', () => {\n // Don't log to stderr in stdio mode to avoid interfering with MCP protocol\n process.exit(0);\n});\nprocess.on('SIGTERM', () => {\n // Don't log to stderr in stdio mode to avoid interfering with MCP protocol\n process.exit(0);\n});\n// Start the CLI\nmain().catch((error) => {\n // Only log to stderr if logging is explicitly enabled\n if (process.env.XHS_ENABLE_LOGGING === 'true') {\n process.stderr.write(`Fatal error: ${error}\\n`);\n }\n process.exit(1);\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3pGLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUM3QyxDQUFDO1FBRUQsTUFBTTtRQUNOLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNuRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDN0MsQ0FBQztRQUVELE9BQU87UUFDUCxJQUNFLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJO1lBQ25CLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJLEVBQ25CLENBQUM7WUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDOUMsQ0FBQztRQUVELE1BQU07UUFDTixJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFD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LENBQUM7QUFDbEIsQ0FBQyxDQUFDLENBQUM7QUFFSCxnQkFBZ0I7QUFDaEIsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7SUFDckIsc0RBQXNEO0lBQ3RELElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUM5QyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsS0FBSyxJQUFJLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL3hocy1tY3AvZXh0ZXJuYWwgY29tbW9uanMyIFwiY29tbWFuZGVyXCI/YzQ0OCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NoYXJlZC94aHMudXRpbHMudHM/YjI1ZSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvYXV0aC9hdXRoLnNlcnZpY2UudHM/NjlmZSIsIndlYnBhY2s6Ly94aHMtbWNwL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJub2RlOmNoaWxkX3Byb2Nlc3NcIj85ODVkIiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9mZWVkcy9mZWVkLnNlcnZpY2UudHM/NjRiNyIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NoYXJlZC90aXRsZS12YWxpZGF0b3IudHM/MjQzOSIsIndlYnBhY2s6Ly94aHMtbWNwL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJjcnlwdG9cIj9hOGIyIiwid2VicGFjazovL3hocy1tY3AvZXh0ZXJuYWwgY29tbW9uanMyIFwibm9kZS1mZXRjaFwiPzM2ZTUiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvaW1hZ2UtZG93bmxvYWRlci50cz81MzU2Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9wdWJsaXNoaW5nL3B1Ymxpc2gtYmFzZS5zZXJ2aWNlLnRzPzY3OGMiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL3B1Ymxpc2hpbmcvcHVibGlzaC1pbWFnZS5zZXJ2aWNlLnRzP2Q1ZjQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL3B1Ymxpc2hpbmcvcHVibGlzaC12aWRlby5zZXJ2aWNlLnRzPzU0MDYiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL3B1Ymxpc2hpbmcvcHVibGlzaC5zZXJ2aWNlLnRzPzE3ZTkiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zZXJ2ZXIvaGFuZGxlcnMvdG9vbC5oYW5kbGVycy50cz83Zjc0Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL2luZGV4LnRzPzg0NWUiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zZXJ2ZXIvaGFuZGxlcnMvcmVzb3VyY2UuaGFuZGxlcnMudHM/YWEzOSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9zY2hlbWFzL3Rvb2wuc2NoZW1hcy50cz9kZjhmIiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2VydmVyL21jcC5zZXJ2ZXIudHM/MzM5NCIsIndlYnBhY2s6Ly94aHMtbWNwL2V4dGVybmFsIGNvbW1vbmpzMiBcImV4cHJlc3NcIj81ZTNhIiwid2VicGFjazovL3hocy1tY3AvZXh0ZXJuYWwgY29tbW9uanMyIFwiY29yc1wiPzljN2QiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zZXJ2ZXIvaHR0cC5zZXJ2ZXIudHM/OGNkNCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9oYW5kbGVycy9pbmRleC50cz8xZTk0Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2VydmVyL2luZGV4LnRzPzVlZTYiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jbGkvY2xpLnRzP2NiOWQiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgX19XRUJQQUNLX05BTUVTUEFDRV9PQkpFQ1RfXyA9IHJlcXVpcmUoXCJjb21tYW5kZXJcIik7IiwiLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9ucyBmb3IgWEhTIG9wZXJhdGlvbnNcbiAqL1xuXG5pbXBvcnQgeyBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcblxuZXhwb3J0IGNvbnN0IFhIU19IT01FX1VSTCA9ICdodHRwczovL3d3dy54aWFvaG9uZ3NodS5jb20nO1xuZXhwb3J0IGNvbnN0IFhIU19FWFBMT1JFX1VSTCA9IGAke1hIU19IT01FX1VSTH0vZXhwbG9yZWA7XG5leHBvcnQgY29uc3QgWEhTX1NFQVJDSF9VUkwgPSBgJHtYSFNfSE9NRV9VUkx9L3NlYXJjaF9yZXN1bHRgO1xuZXhwb3J0IGNvbnN0IFhIU19DUkVBVE9SX1BVQkxJU0hfVVJMID1cbiAgJ2h0dHBzOi8vY3JlYXRvci54aWFvaG9uZ3NodS5jb20vcHVibGlzaC9wdWJsaXNoP3NvdXJjZT1vZmZpY2lhbCc7XG5leHBvcnQgY29uc3QgTE9HSU5fT0tfU0VMRUNUT1IgPSAnLm1haW4tY29udGFpbmVyIC51c2VyIC5saW5rLXdyYXBwZXIgLmNoYW5uZWwnO1xuXG5leHBvcnQgZnVuY3Rpb24gbWFrZVNlYXJjaFVybChrZXl3b3JkOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHtcbiAgICBrZXl3b3JkLFxuICAgIHNvdXJjZTogJ3dlYl9leHBsb3JlX2ZlZWQnLFxuICB9KTtcbiAgcmV0dXJuIGAke1hIU19TRUFSQ0hfVVJMfT8ke3BhcmFtcy50b1N0cmluZygpfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlRmVlZERldGFpbFVybChmZWVkSWQ6IHN0cmluZywgeHNlY1Rva2VuOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHtcbiAgICB4c2VjX3Rva2VuOiB4c2VjVG9rZW4sXG4gICAgeHNlY19zb3VyY2U6ICdwY19mZWVkJyxcbiAgfSk7XG4gIHJldHVybiBgJHtYSFNfRVhQTE9SRV9VUkx9LyR7ZmVlZElkfT8ke3BhcmFtcy50b1N0cmluZygpfWA7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleHRyYWN0SW5pdGlhbFN0YXRlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgbnVsbD4ge1xuICB0cnkge1xuICAgIC8vIFdhaXQgZm9yIHBhZ2UgdG8gYmUgZnVsbHkgbG9hZGVkIC0gUHVwcGV0ZWVyIGRvZXNuJ3QgaGF2ZSB3YWl0Rm9yTG9hZFN0YXRlXG4gICAgLy8gV2UnbGwganVzdCB3YWl0IGEgYml0IGZvciB0aGUgcGFnZSB0byBzZXR0bGVcbiAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gZ2xvYmFsVGhpcy5zZXRUaW1lb3V0KHJlc29sdmUsIDEwMDApKTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gSWdub3JlIGxvYWQgc3RhdGUgZXJyb3JzXG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoYFxuICAgICAgKCgpID0+IHtcbiAgICAgICAgLy8gVHJ5IG11bHRpcGxlIHBvc3NpYmxlIHN0YXRlIG9iamVjdHNcbiAgICAgICAgY29uc3QgcG9zc2libGVTdGF0ZXMgPSBbXG4gICAgICAgICAgd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLFxuICAgICAgICAgIHdpbmRvdy5fX0lOSVRJQUxfU1NSX1NUQVRFX18sXG4gICAgICAgICAgd2luZG93Ll9fTkVYVF9EQVRBX18sXG4gICAgICAgICAgd2luZG93Ll9fTlVYVF9fLFxuICAgICAgICAgIHdpbmRvdy5fX1ZVRV9fLFxuICAgICAgICAgIHdpbmRvdy5fX1JFQUNUX1FVRVJZX1NUQVRFX19cbiAgICAgICAgXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0YXRlIG9mIHBvc3NpYmxlU3RhdGVzKSB7XG4gICAgICAgICAgaWYgKHN0YXRlICYmIHR5cGVvZiBzdGF0ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIC8vIFVzZSBhIG1vcmUgcm9idXN0IEpTT04gc2VyaWFsaXphdGlvbiB0aGF0IGhhbmRsZXMgY2lyY3VsYXIgcmVmZXJlbmNlc1xuICAgICAgICAgICAgICBjb25zdCBzZWVuID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHN0YXRlLCAoa2V5LCB2YWwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodmFsICE9IG51bGwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgICAgaWYgKHNlZW4uaGFzKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiW0NpcmN1bGFyXVwiO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgc2Vlbi5hZGQodmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdKU09OLnN0cmluZ2lmeSBmYWlsZWQgZm9yIHN0YXRlOicsIGUubWVzc2FnZSk7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIG5vIHN0YXRlIGZvdW5kLCB0cnkgdG8gZmluZCBhbnkgZ2xvYmFsIHN0YXRlXG4gICAgICAgIGNvbnN0IGdsb2JhbEtleXMgPSBPYmplY3Qua2V5cyh3aW5kb3cpLmZpbHRlcihrZXkgPT5cbiAgICAgICAgICBrZXkuaW5jbHVkZXMoJ1NUQVRFJykgfHwga2V5LmluY2x1ZGVzKCdEQVRBJykgfHwga2V5LmluY2x1ZGVzKCdJTklUSUFMJylcbiAgICAgICAgKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBnbG9iYWxLZXlzKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSB3aW5kb3dba2V5XTtcbiAgICAgICAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBXZWFrU2V0KCk7XG4gICAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgKGtleSwgdmFsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbCAhPSBudWxsICYmIHR5cGVvZiB2YWwgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChzZWVuLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIltDaXJjdWxhcl1cIjtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIHNlZW4uYWRkKHZhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBsb2dnZXIud2FybignSlNPTi5zdHJpbmdpZnkgZmFpbGVkIGZvciBnbG9iYWwga2V5OicsIGtleSwgZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfSkoKVxuICAgIGApO1xuXG4gICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3VsdCBhcyBzdHJpbmcpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNMb2dnZWRJbihwYWdlOiBQYWdlKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKExPR0lOX09LX1NFTEVDVE9SKTtcbiAgICByZXR1cm4gZWxlbWVudHMubGVuZ3RoID4gMDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRMb2dpblN0YXR1c1dpdGhQcm9maWxlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHtcbiAgaXNMb2dnZWRJbjogYm9vbGVhbjtcbiAgcHJvZmlsZT86IHtcbiAgICB1c2VySWQ/OiBzdHJpbmc7XG4gICAgbmlja25hbWU/OiBzdHJpbmc7XG4gICAgdXNlcm5hbWU/OiBzdHJpbmc7XG4gICAgYXZhdGFyPzogc3RyaW5nO1xuICAgIGZvbGxvd2Vycz86IG51bWJlcjtcbiAgICBmb2xsb3dpbmc/OiBudW1iZXI7XG4gICAgbGlrZXM/OiBudW1iZXI7XG4gICAgeGhzTnVtYmVyPzogc3RyaW5nO1xuICAgIGlwTG9jYXRpb24/OiBzdHJpbmc7XG4gICAgcHJvZmlsZVVybD86IHN0cmluZztcbiAgfTtcbn0+IHtcbiAgdHJ5IHtcbiAgICAvLyBGaXJzdCBjaGVjayBpZiBsb2dnZWQgaW4gdXNpbmcgdGhlIGV4aXN0aW5nIG1ldGhvZFxuICAgIGNvbnN0IGVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJChMT0dJTl9PS19TRUxFQ1RPUik7XG4gICAgY29uc3QgaXNMb2dnZWRJbiA9IGVsZW1lbnRzLmxlbmd0aCA+IDA7XG5cbiAgICBpZiAoIWlzTG9nZ2VkSW4pIHtcbiAgICAgIHJldHVybiB7IGlzTG9nZ2VkSW46IGZhbHNlIH07XG4gICAgfVxuXG4gICAgLy8gSWYgbG9nZ2VkIGluLCB0cnkgdG8gZXh0cmFjdCBwcm9maWxlIGluZm9ybWF0aW9uIGZyb20gY3VycmVudCBwYWdlXG4gICAgbGV0IHByb2ZpbGVEYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgIHRyeSB7XG4gICAgICBwcm9maWxlRGF0YSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICBjb25zdCBwcm9maWxlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuXG4gICAgICAgIC8vIEV4dHJhY3QgdXNlciBJRCBmcm9tIFVSTCBpZiBvbiBwcm9maWxlIHBhZ2VcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgIGNvbnN0IHVybE1hdGNoID0gd2luZG93LmxvY2F0aW9uLmhyZWYubWF0Y2goL1xcL3VzZXJcXC9wcm9maWxlXFwvKFthLWYwLTldKykvKTtcbiAgICAgICAgaWYgKHVybE1hdGNoKSB7XG4gICAgICAgICAgcHJvZmlsZS51c2VySWQgPSB1cmxNYXRjaFsxXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyeSB0byBmaW5kIHVzZXIgbmlja25hbWVcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgIGNvbnN0IG5hbWVFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAnLnVzZXItbmFtZSwgW2NsYXNzKj1cInVzZXItbmFtZVwiXSwgW2NsYXNzKj1cIm5pY2tuYW1lXCJdJ1xuICAgICAgICApO1xuICAgICAgICBpZiAobmFtZUVsZW1lbnQpIHtcbiAgICAgICAgICBwcm9maWxlLm5pY2tuYW1lID0gbmFtZUVsZW1lbnQudGV4dENvbnRlbnQ/LnRyaW0oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyeSB0byBmaW5kIHVzZXIgaW5mbyB0ZXh0IHRoYXQgbWlnaHQgY29udGFpbiBzdGF0c1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgY29uc3QgaW5mb0VsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudXNlci1pbmZvLCBbY2xhc3MqPVwidXNlci1pbmZvXCJdJyk7XG4gICAgICAgIGlmIChpbmZvRWxlbWVudCkge1xuICAgICAgICAgIGNvbnN0IGluZm9UZXh0ID0gaW5mb0VsZW1lbnQudGV4dENvbnRlbnQgfHwgJyc7XG4gICAgICAgICAgcHJvZmlsZS5pbmZvVGV4dCA9IGluZm9UZXh0O1xuXG4gICAgICAgICAgLy8gVHJ5IHRvIGV4dHJhY3QgbnVtYmVycyBmcm9tIHRoZSBpbmZvIHRleHQgKGZvbGxvd2VycywgZm9sbG93aW5nLCBsaWtlcylcbiAgICAgICAgICBjb25zdCBudW1iZXJzID0gaW5mb1RleHQubWF0Y2goL1xcZCsvZyk7XG4gICAgICAgICAgaWYgKG51bWJlcnMgJiYgbnVtYmVycy5sZW5ndGggPj0gMykge1xuICAgICAgICAgICAgLy8gQ29tbW9uIHBhdHRlcm46IGZvbGxvd2VycywgZm9sbG93aW5nLCBsaWtlc1xuICAgICAgICAgICAgcHJvZmlsZS5mb2xsb3dpbmcgPSBwYXJzZUludChudW1iZXJzWzBdKSB8fCAwO1xuICAgICAgICAgICAgcHJvZmlsZS5mb2xsb3dlcnMgPSBwYXJzZUludChudW1iZXJzWzFdKSB8fCAwO1xuICAgICAgICAgICAgcHJvZmlsZS5saWtlcyA9IHBhcnNlSW50KG51bWJlcnNbMl0pIHx8IDA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gRXh0cmFjdCDlsI/nuqLkuablj7cgKFhIUyBudW1iZXIpXG4gICAgICAgICAgY29uc3QgeGhzTWF0Y2ggPSBpbmZvVGV4dC5tYXRjaCgv5bCP57qi5Lmm5Y+377yaKFxcZCspLyk7XG4gICAgICAgICAgaWYgKHhoc01hdGNoKSB7XG4gICAgICAgICAgICBwcm9maWxlLnhoc051bWJlciA9IHhoc01hdGNoWzFdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEV4dHJhY3QgSVDlsZ7lnLAgKElQIGxvY2F0aW9uKVxuICAgICAgICAgIGNvbnN0IGlwTWF0Y2ggPSBpbmZvVGV4dC5tYXRjaCgvSVDlsZ7lnLDvvJooW14wLTldKykvKTtcbiAgICAgICAgICBpZiAoaXBNYXRjaCkge1xuICAgICAgICAgICAgcHJvZmlsZS5pcExvY2F0aW9uID0gaXBNYXRjaFsxXS50cmltKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHJ5IHRvIGZpbmQgYXZhdGFyXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgICBjb25zdCBhdmF0YXJFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAnaW1nW2NsYXNzKj1cImF2YXRhclwiXSwgaW1nW2NsYXNzKj1cInByb2ZpbGVcIl0sIC5hdmF0YXIgaW1nLCAucHJvZmlsZSBpbWcnXG4gICAgICAgICkgYXMgSFRNTEltYWdlRWxlbWVudDtcbiAgICAgICAgaWYgKGF2YXRhckVsZW1lbnQpIHtcbiAgICAgICAgICBwcm9maWxlLmF2YXRhciA9IGF2YXRhckVsZW1lbnQuc3JjO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHByb2ZpbGU7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgaW4gcGFnZS5ldmFsdWF0ZScpO1xuICAgICAgcHJvZmlsZURhdGEgPSB7fTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaXNMb2dnZWRJbjogdHJ1ZSxcbiAgICAgIHByb2ZpbGU6IE9iamVjdC5rZXlzKHByb2ZpbGVEYXRhKS5sZW5ndGggPiAwID8gcHJvZmlsZURhdGEgOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gSWYgdGhlcmUncyBhbiBlcnJvciwgZmFsbCBiYWNrIHRvIGJhc2ljIGxvZ2luIGNoZWNrXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJChMT0dJTl9PS19TRUxFQ1RPUik7XG4gICAgICByZXR1cm4geyBpc0xvZ2dlZEluOiBlbGVtZW50cy5sZW5ndGggPiAwIH07XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4geyBpc0xvZ2dlZEluOiBmYWxzZSB9O1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBBdXRoZW50aWNhdGlvbiBzZXJ2aWNlIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbmltcG9ydCB7IENvbmZpZywgTG9naW5SZXN1bHQsIFN0YXR1c1Jlc3VsdCB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQge1xuICBMb2dpblRpbWVvdXRFcnJvcixcbiAgTG9naW5GYWlsZWRFcnJvcixcbiAgTm90TG9nZ2VkSW5FcnJvcixcbiAgWEhTRXJyb3IsXG59IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvYmFzZS5zZXJ2aWNlJztcbmltcG9ydCB7IGRlbGV0ZUNvb2tpZXNGaWxlLCBnZXRDb29raWVzSW5mbyB9IGZyb20gJy4uLy4uL3NoYXJlZC9jb29raWVzJztcbmltcG9ydCB7IGlzTG9nZ2VkSW4sIGdldExvZ2luU3RhdHVzV2l0aFByb2ZpbGUgfSBmcm9tICcuLi8uLi9zaGFyZWQveGhzLnV0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgQXV0aFNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnKSB7XG4gICAgc3VwZXIoY29uZmlnKTtcbiAgfVxuXG4gIGFzeW5jIGxvZ2luKGJyb3dzZXJQYXRoPzogc3RyaW5nLCB0aW1lb3V0OiBudW1iZXIgPSAzMDApOiBQcm9taXNlPExvZ2luUmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZShmYWxzZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBOYXZpZ2F0ZSB0byBleHBsb3JlIHBhZ2VcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmV4cGxvcmVVcmwpO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIGFscmVhZHkgbG9nZ2VkIGluXG4gICAgICAgIGlmIChhd2FpdCBpc0xvZ2dlZEluKHBhZ2UpKSB7XG4gICAgICAgICAgLy8gR2V0IHByb2ZpbGUgaW5mb3JtYXRpb24gaWYgYWxyZWFkeSBsb2dnZWQgaW5cbiAgICAgICAgICBsZXQgcHJvZmlsZTogYW55ID0gdW5kZWZpbmVkO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBGaW5kIGN1cnJlbnQgdXNlcidzIHByb2ZpbGUgbGluayBhbmQgZXh0cmFjdCB1c2VyIElEIGZyb20gVVJMXG4gICAgICAgICAgICBjb25zdCBwcm9maWxlVXJsID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHVzZXJMaW5rcyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnYVtocmVmKj1cIi91c2VyL3Byb2ZpbGUvXCJdJykpO1xuICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VXNlckxpbmsgPSB1c2VyTGlua3MuZmluZCgobGluaykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSBsaW5rLnRleHRDb250ZW50Py50cmltKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgIHRleHQgPT09ICfmiJEnIHx8XG4gICAgICAgICAgICAgICAgICAodGV4dCAmJiB0ZXh0LmluY2x1ZGVzKCdwcm9maWxlJykpIHx8XG4gICAgICAgICAgICAgICAgICAodGV4dCAmJiB0ZXh0LmluY2x1ZGVzKCfnlKjmiLcnKSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRVc2VyTGluayA/IChjdXJyZW50VXNlckxpbmsgYXMgSFRNTEFuY2hvckVsZW1lbnQpLmhyZWYgOiBudWxsO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChwcm9maWxlVXJsKSB7XG4gICAgICAgICAgICAgIC8vIEV4dHJhY3QgdXNlciBJRCBmcm9tIHByb2ZpbGUgVVJMXG4gICAgICAgICAgICAgIGNvbnN0IHVzZXJJZE1hdGNoID0gcHJvZmlsZVVybC5tYXRjaCgvXFwvdXNlclxcL3Byb2ZpbGVcXC8oW2EtZjAtOV0rKS8pO1xuICAgICAgICAgICAgICBpZiAodXNlcklkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICBwcm9maWxlID0ge1xuICAgICAgICAgICAgICAgICAgdXNlcklkOiB1c2VySWRNYXRjaFsxXSxcbiAgICAgICAgICAgICAgICAgIHByb2ZpbGVVcmw6IHByb2ZpbGVVcmwsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBbHNvIHRyeSB0byBnZXQgYWRkaXRpb25hbCBwcm9maWxlIGluZm8gZnJvbSBjdXJyZW50IHBhZ2VcbiAgICAgICAgICAgIGNvbnN0IGxvZ2luU3RhdHVzID0gYXdhaXQgZ2V0TG9naW5TdGF0dXNXaXRoUHJvZmlsZShwYWdlKTtcbiAgICAgICAgICAgIGlmIChsb2dpblN0YXR1cy5wcm9maWxlKSB7XG4gICAgICAgICAgICAgIHByb2ZpbGUgPSB7IC4uLnByb2ZpbGUsIC4uLmxvZ2luU3RhdHVzLnByb2ZpbGUgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChwcm9maWxlRXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gZ2V0IHByb2ZpbGUgaW5mb3JtYXRpb246JywgcHJvZmlsZUVycm9yKTtcbiAgICAgICAgICAgIC8vIENvbnRpbnVlIHdpdGhvdXQgcHJvZmlsZSBpbmZvXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiAnQWxyZWFkeSBsb2dnZWQgaW4nLFxuICAgICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX2luJyxcbiAgICAgICAgICAgIGFjdGlvbjogJ25vbmUnLFxuICAgICAgICAgICAgcHJvZmlsZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgbG9naW4gY29tcGxldGlvblxuICAgICAgICBjb25zdCBjaGVja0ludGVydmFsID0gNTsgLy8gQ2hlY2sgZXZlcnkgNSBzZWNvbmRzXG4gICAgICAgIGNvbnN0IG1heENoZWNrcyA9IHRpbWVvdXQgLyBjaGVja0ludGVydmFsO1xuXG4gICAgICAgIGZvciAobGV0IGNoZWNrQ291bnQgPSAwOyBjaGVja0NvdW50IDwgbWF4Q2hlY2tzOyBjaGVja0NvdW50KyspIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgbG9naW4gY29tcGxldGVkIHdpdGggc2hvcnQgdGltZW91dFxuICAgICAgICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yU2VsZWN0b3IodGhpcy5nZXRDb25maWcoKS54aHMubG9naW5Pa1NlbGVjdG9yLCB7XG4gICAgICAgICAgICAgIHRpbWVvdXQ6IGNoZWNrSW50ZXJ2YWwgKiAxMDAwLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBMb2dpbiBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gTG9naW4gbm90IHlldCBjb21wbGV0ZSwgY29udGludWUgY2hlY2tpbmdcbiAgICAgICAgICAgIGNvbnN0IGVsYXBzZWQgPSAoY2hlY2tDb3VudCArIDEpICogY2hlY2tJbnRlcnZhbDtcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZyA9IHRpbWVvdXQgLSBlbGFwc2VkO1xuXG4gICAgICAgICAgICBpZiAoY2hlY2tDb3VudCA9PT0gbWF4Q2hlY2tzIC0gMSkge1xuICAgICAgICAgICAgICAvLyBGaW5hbCB0aW1lb3V0IHJlYWNoZWRcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IExvZ2luVGltZW91dEVycm9yKFxuICAgICAgICAgICAgICAgIGBMb2dpbiB0aW1lZCBvdXQgYWZ0ZXIgJHt0aW1lb3V0fSBzZWNvbmRzLiBQbGVhc2UgY29tcGxldGUgUVIgY29kZSBzY2FubmluZyBvciBtYW51YWwgbG9naW4gaW4gdGhlIGJyb3dzZXIgd2luZG93LmAsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgdGltZW91dCxcbiAgICAgICAgICAgICAgICAgIHVybDogdGhpcy5nZXRDb25maWcoKS54aHMuZXhwbG9yZVVybCxcbiAgICAgICAgICAgICAgICAgIGVsYXBzZWRUaW1lOiBlbGFwc2VkLFxuICAgICAgICAgICAgICAgICAgc3VnZ2VzdGlvbjogJ0luY3JlYXNlIHRpbWVvdXQgcGFyYW1ldGVyIG9yIGNvbXBsZXRlIGxvZ2luIGZhc3RlcicsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNhdmUgY29va2llcyBhZnRlciBzdWNjZXNzZnVsIGxvZ2luXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5zYXZlQ29va2llc0Zyb21QYWdlKHBhZ2UpO1xuXG4gICAgICAgIC8vIFZlcmlmeSBsb2dpbiBzdWNjZXNzIGFuZCBnZXQgcHJvZmlsZSBpbmZvcm1hdGlvblxuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTsgLy8gQnJpZWYgd2FpdCBmb3IgcGFnZSB0byB1cGRhdGVcbiAgICAgICAgY29uc3QgbG9naW5TdGF0dXMgPSBhd2FpdCBnZXRMb2dpblN0YXR1c1dpdGhQcm9maWxlKHBhZ2UpO1xuICAgICAgICBpZiAobG9naW5TdGF0dXMuaXNMb2dnZWRJbikge1xuICAgICAgICAgIC8vIFRyeSB0byBnZXQgYWRkaXRpb25hbCBwcm9maWxlIGluZm9ybWF0aW9uXG4gICAgICAgICAgbGV0IHByb2ZpbGUgPSBsb2dpblN0YXR1cy5wcm9maWxlO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBGaW5kIGN1cnJlbnQgdXNlcidzIHByb2ZpbGUgbGluayBhbmQgZXh0cmFjdCB1c2VyIElEIGZyb20gVVJMXG4gICAgICAgICAgICBjb25zdCBwcm9maWxlVXJsID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHVzZXJMaW5rcyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnYVtocmVmKj1cIi91c2VyL3Byb2ZpbGUvXCJdJykpO1xuICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VXNlckxpbmsgPSB1c2VyTGlua3MuZmluZCgobGluaykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSBsaW5rLnRleHRDb250ZW50Py50cmltKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgIHRleHQgPT09ICfmiJEnIHx8XG4gICAgICAgICAgICAgICAgICAodGV4dCAmJiB0ZXh0LmluY2x1ZGVzKCdwcm9maWxlJykpIHx8XG4gICAgICAgICAgICAgICAgICAodGV4dCAmJiB0ZXh0LmluY2x1ZGVzKCfnlKjmiLcnKSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRVc2VyTGluayA/IChjdXJyZW50VXNlckxpbmsgYXMgSFRNTEFuY2hvckVsZW1lbnQpLmhyZWYgOiBudWxsO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChwcm9maWxlVXJsKSB7XG4gICAgICAgICAgICAgIC8vIEV4dHJhY3QgdXNlciBJRCBmcm9tIHByb2ZpbGUgVVJMXG4gICAgICAgICAgICAgIGNvbnN0IHVzZXJJZE1hdGNoID0gcHJvZmlsZVVybC5tYXRjaCgvXFwvdXNlclxcL3Byb2ZpbGVcXC8oW2EtZjAtOV0rKS8pO1xuICAgICAgICAgICAgICBpZiAodXNlcklkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICBwcm9maWxlID0ge1xuICAgICAgICAgICAgICAgICAgLi4ucHJvZmlsZSxcbiAgICAgICAgICAgICAgICAgIHVzZXJJZDogdXNlcklkTWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgICBwcm9maWxlVXJsOiBwcm9maWxlVXJsLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChwcm9maWxlRXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gZ2V0IGFkZGl0aW9uYWwgcHJvZmlsZSBpbmZvcm1hdGlvbjonLCBwcm9maWxlRXJyb3IpO1xuICAgICAgICAgICAgLy8gQ29udGludWUgd2l0aCBleGlzdGluZyBwcm9maWxlIGluZm9cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdMb2dpbiBzdWNjZXNzZnVsJyxcbiAgICAgICAgICAgIHN0YXR1czogJ2xvZ2dlZF9pbicsXG4gICAgICAgICAgICBhY3Rpb246ICdsb2dnZWRfaW4nLFxuICAgICAgICAgICAgcHJvZmlsZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBMb2dpbkZhaWxlZEVycm9yKFxuICAgICAgICAgICAgJ0xvZ2luIHByb2Nlc3MgY29tcGxldGVkIGJ1dCBhdXRoZW50aWNhdGlvbiB2ZXJpZmljYXRpb24gZmFpbGVkJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTG9naW5UaW1lb3V0RXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBMb2dpbkZhaWxlZEVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmVycm9yKGBMb2dpbiBmYWlsZWQgd2l0aCB1bmV4cGVjdGVkIGVycm9yOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKGBMb2dpbiBmYWlsZWQ6ICR7ZXJyb3J9YCwgJ0xvZ2luRXJyb3InLCB7IHRpbWVvdXQgfSwgZXJyb3IgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGxvZ291dCgpOiBQcm9taXNlPExvZ2luUmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN1Y2Nlc3MgPSBkZWxldGVDb29raWVzRmlsZSgpO1xuXG4gICAgICBpZiAoc3VjY2Vzcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgbWVzc2FnZTogJ0xvZ2dlZCBvdXQgc3VjY2Vzc2Z1bGx5IChjb29raWVzIGRlbGV0ZWQpJyxcbiAgICAgICAgICBzdGF0dXM6ICdsb2dnZWRfb3V0JyxcbiAgICAgICAgICBhY3Rpb246ICdsb2dnZWRfb3V0JyxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBkZWxldGUgY29va2llcyBmaWxlJyxcbiAgICAgICAgICBzdGF0dXM6ICdsb2dnZWRfb3V0JyxcbiAgICAgICAgICBhY3Rpb246ICdub25lJyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBMb2dvdXQgZmFpbGVkOiAke2Vycm9yfWApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgIG1lc3NhZ2U6IGBMb2dvdXQgZmFpbGVkOiAke2Vycm9yfWAsXG4gICAgICAgIHN0YXR1czogJ2xvZ2dlZF9vdXQnLFxuICAgICAgICBhY3Rpb246ICdub25lJyxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY2hlY2tTdGF0dXMoYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPFN0YXR1c1Jlc3VsdD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkocGFnZSwgdGhpcy5nZXRDb25maWcoKS54aHMuZXhwbG9yZVVybCk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApOyAvLyBXYWl0IGZvciBwYWdlIHRvIGxvYWRcblxuICAgICAgICAvLyBGaXJzdCBjaGVjayBpZiBsb2dnZWQgaW5cbiAgICAgICAgY29uc3QgbG9nZ2VkSW4gPSBhd2FpdCBpc0xvZ2dlZEluKHBhZ2UpO1xuXG4gICAgICAgIGlmICghbG9nZ2VkSW4pIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIGxvZ2dlZEluOiBmYWxzZSxcbiAgICAgICAgICAgIHN0YXR1czogJ2xvZ2dlZF9vdXQnLFxuICAgICAgICAgICAgdXJsQ2hlY2tlZDogdGhpcy5nZXRDb25maWcoKS54aHMuZXhwbG9yZVVybCxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgbG9nZ2VkIGluLCB0cnkgdG8gZ2V0IHByb2ZpbGUgaW5mb3JtYXRpb25cbiAgICAgICAgbGV0IHByb2ZpbGU6IGFueSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBGaW5kIGN1cnJlbnQgdXNlcidzIHByb2ZpbGUgbGluayBhbmQgZXh0cmFjdCB1c2VyIElEIGZyb20gVVJMXG4gICAgICAgICAgY29uc3QgcHJvZmlsZVVybCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXNlckxpbmtzID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdhW2hyZWYqPVwiL3VzZXIvcHJvZmlsZS9cIl0nKSk7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50VXNlckxpbmsgPSB1c2VyTGlua3MuZmluZCgobGluaykgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gbGluay50ZXh0Q29udGVudD8udHJpbSgpO1xuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIHRleHQgPT09ICfmiJEnIHx8XG4gICAgICAgICAgICAgICAgKHRleHQgJiYgdGV4dC5pbmNsdWRlcygncHJvZmlsZScpKSB8fFxuICAgICAgICAgICAgICAgICh0ZXh0ICYmIHRleHQuaW5jbHVkZXMoJ+eUqOaItycpKVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudFVzZXJMaW5rID8gKGN1cnJlbnRVc2VyTGluayBhcyBIVE1MQW5jaG9yRWxlbWVudCkuaHJlZiA6IG51bGw7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAocHJvZmlsZVVybCkge1xuICAgICAgICAgICAgLy8gRXh0cmFjdCB1c2VyIElEIGZyb20gcHJvZmlsZSBVUkxcbiAgICAgICAgICAgIGNvbnN0IHVzZXJJZE1hdGNoID0gcHJvZmlsZVVybC5tYXRjaCgvXFwvdXNlclxcL3Byb2ZpbGVcXC8oW2EtZjAtOV0rKS8pO1xuICAgICAgICAgICAgaWYgKHVzZXJJZE1hdGNoKSB7XG4gICAgICAgICAgICAgIHByb2ZpbGUgPSB7XG4gICAgICAgICAgICAgICAgdXNlcklkOiB1c2VySWRNYXRjaFsxXSxcbiAgICAgICAgICAgICAgICBwcm9maWxlVXJsOiBwcm9maWxlVXJsLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAocHJvZmlsZUVycm9yKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcign4p2MIEZhaWxlZCB0byBnZXQgcHJvZmlsZSBpbmZvcm1hdGlvbjonLCBwcm9maWxlRXJyb3IpO1xuICAgICAgICAgIC8vIENvbnRpbnVlIHdpdGhvdXQgcHJvZmlsZSBpbmZvXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgbG9nZ2VkSW46IHRydWUsXG4gICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX2luJyxcbiAgICAgICAgICB1cmxDaGVja2VkOiB0aGlzLmdldENvbmZpZygpLnhocy5leHBsb3JlVXJsLFxuICAgICAgICAgIHByb2ZpbGUsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgU3RhdHVzIGNoZWNrIGZhaWxlZDogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcihgU3RhdHVzIGNoZWNrIGZhaWxlZDogJHtlcnJvcn1gLCAnU3RhdHVzQ2hlY2tFcnJvcicsIHt9LCBlcnJvciBhcyBFcnJvcik7XG4gICAgfVxuICB9XG59XG4iLCJjb25zdCBfX1dFQlBBQ0tfTkFNRVNQQUNFX09CSkVDVF9fID0gcmVxdWlyZShcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiKTsiLCIvKipcbiAqIEZlZWQgb3BlcmF0aW9ucyBzZXJ2aWNlIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbmltcG9ydCB7XG4gIENvbmZpZyxcbiAgRmVlZExpc3RSZXN1bHQsXG4gIFNlYXJjaFJlc3VsdCxcbiAgRmVlZERldGFpbFJlc3VsdCxcbiAgQ29tbWVudFJlc3VsdCxcbiAgRmVlZEl0ZW0sXG59IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQge1xuICBGZWVkRXJyb3IsXG4gIEZlZWRQYXJzaW5nRXJyb3IsXG4gIEZlZWROb3RGb3VuZEVycm9yLFxuICBOb3RMb2dnZWRJbkVycm9yLFxuICBYSFNFcnJvcixcbn0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBCYXNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgbWFrZVNlYXJjaFVybCxcbiAgbWFrZUZlZWREZXRhaWxVcmwsXG4gIGV4dHJhY3RJbml0aWFsU3RhdGUsXG4gIGlzTG9nZ2VkSW4sXG59IGZyb20gJy4uLy4uL3NoYXJlZC94aHMudXRpbHMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBGZWVkU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcpIHtcbiAgICBzdXBlcihjb25maWcpO1xuICB9XG5cbiAgYXN5bmMgZ2V0RmVlZExpc3QoYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPEZlZWRMaXN0UmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZSh0cnVlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShwYWdlLCB0aGlzLmdldENvbmZpZygpLnhocy5ob21lVXJsKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgbG9nZ2VkIGluXG4gICAgICAgIGlmICghKGF3YWl0IGlzTG9nZ2VkSW4ocGFnZSkpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vdExvZ2dlZEluRXJyb3IoJ011c3QgYmUgbG9nZ2VkIGluIHRvIGFjY2VzcyBmZWVkIGxpc3QnLCB7XG4gICAgICAgICAgICBvcGVyYXRpb246ICdnZXRfZmVlZF9saXN0JyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEV4dHJhY3QgZmVlZCBkYXRhIHVzaW5nIGEgbW9yZSB0YXJnZXRlZCBhcHByb2FjaFxuICAgICAgICBsZXQgZmVlZERhdGE6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgICAgICBsZXQgYXR0ZW1wdHMgPSAwO1xuICAgICAgICBjb25zdCBtYXhBdHRlbXB0cyA9IDEwO1xuXG4gICAgICAgIHdoaWxlIChhdHRlbXB0cyA8IG1heEF0dGVtcHRzICYmICFmZWVkRGF0YSkge1xuICAgICAgICAgIGF3YWl0IHNsZWVwKDIwMDApOyAvLyBXYWl0IDIgc2Vjb25kcyBiZXR3ZWVuIGF0dGVtcHRzXG4gICAgICAgICAgYXR0ZW1wdHMrKztcblxuICAgICAgICAgIGZlZWREYXRhID0gKGF3YWl0IHBhZ2UuZXZhbHVhdGUoYFxuICAgICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXyAmJiB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18uZmVlZCAmJiB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18uZmVlZC5mZWVkcyAmJiB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18uZmVlZC5mZWVkcy5fdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgLy8gVHJ5IHRvIHNlcmlhbGl6ZSBqdXN0IHRoZSBmZWVkcyBkYXRhIHRvIGF2b2lkIGNpcmN1bGFyIHJlZmVyZW5jZSBpc3N1ZXNcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZlZWRzRGF0YSA9IHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5mZWVkLmZlZWRzLl92YWx1ZTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShmZWVkc0RhdGEpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gc2VyaWFsaXplIGZlZWRzIGRhdGE6JywgZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH0pKClcbiAgICAgICAgICBgKSkgYXMgc3RyaW5nIHwgbnVsbDtcblxuICAgICAgICAgIGlmIChmZWVkRGF0YSkge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYEZlZWQgcmVzdWx0cyBsb2FkZWQgYWZ0ZXIgJHthdHRlbXB0c30gYXR0ZW1wdHNgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZmVlZERhdGEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmVlZFBhcnNpbmdFcnJvcihcbiAgICAgICAgICAgIGBDb3VsZCBub3QgZXh0cmFjdCBmZWVkIGRhdGEgYWZ0ZXIgJHttYXhBdHRlbXB0c30gYXR0ZW1wdHMuIFRoZSBwYWdlIG1heSBub3QgYmUgZnVsbHkgbG9hZGVkIG9yIHRoZSBzdGF0ZSBzdHJ1Y3R1cmUgaGFzIGNoYW5nZWQuYCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdXJsOiB0aGlzLmdldENvbmZpZygpLnhocy5ob21lVXJsLFxuICAgICAgICAgICAgICBzdWdnZXN0aW9uOiAnVHJ5IGxvZ2dpbmcgaW4gZmlyc3QgdXNpbmcgeGhzX2F1dGhfbG9naW4gdG9vbCcsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZlZWRzVmFsdWUgPSBKU09OLnBhcnNlKGZlZWREYXRhKSBhcyB1bmtub3duW107XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIGZlZWRzOiBmZWVkc1ZhbHVlIGFzIEZlZWRJdGVtW10sXG4gICAgICAgICAgY291bnQ6IGZlZWRzVmFsdWUubGVuZ3RoLFxuICAgICAgICAgIHNvdXJjZTogJ2hvbWVfcGFnZScsXG4gICAgICAgICAgdXJsOiB0aGlzLmdldENvbmZpZygpLnhocy5ob21lVXJsLFxuICAgICAgICB9O1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb3RMb2dnZWRJbkVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgRmVlZFBhcnNpbmdFcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGdldCBmZWVkIGxpc3Q6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgWEhTRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gZ2V0IGZlZWQgbGlzdDogJHtlcnJvcn1gLFxuICAgICAgICAnR2V0RmVlZExpc3RFcnJvcicsXG4gICAgICAgIHt9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzZWFyY2hGZWVkcyhrZXl3b3JkOiBzdHJpbmcsIGJyb3dzZXJQYXRoPzogc3RyaW5nKTogUHJvbWlzZTxTZWFyY2hSZXN1bHQ+IHtcbiAgICBpZiAoIWtleXdvcmQgfHwgIWtleXdvcmQudHJpbSgpKSB7XG4gICAgICB0aHJvdyBuZXcgRmVlZEVycm9yKCdTZWFyY2gga2V5d29yZCBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICBjb25zdCB0cmltbWVkS2V5d29yZCA9IGtleXdvcmQudHJpbSgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZSh0cnVlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHNlYXJjaFVybCA9IG1ha2VTZWFyY2hVcmwodHJpbW1lZEtleXdvcmQpO1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkocGFnZSwgc2VhcmNoVXJsKTtcblxuICAgICAgICAvLyBXYWl0IGZvciBzZWFyY2ggcmVzdWx0cyB0byBsb2FkIHdpdGggbXVsdGlwbGUgYXR0ZW1wdHNcbiAgICAgICAgbGV0IHNlYXJjaERhdGE6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgICAgICBsZXQgYXR0ZW1wdHMgPSAwO1xuICAgICAgICBjb25zdCBtYXhBdHRlbXB0cyA9IDEwO1xuXG4gICAgICAgIHdoaWxlIChhdHRlbXB0cyA8IG1heEF0dGVtcHRzICYmICFzZWFyY2hEYXRhKSB7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7IC8vIFdhaXQgMiBzZWNvbmRzIGJldHdlZW4gYXR0ZW1wdHNcbiAgICAgICAgICBhdHRlbXB0cysrO1xuXG4gICAgICAgICAgc2VhcmNoRGF0YSA9IChhd2FpdCBwYWdlLmV2YWx1YXRlKGBcbiAgICAgICAgICAgICgoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICh3aW5kb3cuX19JTklUSUFMX1NUQVRFX18gJiYgd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLnNlYXJjaCAmJiB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18uc2VhcmNoLmZlZWRzICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5zZWFyY2guZmVlZHMuX3ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIC8vIFRyeSB0byBzZXJpYWxpemUganVzdCB0aGUgZmVlZHMgZGF0YSB0byBhdm9pZCBjaXJjdWxhciByZWZlcmVuY2UgaXNzdWVzXG4gICAgICAgICAgICAgICAgICBjb25zdCBmZWVkc0RhdGEgPSB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18uc2VhcmNoLmZlZWRzLl92YWx1ZTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShmZWVkc0RhdGEpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gc2VyaWFsaXplIGZlZWRzIGRhdGE6JywgZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH0pKClcbiAgICAgICAgICBgKSkgYXMgc3RyaW5nIHwgbnVsbDtcblxuICAgICAgICAgIGlmIChzZWFyY2hEYXRhKSB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhgU2VhcmNoIHJlc3VsdHMgbG9hZGVkIGFmdGVyICR7YXR0ZW1wdHN9IGF0dGVtcHRzYCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXNlYXJjaERhdGEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmVlZFBhcnNpbmdFcnJvcihcbiAgICAgICAgICAgIGBDb3VsZCBub3QgZXh0cmFjdCBzZWFyY2ggcmVzdWx0cyBmb3Iga2V5d29yZDogJHt0cmltbWVkS2V5d29yZH0gYWZ0ZXIgJHttYXhBdHRlbXB0c30gYXR0ZW1wdHNgLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBrZXl3b3JkOiB0cmltbWVkS2V5d29yZCxcbiAgICAgICAgICAgICAgdXJsOiBzZWFyY2hVcmwsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZlZWRzVmFsdWUgPSBKU09OLnBhcnNlKHNlYXJjaERhdGEpIGFzIHVua25vd25bXTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAga2V5d29yZDogdHJpbW1lZEtleXdvcmQsXG4gICAgICAgICAgZmVlZHM6IGZlZWRzVmFsdWUgYXMgRmVlZEl0ZW1bXSxcbiAgICAgICAgICBjb3VudDogZmVlZHNWYWx1ZS5sZW5ndGgsXG4gICAgICAgICAgc2VhcmNoVXJsLFxuICAgICAgICB9O1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBGZWVkRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICBsb2dnZXIuZXJyb3IoYEZlZWQgc2VhcmNoIGZhaWxlZCBmb3Iga2V5d29yZCAnJHt0cmltbWVkS2V5d29yZH0nOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKFxuICAgICAgICBgRmVlZCBzZWFyY2ggZmFpbGVkOiAke2Vycm9yfWAsXG4gICAgICAgICdTZWFyY2hGZWVkc0Vycm9yJyxcbiAgICAgICAgeyBrZXl3b3JkOiB0cmltbWVkS2V5d29yZCB9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnZXRGZWVkRGV0YWlsKFxuICAgIGZlZWRJZDogc3RyaW5nLFxuICAgIHhzZWNUb2tlbjogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8RmVlZERldGFpbFJlc3VsdD4ge1xuICAgIGlmICghZmVlZElkIHx8ICF4c2VjVG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBGZWVkRXJyb3IoJ0JvdGggZmVlZF9pZCBhbmQgeHNlY190b2tlbiBhcmUgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGV0YWlsVXJsID0gbWFrZUZlZWREZXRhaWxVcmwoZmVlZElkLCB4c2VjVG9rZW4pO1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkocGFnZSwgZGV0YWlsVXJsKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG5cbiAgICAgICAgY29uc3Qgc3RhdGUgPSBhd2FpdCBleHRyYWN0SW5pdGlhbFN0YXRlKHBhZ2UpO1xuXG4gICAgICAgIGNvbnN0IG5vdGVEYXRhID0gc3RhdGU/Lm5vdGUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgIGlmICghc3RhdGUgfHwgIW5vdGVEYXRhIHx8ICFub3RlRGF0YS5ub3RlRGV0YWlsTWFwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZlZWRQYXJzaW5nRXJyb3IoYENvdWxkIG5vdCBleHRyYWN0IG5vdGUgZGV0YWlscyBmb3IgZmVlZDogJHtmZWVkSWR9YCwge1xuICAgICAgICAgICAgZmVlZElkLFxuICAgICAgICAgICAgdXJsOiBkZXRhaWxVcmwsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBub3RlRGV0YWlsTWFwID0gbm90ZURhdGEubm90ZURldGFpbE1hcCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgaWYgKCEoZmVlZElkIGluIG5vdGVEZXRhaWxNYXApKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZlZWROb3RGb3VuZEVycm9yKGBGZWVkICR7ZmVlZElkfSBub3QgZm91bmQgaW4gbm90ZSBkZXRhaWxzYCwge1xuICAgICAgICAgICAgZmVlZElkLFxuICAgICAgICAgICAgYXZhaWxhYmxlRmVlZHM6IE9iamVjdC5rZXlzKG5vdGVEZXRhaWxNYXApLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGV0YWlsID0gbm90ZURldGFpbE1hcFtmZWVkSWRdIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBmZWVkSWQsXG4gICAgICAgICAgZGV0YWlsLFxuICAgICAgICAgIHVybDogZGV0YWlsVXJsLFxuICAgICAgICB9O1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRmVlZEVycm9yIHx8XG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRmVlZE5vdEZvdW5kRXJyb3IgfHxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBGZWVkUGFyc2luZ0Vycm9yXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgZmVlZCBkZXRhaWwgZm9yICR7ZmVlZElkfTogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBnZXQgZmVlZCBkZXRhaWw6ICR7ZXJyb3J9YCxcbiAgICAgICAgJ0dldEZlZWREZXRhaWxFcnJvcicsXG4gICAgICAgIHsgZmVlZElkIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNvbW1lbnRPbkZlZWQoXG4gICAgZmVlZElkOiBzdHJpbmcsXG4gICAgeHNlY1Rva2VuOiBzdHJpbmcsXG4gICAgbm90ZTogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8Q29tbWVudFJlc3VsdD4ge1xuICAgIGlmICghZmVlZElkIHx8ICF4c2VjVG9rZW4gfHwgIW5vdGUpIHtcbiAgICAgIHRocm93IG5ldyBGZWVkRXJyb3IoJ2ZlZWRfaWQsIHhzZWNfdG9rZW4sIGFuZCBub3RlIGFyZSBhbGwgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAobm90ZS50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRmVlZEVycm9yKCdDb21tZW50IG5vdGUgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZShmYWxzZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkZXRhaWxVcmwgPSBtYWtlRmVlZERldGFpbFVybChmZWVkSWQsIHhzZWNUb2tlbik7XG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShwYWdlLCBkZXRhaWxVcmwpO1xuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBsb2dnZWQgaW5cbiAgICAgICAgaWYgKCEoYXdhaXQgaXNMb2dnZWRJbihwYWdlKSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm90TG9nZ2VkSW5FcnJvcignTXVzdCBiZSBsb2dnZWQgaW4gdG8gY29tbWVudCBvbiBmZWVkcycsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogJ2NvbW1lbnRfb25fZmVlZCcsXG4gICAgICAgICAgICBmZWVkSWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDbGljayBvbiBjb21tZW50IGlucHV0XG4gICAgICAgIGNvbnN0IGNvbW1lbnRJbnB1dFNlbGVjdG9yID0gJ2Rpdi5pbnB1dC1ib3ggZGl2LmNvbnRlbnQtZWRpdCBzcGFuJztcbiAgICAgICAgaWYgKCEoYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLnRyeVdhaXRGb3JTZWxlY3RvcihwYWdlLCBjb21tZW50SW5wdXRTZWxlY3RvcikpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZlZWRFcnJvcignQ29tbWVudCBpbnB1dCBub3QgZm91bmQgb24gcGFnZScsIHtcbiAgICAgICAgICAgIGZlZWRJZCxcbiAgICAgICAgICAgIHNlbGVjdG9yOiBjb21tZW50SW5wdXRTZWxlY3RvcixcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbW1lbnRJbnB1dCA9IGF3YWl0IHBhZ2UuJChjb21tZW50SW5wdXRTZWxlY3Rvcik7XG4gICAgICAgIGlmIChjb21tZW50SW5wdXQpIHtcbiAgICAgICAgICBhd2FpdCBjb21tZW50SW5wdXQuY2xpY2soKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZpbGwgY29tbWVudCBub3RlXG4gICAgICAgIGNvbnN0IGVkaXRvclNlbGVjdG9yID0gJ2Rpdi5pbnB1dC1ib3ggZGl2LmNvbnRlbnQtZWRpdCBwLmNvbnRlbnQtaW5wdXQnO1xuICAgICAgICBjb25zdCBlZGl0b3IgPSBhd2FpdCBwYWdlLiQoZWRpdG9yU2VsZWN0b3IpO1xuXG4gICAgICAgIGlmIChlZGl0b3IpIHtcbiAgICAgICAgICBhd2FpdCBlZGl0b3IuY2xpY2soKTtcbiAgICAgICAgICBhd2FpdCBlZGl0b3IudHlwZShub3RlLCB7IGRlbGF5OiAzMCB9KTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgICAvLyBTdWJtaXQgY29tbWVudFxuICAgICAgICBjb25zdCBzdWJtaXRTZWxlY3RvciA9ICdkaXYuYm90dG9tIGJ1dHRvbi5zdWJtaXQnO1xuICAgICAgICBjb25zdCBzdWJtaXRCdXR0b24gPSBhd2FpdCBwYWdlLiQoc3VibWl0U2VsZWN0b3IpO1xuICAgICAgICBpZiAoc3VibWl0QnV0dG9uKSB7XG4gICAgICAgICAgYXdhaXQgc3VibWl0QnV0dG9uLmNsaWNrKCk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7IC8vIFdhaXQgZm9yIHN1Ym1pc3Npb25cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgbWVzc2FnZTogJ0NvbW1lbnQgc3VibWl0dGVkIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgZmVlZElkLFxuICAgICAgICAgIG5vdGUsXG4gICAgICAgICAgdXJsOiBkZXRhaWxVcmwsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEZlZWRFcnJvciB8fCBlcnJvciBpbnN0YW5jZW9mIE5vdExvZ2dlZEluRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBjb21tZW50IG9uIGZlZWQgJHtmZWVkSWR9OiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGNvbW1lbnQgb24gZmVlZDogJHtlcnJvcn1gLFxuICAgICAgICAnQ29tbWVudE9uRmVlZEVycm9yJyxcbiAgICAgICAgeyBmZWVkSWQgfSxcbiAgICAgICAgZXJyb3IgYXMgRXJyb3JcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIFRpdGxlIHZhbGlkYXRpb24gdXRpbGl0eSBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqIFZhbGlkYXRlcyB0aXRsZSB3aWR0aCBhY2NvcmRpbmcgdG8gWGlhb0hvbmdTaHUncyBkaXNwbGF5IHdpZHRoIHJ1bGVzXG4gKlxuICogWEhTIFJ1bGVzOlxuICogLSBNYXggd2lkdGg6IDQwIHVuaXRzXG4gKiAtIENKSyBjaGFyYWN0ZXJzIChDaGluZXNlL0phcGFuZXNlL0tvcmVhbik6IDIgdW5pdHMgZWFjaFxuICogLSBPdGhlciBjaGFyYWN0ZXJzIChFbmdsaXNoL051bWJlcnMpOiAxIHVuaXQgZWFjaFxuICovXG5cbmltcG9ydCBzdHJpbmdXaWR0aCBmcm9tICdzdHJpbmctd2lkdGgnO1xuaW1wb3J0IHsgUHVibGlzaEVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRpdGxlVmFsaWRhdGlvblJlc3VsdCB7XG4gIHZhbGlkOiBib29sZWFuO1xuICB3aWR0aDogbnVtYmVyO1xuICBtYXhXaWR0aDogbnVtYmVyO1xuICBtZXNzYWdlPzogc3RyaW5nO1xuICBzdWdnZXN0aW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFhpYW9Ib25nU2h1IHRpdGxlIGNvbnN0cmFpbnRzXG4gKi9cbmV4cG9ydCBjb25zdCBYSFNfVElUTEVfQ09OU1RSQUlOVFMgPSB7XG4gIE1BWF9XSURUSDogNDAsIC8vIE1heGltdW0gZGlzcGxheSB3aWR0aCBpbiB1bml0c1xuICBNQVhfTEVOR1RIOiAyMCwgLy8gQXBwcm94aW1hdGUgbWF4IGNoYXJhY3RlciBjb3VudCAoZm9yIHJlZmVyZW5jZSlcbn0gYXMgY29uc3Q7XG5cbi8qKlxuICogVmFsaWRhdGUgdGl0bGUgd2lkdGggYWNjb3JkaW5nIHRvIFhIUyBkaXNwbGF5IHJ1bGVzXG4gKlxuICogQHBhcmFtIHRpdGxlIC0gVGhlIHRpdGxlIHRvIHZhbGlkYXRlXG4gKiBAcmV0dXJucyBWYWxpZGF0aW9uIHJlc3VsdCB3aXRoIHdpZHRoIGluZm9ybWF0aW9uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRlVGl0bGVXaWR0aCgnSGVsbG/kuJbnlYwnKTtcbiAqIGNvbnNvbGUubG9nKHJlc3VsdC53aWR0aCk7IC8vIDEwICg1ICsgMioyICsgMSA9IDEwKVxuICogY29uc29sZS5sb2cocmVzdWx0LnZhbGlkKTsgLy8gdHJ1ZVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVRpdGxlV2lkdGgodGl0bGU6IHN0cmluZyk6IFRpdGxlVmFsaWRhdGlvblJlc3VsdCB7XG4gIGlmICghdGl0bGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgd2lkdGg6IDAsXG4gICAgICBtYXhXaWR0aDogWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSCxcbiAgICAgIG1lc3NhZ2U6ICdUaXRsZSBjYW5ub3QgYmUgZW1wdHknLFxuICAgICAgc3VnZ2VzdGlvbjogJ1BsZWFzZSBwcm92aWRlIGEgdmFsaWQgdGl0bGUnLFxuICAgIH07XG4gIH1cblxuICAvLyBDYWxjdWxhdGUgZGlzcGxheSB3aWR0aCB1c2luZyBzdHJpbmctd2lkdGhcbiAgLy8gVGhpcyBjb3JyZWN0bHkgaGFuZGxlcyBDSksgY2hhcmFjdGVycywgZW1vamksIGFuZCBvdGhlciBVbmljb2RlXG4gIGNvbnN0IHdpZHRoID0gc3RyaW5nV2lkdGgodGl0bGUpO1xuXG4gIGlmICh3aWR0aCA+IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgd2lkdGgsXG4gICAgICBtYXhXaWR0aDogWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSCxcbiAgICAgIG1lc3NhZ2U6IGBUaXRsZSB3aWR0aCBleGNlZWRzIGxpbWl0OiAke3dpZHRofSB1bml0cyAobWF4OiAke1hIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEh9IHVuaXRzKWAsXG4gICAgICBzdWdnZXN0aW9uOiBgQ3VycmVudCB0aXRsZSBpcyB0b28gbG9uZy4gQ0pLIGNoYXJhY3RlcnMgY291bnQgYXMgMiB1bml0cywgRW5nbGlzaC9udW1iZXJzIGFzIDEgdW5pdC4gUGxlYXNlIHNob3J0ZW4geW91ciB0aXRsZS5gLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHZhbGlkOiB0cnVlLFxuICAgIHdpZHRoLFxuICAgIG1heFdpZHRoOiBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRILFxuICB9O1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIGFuZCB0aHJvdyBlcnJvciBpZiB0aXRsZSB3aWR0aCBpcyBpbnZhbGlkXG4gKlxuICogQHBhcmFtIHRpdGxlIC0gVGhlIHRpdGxlIHRvIHZhbGlkYXRlXG4gKiBAdGhyb3dzIFB1Ymxpc2hFcnJvciBpZiB0aXRsZSB3aWR0aCBpcyBpbnZhbGlkXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyeSB7XG4gKiAgIGFzc2VydFRpdGxlV2lkdGhWYWxpZCgn5b6I6ZW/5b6I6ZW/55qE5qCH6aKYJy5yZXBlYXQoMTApKTtcbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydFRpdGxlV2lkdGhWYWxpZCh0aXRsZTogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRlVGl0bGVXaWR0aCh0aXRsZSk7XG5cbiAgaWYgKCFyZXN1bHQudmFsaWQpIHtcbiAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKHJlc3VsdC5tZXNzYWdlISwge1xuICAgICAgdGl0bGUsXG4gICAgICB3aWR0aDogcmVzdWx0LndpZHRoLFxuICAgICAgbWF4V2lkdGg6IHJlc3VsdC5tYXhXaWR0aCxcbiAgICAgIHN1Z2dlc3Rpb246IHJlc3VsdC5zdWdnZXN0aW9uLFxuICAgICAgZGV0YWlsczoge1xuICAgICAgICB0aXRsZUxlbmd0aDogdGl0bGUubGVuZ3RoLFxuICAgICAgICBkaXNwbGF5V2lkdGg6IHJlc3VsdC53aWR0aCxcbiAgICAgICAgbWF4RGlzcGxheVdpZHRoOiByZXN1bHQubWF4V2lkdGgsXG4gICAgICAgIGV4Y2VlZGVkOiByZXN1bHQud2lkdGggLSByZXN1bHQubWF4V2lkdGgsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSBkaXNwbGF5IHdpZHRoIG9mIGEgdGl0bGVcbiAqXG4gKiBAcGFyYW0gdGl0bGUgLSBUaGUgdGl0bGUgdG8gbWVhc3VyZVxuICogQHJldHVybnMgRGlzcGxheSB3aWR0aCBpbiB1bml0c1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zb2xlLmxvZyhnZXRUaXRsZVdpZHRoKCdIZWxsbycpKTsgICAgICAgIC8vIDVcbiAqIGNvbnNvbGUubG9nKGdldFRpdGxlV2lkdGgoJ+S9oOWlvScpKTsgICAgICAgICAvLyA0ICgyKjIpXG4gKiBjb25zb2xlLmxvZyhnZXRUaXRsZVdpZHRoKCdIZWxsb+S4lueVjCcpKTsgICAgLy8gMTAgKDUgKyAyKjIgKyAxKVxuICogY29uc29sZS5sb2coZ2V0VGl0bGVXaWR0aCgn8J+Ri0hlbGxvJykpOyAgICAgIC8vIDcgKDIgKyA1KVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUaXRsZVdpZHRoKHRpdGxlOiBzdHJpbmcpOiBudW1iZXIge1xuICByZXR1cm4gc3RyaW5nV2lkdGgodGl0bGUpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBob3cgbWFueSBjaGFyYWN0ZXJzIGNhbiBiZSBhZGRlZCB0byB0aGUgdGl0bGVcbiAqXG4gKiBAcGFyYW0gdGl0bGUgLSBDdXJyZW50IHRpdGxlXG4gKiBAcmV0dXJucyBSZW1haW5pbmcgd2lkdGggdW5pdHMgYXZhaWxhYmxlXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlbWFpbmluZyA9IGdldFJlbWFpbmluZ1RpdGxlV2lkdGgoJ0hlbGxvJyk7IC8vIDM1XG4gKiBjb25zb2xlLmxvZyhgWW91IGNhbiBhZGQgJHtyZW1haW5pbmd9IG1vcmUgdW5pdHNgKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlUmVtYWluaW5nVGl0bGVXaWR0aCh0aXRsZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgY29uc3QgY3VycmVudFdpZHRoID0gZ2V0VGl0bGVXaWR0aCh0aXRsZSk7XG4gIHJldHVybiBNYXRoLm1heCgwLCBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRIIC0gY3VycmVudFdpZHRoKTtcbn1cblxuLyoqXG4gKiBUcnVuY2F0ZSB0aXRsZSB0byBmaXQgd2l0aGluIHdpZHRoIGxpbWl0XG4gKlxuICogQHBhcmFtIHRpdGxlIC0gVGhlIHRpdGxlIHRvIHRydW5jYXRlXG4gKiBAcGFyYW0gbWF4V2lkdGggLSBNYXhpbXVtIHdpZHRoIChkZWZhdWx0OiBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRIKVxuICogQHJldHVybnMgVHJ1bmNhdGVkIHRpdGxlIHRoYXQgZml0cyB3aXRoaW4gd2lkdGggbGltaXRcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbG9uZyA9ICfov5nmmK/kuIDkuKrlvojplb/lvojplb/nmoTmoIfpopgnLnJlcGVhdCg1KTtcbiAqIGNvbnN0IHRydW5jYXRlZCA9IHRydW5jYXRlVGl0bGVUb1dpZHRoKGxvbmcpO1xuICogY29uc29sZS5sb2coZ2V0VGl0bGVXaWR0aCh0cnVuY2F0ZWQpKTsgLy8gPD0gNDBcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJ1bmNhdGVUaXRsZVRvV2lkdGgoXG4gIHRpdGxlOiBzdHJpbmcsXG4gIG1heFdpZHRoOiBudW1iZXIgPSBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRIXG4pOiBzdHJpbmcge1xuICBpZiAoZ2V0VGl0bGVXaWR0aCh0aXRsZSkgPD0gbWF4V2lkdGgpIHtcbiAgICByZXR1cm4gdGl0bGU7XG4gIH1cblxuICBsZXQgdHJ1bmNhdGVkID0gJyc7XG4gIGxldCBjdXJyZW50V2lkdGggPSAwO1xuXG4gIGZvciAoY29uc3QgY2hhciBvZiB0aXRsZSkge1xuICAgIGNvbnN0IGNoYXJXaWR0aCA9IHN0cmluZ1dpZHRoKGNoYXIpO1xuXG4gICAgaWYgKGN1cnJlbnRXaWR0aCArIGNoYXJXaWR0aCA+IG1heFdpZHRoKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0cnVuY2F0ZWQgKz0gY2hhcjtcbiAgICBjdXJyZW50V2lkdGggKz0gY2hhcldpZHRoO1xuICB9XG5cbiAgcmV0dXJuIHRydW5jYXRlZDtcbn1cblxuLyoqXG4gKiBHZXQgaHVtYW4tcmVhZGFibGUgd2lkdGggYnJlYWtkb3duXG4gKiBVc2VmdWwgZm9yIGRlYnVnZ2luZyBhbmQgdXNlciBmZWVkYmFja1xuICpcbiAqIEBwYXJhbSB0aXRsZSAtIFRoZSB0aXRsZSB0byBhbmFseXplXG4gKiBAcmV0dXJucyBXaWR0aCBicmVha2Rvd24gaW5mb3JtYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRpdGxlV2lkdGhCcmVha2Rvd24odGl0bGU6IHN0cmluZyk6IHtcbiAgdGl0bGU6IHN0cmluZztcbiAgdG90YWxXaWR0aDogbnVtYmVyO1xuICB0b3RhbENoYXJzOiBudW1iZXI7XG4gIG1heFdpZHRoOiBudW1iZXI7XG4gIHJlbWFpbmluZzogbnVtYmVyO1xuICB2YWxpZDogYm9vbGVhbjtcbiAgYnJlYWtkb3duOiBBcnJheTx7XG4gICAgY2hhcjogc3RyaW5nO1xuICAgIHdpZHRoOiBudW1iZXI7XG4gICAgdHlwZTogJ0NKSycgfCAnQVNDSUknIHwgJ0Vtb2ppJyB8ICdPdGhlcic7XG4gIH0+O1xufSB7XG4gIGNvbnN0IHRvdGFsV2lkdGggPSBnZXRUaXRsZVdpZHRoKHRpdGxlKTtcbiAgY29uc3QgYnJlYWtkb3duOiBBcnJheTx7XG4gICAgY2hhcjogc3RyaW5nO1xuICAgIHdpZHRoOiBudW1iZXI7XG4gICAgdHlwZTogJ0NKSycgfCAnQVNDSUknIHwgJ0Vtb2ppJyB8ICdPdGhlcic7XG4gIH0+ID0gW107XG5cbiAgZm9yIChjb25zdCBjaGFyIG9mIHRpdGxlKSB7XG4gICAgY29uc3QgY2hhcldpZHRoID0gc3RyaW5nV2lkdGgoY2hhcik7XG4gICAgbGV0IHR5cGU6ICdDSksnIHwgJ0FTQ0lJJyB8ICdFbW9qaScgfCAnT3RoZXInID0gJ090aGVyJztcblxuICAgIGNvbnN0IGNvZGUgPSBjaGFyLmNoYXJDb2RlQXQoMCk7XG4gICAgaWYgKGNoYXIubWF0Y2goL1tcXHU0ZTAwLVxcdTlmZmZcXHUzNDAwLVxcdTRkYmZcXHVmOTAwLVxcdWZhZmZdLykpIHtcbiAgICAgIHR5cGUgPSAnQ0pLJztcbiAgICB9IGVsc2UgaWYgKGNvZGUgPCAxMjgpIHtcbiAgICAgIHR5cGUgPSAnQVNDSUknO1xuICAgIH0gZWxzZSBpZiAoY2hhci5tYXRjaCgvW1xcdXsxRjMwMH0tXFx1ezFGOUZGfV0vdSkpIHtcbiAgICAgIHR5cGUgPSAnRW1vamknO1xuICAgIH1cblxuICAgIGJyZWFrZG93bi5wdXNoKHsgY2hhciwgd2lkdGg6IGNoYXJXaWR0aCwgdHlwZSB9KTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdGl0bGUsXG4gICAgdG90YWxXaWR0aCxcbiAgICB0b3RhbENoYXJzOiB0aXRsZS5sZW5ndGgsXG4gICAgbWF4V2lkdGg6IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgsXG4gICAgcmVtYWluaW5nOiBjYWxjdWxhdGVSZW1haW5pbmdUaXRsZVdpZHRoKHRpdGxlKSxcbiAgICB2YWxpZDogdG90YWxXaWR0aCA8PSBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRILFxuICAgIGJyZWFrZG93bixcbiAgfTtcbn1cbiIsImNvbnN0IF9fV0VCUEFDS19OQU1FU1BBQ0VfT0JKRUNUX18gPSByZXF1aXJlKFwiY3J5cHRvXCIpOyIsImNvbnN0IF9fV0VCUEFDS19OQU1FU1BBQ0VfT0JKRUNUX18gPSByZXF1aXJlKFwibm9kZS1mZXRjaFwiKTsiLCIvKipcbiAqIEltYWdlIGRvd25sb2FkZXIgdXRpbGl0eSBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqIFN1cHBvcnRzIGRvd25sb2FkaW5nIGltYWdlcyBmcm9tIEhUVFAvSFRUUFMgVVJMc1xuICovXG5cbmltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgZXhpc3RzU3luYywgbWtkaXJTeW5jLCB3cml0ZUZpbGVTeW5jLCBzdGF0U3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbmltcG9ydCBmZXRjaCBmcm9tICdub2RlLWZldGNoJztcbmltcG9ydCB7IEludmFsaWRJbWFnZUVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIERvd25sb2FkUmVzdWx0IHtcbiAgb3JpZ2luYWxVcmw6IHN0cmluZztcbiAgbG9jYWxQYXRoOiBzdHJpbmc7XG4gIGNhY2hlZDogYm9vbGVhbjtcbiAgZmlsZVNpemU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNsYXNzIEltYWdlRG93bmxvYWRlciB7XG4gIHByaXZhdGUgc2F2ZURpcjogc3RyaW5nO1xuICBwcml2YXRlIHRpbWVvdXQ6IG51bWJlcjtcbiAgcHJpdmF0ZSBtYXhGaWxlU2l6ZTogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHNhdmVEaXI6IHN0cmluZyA9ICcuL3RlbXBfaW1hZ2VzJyxcbiAgICB0aW1lb3V0OiBudW1iZXIgPSAzMDAwMCxcbiAgICBtYXhGaWxlU2l6ZTogbnVtYmVyID0gMTAgKiAxMDI0ICogMTAyNCAvLyAxME1CIGRlZmF1bHRcbiAgKSB7XG4gICAgdGhpcy5zYXZlRGlyID0gc2F2ZURpcjtcbiAgICB0aGlzLnRpbWVvdXQgPSB0aW1lb3V0O1xuICAgIHRoaXMubWF4RmlsZVNpemUgPSBtYXhGaWxlU2l6ZTtcblxuICAgIC8vIEVuc3VyZSBzYXZlIGRpcmVjdG9yeSBleGlzdHNcbiAgICBpZiAoIWV4aXN0c1N5bmModGhpcy5zYXZlRGlyKSkge1xuICAgICAgbWtkaXJTeW5jKHRoaXMuc2F2ZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgc3RyaW5nIGlzIGEgdmFsaWQgSFRUUC9IVFRQUyBVUkxcbiAgICovXG4gIHN0YXRpYyBpc0ltYWdlVXJsKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghcGF0aCkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGxvd2VyUGF0aCA9IHBhdGgudG9Mb3dlckNhc2UoKS50cmltKCk7XG4gICAgcmV0dXJuIGxvd2VyUGF0aC5zdGFydHNXaXRoKCdodHRwOi8vJykgfHwgbG93ZXJQYXRoLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJyk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgYSB1bmlxdWUgZmlsZW5hbWUgZm9yIGFuIGltYWdlIFVSTFxuICAgKiBVc2VzIG9ubHkgVVJMIGhhc2ggZm9yIGNvbnNpc3RlbnQgY2FjaGluZ1xuICAgKi9cbiAgcHJpdmF0ZSBnZW5lcmF0ZUZpbGVOYW1lKGltYWdlVXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIC8vIFVzZSBTSEEyNTYgaGFzaCBvZiBVUkwgZm9yIHVuaXF1ZW5lc3NcbiAgICBjb25zdCBoYXNoID0gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKGltYWdlVXJsKS5kaWdlc3QoJ2hleCcpO1xuICAgIGNvbnN0IHNob3J0SGFzaCA9IGhhc2guc3Vic3RyaW5nKDAsIDE2KTtcblxuICAgIC8vIFRyeSB0byBleHRyYWN0IGV4dGVuc2lvbiBmcm9tIFVSTFxuICAgIGxldCBleHRlbnNpb24gPSAnanBnJzsgLy8gZGVmYXVsdFxuICAgIHRyeSB7XG4gICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKGltYWdlVXJsKTtcbiAgICAgIGNvbnN0IHBhdGhuYW1lID0gdXJsLnBhdGhuYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICBjb25zdCBtYXRjaCA9IHBhdGhuYW1lLm1hdGNoKC9cXC4oanBnfGpwZWd8cG5nfGdpZnx3ZWJwfGJtcCkkL2kpO1xuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGV4dGVuc2lvbiA9IG1hdGNoWzFdO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gVXNlIGRlZmF1bHQgZXh0ZW5zaW9uXG4gICAgfVxuXG4gICAgLy8gRml4ZWQgZmlsZW5hbWUgZm9yIHByb3BlciBjYWNoaW5nIChubyB0aW1lc3RhbXApXG4gICAgcmV0dXJuIGBpbWdfJHtzaG9ydEhhc2h9LiR7ZXh0ZW5zaW9ufWA7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhhdCBkb3dubG9hZGVkIGRhdGEgaXMgYWN0dWFsbHkgYW4gaW1hZ2VcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVJbWFnZURhdGEoYnVmZmVyOiBCdWZmZXIpOiB7IGlzVmFsaWQ6IGJvb2xlYW47IGV4dGVuc2lvbjogc3RyaW5nIH0ge1xuICAgIC8vIENoZWNrIGZpbGUgc2lnbmF0dXJlcyAobWFnaWMgbnVtYmVycylcbiAgICBpZiAoYnVmZmVyLmxlbmd0aCA8IDEyKSB7XG4gICAgICByZXR1cm4geyBpc1ZhbGlkOiBmYWxzZSwgZXh0ZW5zaW9uOiAnJyB9O1xuICAgIH1cblxuICAgIC8vIEpQRUdcbiAgICBpZiAoYnVmZmVyWzBdID09PSAweGZmICYmIGJ1ZmZlclsxXSA9PT0gMHhkOCAmJiBidWZmZXJbMl0gPT09IDB4ZmYpIHtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IHRydWUsIGV4dGVuc2lvbjogJ2pwZycgfTtcbiAgICB9XG5cbiAgICAvLyBQTkdcbiAgICBpZiAoYnVmZmVyWzBdID09PSAweDg5ICYmIGJ1ZmZlclsxXSA9PT0gMHg1MCAmJiBidWZmZXJbMl0gPT09IDB4NGUgJiYgYnVmZmVyWzNdID09PSAweDQ3KSB7XG4gICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlLCBleHRlbnNpb246ICdwbmcnIH07XG4gICAgfVxuXG4gICAgLy8gR0lGXG4gICAgaWYgKGJ1ZmZlclswXSA9PT0gMHg0NyAmJiBidWZmZXJbMV0gPT09IDB4NDkgJiYgYnVmZmVyWzJdID09PSAweDQ2KSB7XG4gICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlLCBleHRlbnNpb246ICdnaWYnIH07XG4gICAgfVxuXG4gICAgLy8gV2ViUFxuICAgIGlmIChcbiAgICAgIGJ1ZmZlclswXSA9PT0gMHg1MiAmJlxuICAgICAgYnVmZmVyWzFdID09PSAweDQ5ICYmXG4gICAgICBidWZmZXJbMl0gPT09IDB4NDYgJiZcbiAgICAgIGJ1ZmZlclszXSA9PT0gMHg0NiAmJlxuICAgICAgYnVmZmVyWzhdID09PSAweDU3ICYmXG4gICAgICBidWZmZXJbOV0gPT09IDB4NDUgJiZcbiAgICAgIGJ1ZmZlclsxMF0gPT09IDB4NDIgJiZcbiAgICAgIGJ1ZmZlclsxMV0gPT09IDB4NTBcbiAgICApIHtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IHRydWUsIGV4dGVuc2lvbjogJ3dlYnAnIH07XG4gICAgfVxuXG4gICAgLy8gQk1QXG4gICAgaWYgKGJ1ZmZlclswXSA9PT0gMHg0MiAmJiBidWZmZXJbMV0gPT09IDB4NGQpIHtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IHRydWUsIGV4dGVuc2lvbjogJ2JtcCcgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBpc1ZhbGlkOiBmYWxzZSwgZXh0ZW5zaW9uOiAnJyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIERvd25sb2FkIGEgc2luZ2xlIGltYWdlIGZyb20gVVJMXG4gICAqL1xuICBhc3luYyBkb3dubG9hZEltYWdlKGltYWdlVXJsOiBzdHJpbmcpOiBQcm9taXNlPERvd25sb2FkUmVzdWx0PiB7XG4gICAgLy8gVmFsaWRhdGUgVVJMIGZvcm1hdFxuICAgIGlmICghSW1hZ2VEb3dubG9hZGVyLmlzSW1hZ2VVcmwoaW1hZ2VVcmwpKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoYEludmFsaWQgaW1hZ2UgVVJMIGZvcm1hdDogJHtpbWFnZVVybH1gLCB7XG4gICAgICAgIHVybDogaW1hZ2VVcmwsXG4gICAgICAgIHN1Z2dlc3Rpb246ICdVUkwgbXVzdCBzdGFydCB3aXRoIGh0dHA6Ly8gb3IgaHR0cHM6Ly8nLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gR2VuZXJhdGUgZmlsZW5hbWUgYW5kIHBhdGhcbiAgICBjb25zdCBmaWxlTmFtZSA9IHRoaXMuZ2VuZXJhdGVGaWxlTmFtZShpbWFnZVVybCk7XG4gICAgY29uc3QgbG9jYWxQYXRoID0gam9pbih0aGlzLnNhdmVEaXIsIGZpbGVOYW1lKTtcblxuICAgIC8vIENoZWNrIGlmIGZpbGUgYWxyZWFkeSBleGlzdHMgKGNhY2hlKVxuICAgIGlmIChleGlzdHNTeW5jKGxvY2FsUGF0aCkpIHtcbiAgICAgIGNvbnN0IHN0YXRzID0gc3RhdFN5bmMobG9jYWxQYXRoKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgVXNpbmcgY2FjaGVkIGltYWdlOiAke2xvY2FsUGF0aH1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9yaWdpbmFsVXJsOiBpbWFnZVVybCxcbiAgICAgICAgbG9jYWxQYXRoLFxuICAgICAgICBjYWNoZWQ6IHRydWUsXG4gICAgICAgIGZpbGVTaXplOiBzdGF0cy5zaXplLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBsb2dnZXIuZGVidWcoYERvd25sb2FkaW5nIGltYWdlIGZyb206ICR7aW1hZ2VVcmx9YCk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gRG93bmxvYWQgaW1hZ2Ugd2l0aCB0aW1lb3V0XG4gICAgICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICAgICAgY29uc3QgdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiBjb250cm9sbGVyLmFib3J0KCksIHRoaXMudGltZW91dCk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goaW1hZ2VVcmwsIHtcbiAgICAgICAgc2lnbmFsOiBjb250cm9sbGVyLnNpZ25hbCxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICdVc2VyLUFnZW50JzogJ01vemlsbGEvNS4wIChNYWNpbnRvc2g7IEludGVsIE1hYyBPUyBYIDEwXzE1XzcpIEFwcGxlV2ViS2l0LzUzNy4zNicsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG5cbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKFxuICAgICAgICAgIGBGYWlsZWQgdG8gZG93bmxvYWQgaW1hZ2U6IEhUVFAgJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1gLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVybDogaW1hZ2VVcmwsXG4gICAgICAgICAgICBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgICAgICBzdGF0dXNUZXh0OiByZXNwb25zZS5zdGF0dXNUZXh0LFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgQ29udGVudC1MZW5ndGggaWYgYXZhaWxhYmxlXG4gICAgICBjb25zdCBjb250ZW50TGVuZ3RoID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtbGVuZ3RoJyk7XG4gICAgICBpZiAoY29udGVudExlbmd0aCAmJiBwYXJzZUludChjb250ZW50TGVuZ3RoKSA+IHRoaXMubWF4RmlsZVNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKFxuICAgICAgICAgIGBJbWFnZSBmaWxlIHRvbyBsYXJnZTogJHsocGFyc2VJbnQoY29udGVudExlbmd0aCkgLyAxMDI0IC8gMTAyNCkudG9GaXhlZChcbiAgICAgICAgICAgIDJcbiAgICAgICAgICApfU1CIChtYXg6ICR7KHRoaXMubWF4RmlsZVNpemUgLyAxMDI0IC8gMTAyNCkudG9GaXhlZCgyKX1NQilgLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVybDogaW1hZ2VVcmwsXG4gICAgICAgICAgICBmaWxlU2l6ZTogcGFyc2VJbnQoY29udGVudExlbmd0aCksXG4gICAgICAgICAgICBtYXhTaXplOiB0aGlzLm1heEZpbGVTaXplLFxuICAgICAgICAgICAgc3VnZ2VzdGlvbjogJ1RyeSB1c2luZyBhIHNtYWxsZXIgaW1hZ2Ugb3IgaW5jcmVhc2UgbWF4RmlsZVNpemUnLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gR2V0IGltYWdlIGRhdGFcbiAgICAgIGNvbnN0IGFycmF5QnVmZmVyID0gYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyKTtcblxuICAgICAgLy8gVmVyaWZ5IGFjdHVhbCBzaXplXG4gICAgICBpZiAoYnVmZmVyLmxlbmd0aCA+IHRoaXMubWF4RmlsZVNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKFxuICAgICAgICAgIGBEb3dubG9hZGVkIGZpbGUgdG9vIGxhcmdlOiAkeyhidWZmZXIubGVuZ3RoIC8gMTAyNCAvIDEwMjQpLnRvRml4ZWQoMil9TUIgKG1heDogJHsoXG4gICAgICAgICAgICB0aGlzLm1heEZpbGVTaXplIC9cbiAgICAgICAgICAgIDEwMjQgL1xuICAgICAgICAgICAgMTAyNFxuICAgICAgICAgICkudG9GaXhlZCgyKX1NQilgLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVybDogaW1hZ2VVcmwsXG4gICAgICAgICAgICBmaWxlU2l6ZTogYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgICAgIG1heFNpemU6IHRoaXMubWF4RmlsZVNpemUsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBWYWxpZGF0ZSBpdCdzIGFjdHVhbGx5IGFuIGltYWdlXG4gICAgICBjb25zdCB2YWxpZGF0aW9uID0gdGhpcy52YWxpZGF0ZUltYWdlRGF0YShidWZmZXIpO1xuICAgICAgaWYgKCF2YWxpZGF0aW9uLmlzVmFsaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKGBEb3dubG9hZGVkIGZpbGUgaXMgbm90IGEgdmFsaWQgaW1hZ2U6ICR7aW1hZ2VVcmx9YCwge1xuICAgICAgICAgIHVybDogaW1hZ2VVcmwsXG4gICAgICAgICAgc3VnZ2VzdGlvbjogJ01ha2Ugc3VyZSB0aGUgVVJMIHBvaW50cyB0byBhbiBhY3R1YWwgaW1hZ2UgZmlsZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBTYXZlIHRvIGZpbGVcbiAgICAgIHdyaXRlRmlsZVN5bmMobG9jYWxQYXRoLCBidWZmZXIpO1xuXG4gICAgICBsb2dnZXIuZGVidWcoYEltYWdlIGRvd25sb2FkZWQgc3VjY2Vzc2Z1bGx5OiAke2xvY2FsUGF0aH0gKCR7YnVmZmVyLmxlbmd0aH0gYnl0ZXMpYCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9yaWdpbmFsVXJsOiBpbWFnZVVybCxcbiAgICAgICAgbG9jYWxQYXRoLFxuICAgICAgICBjYWNoZWQ6IGZhbHNlLFxuICAgICAgICBmaWxlU2l6ZTogYnVmZmVyLmxlbmd0aCxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEludmFsaWRJbWFnZUVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuXG4gICAgICAvLyBIYW5kbGUgYWJvcnQgZXJyb3JcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdBYm9ydEVycm9yJykge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgICAgYEltYWdlIGRvd25sb2FkIHRpbWVvdXQgYWZ0ZXIgJHt0aGlzLnRpbWVvdXR9bXM6ICR7aW1hZ2VVcmx9YCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1cmw6IGltYWdlVXJsLFxuICAgICAgICAgICAgdGltZW91dDogdGhpcy50aW1lb3V0LFxuICAgICAgICAgICAgc3VnZ2VzdGlvbjogJ1RoZSBpbWFnZSBtYXkgYmUgdG9vIGxhcmdlIG9yIHRoZSBuZXR3b3JrIGlzIHNsb3cnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGRvd25sb2FkIGltYWdlOiAke2ltYWdlVXJsfWAsXG4gICAgICAgIHtcbiAgICAgICAgICB1cmw6IGltYWdlVXJsLFxuICAgICAgICB9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRG93bmxvYWQgbXVsdGlwbGUgaW1hZ2VzIGZyb20gVVJMcyAocGFyYWxsZWwgZG93bmxvYWQgZm9yIGJldHRlciBwZXJmb3JtYW5jZSlcbiAgICovXG4gIGFzeW5jIGRvd25sb2FkSW1hZ2VzKGltYWdlVXJsczogc3RyaW5nW10pOiBQcm9taXNlPERvd25sb2FkUmVzdWx0W10+IHtcbiAgICAvLyBEb3dubG9hZCBhbGwgaW1hZ2VzIGluIHBhcmFsbGVsXG4gICAgY29uc3QgZG93bmxvYWRQcm9taXNlcyA9IGltYWdlVXJscy5tYXAoKHVybCkgPT5cbiAgICAgIHRoaXMuZG93bmxvYWRJbWFnZSh1cmwpLmNhdGNoKChlcnJvcikgPT4gKHsgZXJyb3IsIHVybCB9KSlcbiAgICApO1xuXG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKGRvd25sb2FkUHJvbWlzZXMpO1xuXG4gICAgY29uc3Qgc3VjY2Vzc1Jlc3VsdHM6IERvd25sb2FkUmVzdWx0W10gPSBbXTtcbiAgICBjb25zdCBlcnJvcnM6IEFycmF5PHsgdXJsOiBzdHJpbmc7IGVycm9yOiBFcnJvciB9PiA9IFtdO1xuXG4gICAgcmVzdWx0cy5mb3JFYWNoKChyZXN1bHQpID0+IHtcbiAgICAgIGlmICgnZXJyb3InIGluIHJlc3VsdCkge1xuICAgICAgICBlcnJvcnMucHVzaCh7IHVybDogcmVzdWx0LnVybCwgZXJyb3I6IHJlc3VsdC5lcnJvciBhcyBFcnJvciB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN1Y2Nlc3NSZXN1bHRzLnB1c2gocmVzdWx0KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIElmIGFueSBkb3dubG9hZHMgZmFpbGVkLCB0aHJvdyBhbiBlcnJvciB3aXRoIGRldGFpbHNcbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZXMgPSBlcnJvcnMubWFwKChlKSA9PiBgJHtlLnVybH06ICR7ZS5lcnJvci5tZXNzYWdlfWApLmpvaW4oJ1xcbicpO1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGRvd25sb2FkICR7ZXJyb3JzLmxlbmd0aH0gb2YgJHtpbWFnZVVybHMubGVuZ3RofSBpbWFnZXM6XFxuJHtlcnJvck1lc3NhZ2VzfWAsXG4gICAgICAgIHtcbiAgICAgICAgICB0b3RhbENvdW50OiBpbWFnZVVybHMubGVuZ3RoLFxuICAgICAgICAgIGZhaWxlZENvdW50OiBlcnJvcnMubGVuZ3RoLFxuICAgICAgICAgIHN1Y2Nlc3NDb3VudDogc3VjY2Vzc1Jlc3VsdHMubGVuZ3RoLFxuICAgICAgICAgIGZhaWxlZFVybHM6IGVycm9ycy5tYXAoKGUpID0+IGUudXJsKSxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3VjY2Vzc1Jlc3VsdHM7XG4gIH1cblxuICAvKipcbiAgICogUHJvY2VzcyBhIGxpc3Qgb2YgaW1hZ2UgcGF0aHMgLSBkb3dubG9hZCBVUkxzIGFuZCBrZWVwIGxvY2FsIHBhdGhzIGFzLWlzXG4gICAqL1xuICBhc3luYyBwcm9jZXNzSW1hZ2VQYXRocyhpbWFnZVBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBjb25zdCBsb2NhbFBhdGhzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHVybHNUb0Rvd25sb2FkOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gU2VwYXJhdGUgVVJMcyBmcm9tIGxvY2FsIHBhdGhzXG4gICAgZm9yIChjb25zdCBwYXRoIG9mIGltYWdlUGF0aHMpIHtcbiAgICAgIGlmIChJbWFnZURvd25sb2FkZXIuaXNJbWFnZVVybChwYXRoKSkge1xuICAgICAgICB1cmxzVG9Eb3dubG9hZC5wdXNoKHBhdGgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVmFsaWRhdGUgbG9jYWwgcGF0aCBleGlzdHNcbiAgICAgICAgaWYgKCFleGlzdHNTeW5jKHBhdGgpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKGBMb2NhbCBpbWFnZSBmaWxlIG5vdCBmb3VuZDogJHtwYXRofWAsIHtcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBzdWdnZXN0aW9uOiAnTWFrZSBzdXJlIHRoZSBmaWxlIHBhdGggaXMgY29ycmVjdCBhbmQgdGhlIGZpbGUgZXhpc3RzJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBsb2NhbFBhdGhzLnB1c2gocGF0aCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRG93bmxvYWQgVVJMcyBpZiBhbnlcbiAgICBpZiAodXJsc1RvRG93bmxvYWQubGVuZ3RoID4gMCkge1xuICAgICAgbG9nZ2VyLmRlYnVnKGBEb3dubG9hZGluZyAke3VybHNUb0Rvd25sb2FkLmxlbmd0aH0gaW1hZ2VzIGZyb20gVVJMcy4uLmApO1xuICAgICAgY29uc3QgZG93bmxvYWRSZXN1bHRzID0gYXdhaXQgdGhpcy5kb3dubG9hZEltYWdlcyh1cmxzVG9Eb3dubG9hZCk7XG4gICAgICBjb25zdCBkb3dubG9hZGVkUGF0aHMgPSBkb3dubG9hZFJlc3VsdHMubWFwKChyKSA9PiByLmxvY2FsUGF0aCk7XG4gICAgICBsb2NhbFBhdGhzLnB1c2goLi4uZG93bmxvYWRlZFBhdGhzKTtcblxuICAgICAgLy8gTG9nIGRvd25sb2FkIHN1bW1hcnlcbiAgICAgIGNvbnN0IGNhY2hlZENvdW50ID0gZG93bmxvYWRSZXN1bHRzLmZpbHRlcigocikgPT4gci5jYWNoZWQpLmxlbmd0aDtcbiAgICAgIGNvbnN0IG5ld0NvdW50ID0gZG93bmxvYWRSZXN1bHRzLmZpbHRlcigocikgPT4gIXIuY2FjaGVkKS5sZW5ndGg7XG4gICAgICBsb2dnZXIuZGVidWcoYERvd25sb2FkZWQgJHtuZXdDb3VudH0gbmV3IGltYWdlcywgdXNlZCAke2NhY2hlZENvdW50fSBjYWNoZWQgaW1hZ2VzYCk7XG4gICAgfVxuXG4gICAgaWYgKGxvY2FsUGF0aHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoJ05vIHZhbGlkIGltYWdlcyBmb3VuZCcsIHtcbiAgICAgICAgcHJvdmlkZWRQYXRoczogaW1hZ2VQYXRocy5sZW5ndGgsXG4gICAgICAgIHN1Z2dlc3Rpb246ICdQcm92aWRlIGF0IGxlYXN0IG9uZSB2YWxpZCBpbWFnZSBVUkwgb3IgbG9jYWwgZmlsZSBwYXRoJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBsb2NhbFBhdGhzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgc2F2ZSBkaXJlY3RvcnkgcGF0aFxuICAgKi9cbiAgZ2V0U2F2ZURpcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnNhdmVEaXI7XG4gIH1cbn1cblxuLy8gRXhwb3J0IGEgZGVmYXVsdCBpbnN0YW5jZVxubGV0IGRlZmF1bHREb3dubG9hZGVyOiBJbWFnZURvd25sb2FkZXIgfCBudWxsID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEltYWdlRG93bmxvYWRlcihzYXZlRGlyPzogc3RyaW5nKTogSW1hZ2VEb3dubG9hZGVyIHtcbiAgaWYgKCFkZWZhdWx0RG93bmxvYWRlciB8fCAoc2F2ZURpciAmJiBkZWZhdWx0RG93bmxvYWRlci5nZXRTYXZlRGlyKCkgIT09IHNhdmVEaXIpKSB7XG4gICAgZGVmYXVsdERvd25sb2FkZXIgPSBuZXcgSW1hZ2VEb3dubG9hZGVyKHNhdmVEaXIpO1xuICB9XG4gIHJldHVybiBkZWZhdWx0RG93bmxvYWRlcjtcbn1cbiIsIi8qKlxuICogUHVibGlzaGluZyBzZXJ2aWNlIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbmltcG9ydCB7IFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgQ29uZmlnLCBQdWJsaXNoUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IFB1Ymxpc2hFcnJvciwgSW52YWxpZEltYWdlRXJyb3IgfSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCBzdGF0U3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgSW1hZ2VEb3dubG9hZGVyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2ltYWdlLWRvd25sb2FkZXInO1xuaW1wb3J0IHsgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkLCBnZXRUaXRsZVdpZHRoIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3RpdGxlLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBDT01NT05fU1RBVFVTX1NFTEVDVE9SUywgQ09NTU9OX1RFWFRfUEFUVEVSTlMsIENPTU1PTl9GSUxFX1NFTEVDVE9SUyB9IGZyb20gJy4uLy4uL3NoYXJlZC9zZWxlY3RvcnMnO1xuXG4vLyBDb25zdGFudHMgZm9yIHZpZGVvIHB1Ymxpc2hpbmdcbmV4cG9ydCBjb25zdCBWSURFT19USU1FT1VUUyA9IHtcbiAgUEFHRV9MT0FEOiAzMDAwLFxuICBUQUJfU1dJVENIOiAyMDAwLFxuICBWSURFT19QUk9DRVNTSU5HOiAxMDAwMCxcbiAgQ09OVEVOVF9XQUlUOiAxMDAwLFxuICBVUExPQURfUkVBRFk6IDEwMDAsXG4gIFVQTE9BRF9TVEFSVDogMzAwMCxcbiAgUFJPQ0VTU0lOR19DSEVDSzogMzAwMCxcbiAgQ09NUExFVElPTl9DSEVDSzogMjAwMCxcbiAgUFJPQ0VTU0lOR19USU1FT1VUOiAxMjAwMDAsIC8vIDIgbWludXRlc1xuICBDT01QTEVUSU9OX1RJTUVPVVQ6IDMwMDAwMCwgLy8gNSBtaW51dGVzXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgU0VMRUNUT1JTID0ge1xuICBGSUxFX0lOUFVUOiBDT01NT05fRklMRV9TRUxFQ1RPUlMuRklMRV9JTlBVVCxcbiAgU1VDQ0VTU19JTkRJQ0FUT1JTOiBDT01NT05fU1RBVFVTX1NFTEVDVE9SUy5TVUNDRVNTLFxuICBFUlJPUl9JTkRJQ0FUT1JTOiBDT01NT05fU1RBVFVTX1NFTEVDVE9SUy5FUlJPUixcbiAgUFJPQ0VTU0lOR19JTkRJQ0FUT1JTOiBDT01NT05fU1RBVFVTX1NFTEVDVE9SUy5QUk9DRVNTSU5HLFxuICBDT01QTEVUSU9OX0lORElDQVRPUlM6IFtcbiAgICAnLnVwbG9hZC1jb21wbGV0ZScsXG4gICAgJy5wcm9jZXNzaW5nLWNvbXBsZXRlJyxcbiAgICAnLnZpZGVvLXJlYWR5JyxcbiAgICAnW2NsYXNzKj1cImNvbXBsZXRlXCJdJyxcbiAgICAnW2NsYXNzKj1cInJlYWR5XCJdJyxcbiAgXSxcbiAgVE9BU1RfU0VMRUNUT1JTOiBDT01NT05fU1RBVFVTX1NFTEVDVE9SUy5UT0FTVCxcbiAgUFVCTElTSF9QQUdFX0lORElDQVRPUlM6IFtcbiAgICAnZGl2LnVwbG9hZC1jb250ZW50JyxcbiAgICAnZGl2LnN1Ym1pdCcsXG4gICAgJy5jcmVhdG9yLWVkaXRvcicsXG4gICAgJy52aWRlby11cGxvYWQtY29udGFpbmVyJyxcbiAgICAnaW5wdXRbdHlwZT1cImZpbGVcIl0nLFxuICBdLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IGNvbnN0IFRFWFRfUEFUVEVSTlMgPSBDT01NT05fVEVYVF9QQVRURVJOUztcblxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUHVibGlzaEJhc2VTZXJ2aWNlIGV4dGVuZHMgQmFzZVNlcnZpY2Uge1xuICBwcm90ZWN0ZWQgaW1hZ2VEb3dubG9hZGVyOiBJbWFnZURvd25sb2FkZXI7XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcpIHtcbiAgICBzdXBlcihjb25maWcpO1xuICAgIHRoaXMuaW1hZ2VEb3dubG9hZGVyID0gbmV3IEltYWdlRG93bmxvYWRlcignLi90ZW1wX2ltYWdlcycpO1xuICB9XG5cbiAgLy8gSGVscGVyIG1ldGhvZHMgZm9yIGVsZW1lbnQgZGV0ZWN0aW9uIGFuZCB0ZXh0IG1hdGNoaW5nXG4gIHByb3RlY3RlZCBhc3luYyBmaW5kRWxlbWVudEJ5U2VsZWN0b3JzKFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgc2VsZWN0b3JzOiByZWFkb25seSBzdHJpbmdbXVxuICApOiBQcm9taXNlPGFueSB8IG51bGw+IHtcbiAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGVsZW1lbnQgd2l0aCBzZWxlY3RvcjogJHtzZWxlY3Rvcn1gKTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldEVsZW1lbnRUZXh0KGVsZW1lbnQ6IEVsZW1lbnQpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IChlbGVtZW50IGFzIGFueSkucGFnZSgpLmV2YWx1YXRlKChlbDogRWxlbWVudCkgPT4gZWwudGV4dENvbnRlbnQsIGVsZW1lbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGdldCBlbGVtZW50IHRleHQ6ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY2hlY2tUZXh0UGF0dGVybnMoXG4gICAgdGV4dDogc3RyaW5nIHwgbnVsbCxcbiAgICBwYXR0ZXJuczogcmVhZG9ubHkgc3RyaW5nW11cbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKCF0ZXh0KSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHBhdHRlcm5zLnNvbWUoKHBhdHRlcm4pID0+IHRleHQuaW5jbHVkZXMocGF0dGVybikpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgc2VsZWN0b3JzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgICBwYXR0ZXJuczogcmVhZG9ubHkgc3RyaW5nW11cbiAgKTogUHJvbWlzZTx7IGZvdW5kOiBib29sZWFuOyB0ZXh0Pzogc3RyaW5nOyBlbGVtZW50PzogYW55IH0+IHtcbiAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgdGhpcy5nZXRFbGVtZW50VGV4dChlbGVtZW50IGFzIHVua25vd24gYXMgRWxlbWVudCk7XG4gICAgICAgIGlmICh0ZXh0ICYmIChhd2FpdCB0aGlzLmNoZWNrVGV4dFBhdHRlcm5zKHRleHQsIHBhdHRlcm5zKSkpIHtcbiAgICAgICAgICByZXR1cm4geyBmb3VuZDogdHJ1ZSwgdGV4dCwgZWxlbWVudCB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGZvdW5kOiBmYWxzZSB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHdhaXRGb3JDb25kaXRpb24oXG4gICAgY29uZGl0aW9uOiAoKSA9PiBQcm9taXNlPGJvb2xlYW4+LFxuICAgIHRpbWVvdXQ6IG51bWJlcixcbiAgICBjaGVja0ludGVydmFsOiBudW1iZXIgPSAxMDAwLFxuICAgIGVycm9yTWVzc2FnZTogc3RyaW5nXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSA8IHRpbWVvdXQpIHtcbiAgICAgIGlmIChhd2FpdCBjb25kaXRpb24oKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhd2FpdCBzbGVlcChjaGVja0ludGVydmFsKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGVycm9yTWVzc2FnZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmlsbFRpdGxlKHBhZ2U6IFBhZ2UsIHRpdGxlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBXYWl0IGZvciBhIGxpa2VseSB0aXRsZSBpbnB1dCB0byBhcHBlYXJcbiAgICB0cnkge1xuICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yU2VsZWN0b3IoXG4gICAgICAgICdpbnB1dC5jLWlucHV0X2lubmVyLCBpbnB1dC5jLWlucHV0LCBpbnB1dFtwbGFjZWhvbGRlcio9XCLmoIfpophcIl0sIC50aXRsZS1pbnB1dCBpbnB1dCwgaW5wdXRbY2xhc3MqPVwidGl0bGVcIl0nLFxuICAgICAgICB7IHRpbWVvdXQ6IDEwMDAwIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIENvbnRpbnVlIHdpdGhvdXQgd2FpdGluZyBpZiBub3QgZm91bmQgcHVyZWx5IGJ5IHNlbGVjdG9yXG4gICAgfVxuXG4gICAgY29uc3QgdGl0bGVTZWxlY3RvcnMgPSBbXG4gICAgICAnaW5wdXQuYy1pbnB1dF9pbm5lcicsIC8vIHNwZWNpZmljIGZvciByZWNlbnQgWGlhb2hvbmdzaHUgY3JlYXRvciBVSVxuICAgICAgJ2lucHV0LmMtaW5wdXQnLFxuICAgICAgJ2lucHV0W3BsYWNlaG9sZGVyKj1cIuagh+mimFwiXScsXG4gICAgICAnaW5wdXRbcGxhY2Vob2xkZXIqPVwi5aGr5YaZ5qCH6aKY5Lya5pyJ5pu05aSa6LWe5ZOmXCJdJyxcbiAgICAgICdpbnB1dFtwbGFjZWhvbGRlcio9XCJ0aXRsZVwiXScsXG4gICAgICAnaW5wdXRbZGF0YS1wbGFjZWhvbGRlcio9XCLmoIfpophcIl0nLFxuICAgICAgJy50aXRsZS1pbnB1dCBpbnB1dCcsXG4gICAgICAnaW5wdXRbcGxhY2Vob2xkZXIqPVwi6K+36L6T5YWl5qCH6aKYXCJdJyxcbiAgICAgICdpbnB1dFtuYW1lPVwidGl0bGVcIl0nLFxuICAgICAgJ2lucHV0W2lkKj1cInRpdGxlXCJdJyxcbiAgICAgICdpbnB1dFtjbGFzcyo9XCJ0aXRsZVwiXScsXG4gICAgICAnaW5wdXRbdHlwZT1cInRleHRcIl0nLCAvLyBGYWxsYmFja3NcbiAgICAgICdkaXZbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXScsXG4gICAgICAndGV4dGFyZWFbcGxhY2Vob2xkZXIqPVwi5qCH6aKYXCJdJyxcbiAgICAgICd0ZXh0YXJlYVtwbGFjZWhvbGRlcio9XCJ0aXRsZVwiXScsXG4gICAgXTtcblxuICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgdGl0bGVTZWxlY3RvcnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHRpdGxlSW5wdXQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAodGl0bGVJbnB1dCkge1xuICAgICAgICAgIC8vIFNjcm9sbCBpbnRvIHZpZXcganVzdCBpbiBjYXNlIGl0J3Mgb2ZmIHNjcmVlblxuICAgICAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgICBpZiAoZWwgJiYgdHlwZW9mIGVsLnNjcm9sbEludG9WaWV3ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIGVsLnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnLCBibG9jazogJ2NlbnRlcicgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgdGl0bGVJbnB1dCk7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcblxuICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IHRpdGxlSW5wdXQuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuXG4gICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgYXdhaXQgdGl0bGVJbnB1dC5jbGljaygpO1xuICAgICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTsgLy8gV2FpdCBmb3IgZm9jdXNcblxuICAgICAgICAgICAgLy8gY2xlYXIgZXhpc3RpbmcgaW5wdXQgaWYgYW55XG4gICAgICAgICAgICBhd2FpdCB0aXRsZUlucHV0LmNsaWNrKHsgY2xpY2tDb3VudDogMyB9KTtcbiAgICAgICAgICAgIGF3YWl0IHRpdGxlSW5wdXQucHJlc3MoJ0JhY2tzcGFjZScpO1xuXG4gICAgICAgICAgICBhd2FpdCB0aXRsZUlucHV0LnR5cGUodGl0bGUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBzZWxlY3RvclxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG5vIHNwZWNpZmljIGlucHV0IGZvdW5kLCB0cnkgdG8gZmluZCBhbnkgdmlzaWJsZSBpbnB1dCBvciB0ZXh0YXJlYSBvbiB0aGUgcGFnZVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBhbGxJbnB1dHMgPSBhd2FpdCBwYWdlLiQkKCdpbnB1dCwgdGV4dGFyZWEnKTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbGxJbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBhbGxJbnB1dHNbaV07XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC5nZXRBdHRyaWJ1dGUoJ3R5cGUnKSwgaW5wdXQpO1xuXG4gICAgICAgICAgLy8gYXZvaWQgZmlsZSBpbnB1dHMgb3IgaGlkZGVuIGlucHV0c1xuICAgICAgICAgIGlmICh0eXBlICE9PSAnZmlsZScgJiYgdHlwZSAhPT0gJ2hpZGRlbicpIHtcbiAgICAgICAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChlbCAmJiB0eXBlb2YgZWwuc2Nyb2xsSW50b1ZpZXcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBlbC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdjZW50ZXInIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCBpbnB1dCk7XG4gICAgICAgICAgICBhd2FpdCBzbGVlcCg1MDApO1xuXG4gICAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCBpbnB1dC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG5cbiAgICAgICAgICAgIGlmIChpc1Zpc2libGUpIHtcbiAgICAgICAgICAgICAgYXdhaXQgaW5wdXQuY2xpY2soKTtcbiAgICAgICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcblxuICAgICAgICAgICAgICAvLyBjbGVhciBleGlzdGluZyBpbnB1dCBpZiBhbnlcbiAgICAgICAgICAgICAgYXdhaXQgaW5wdXQuY2xpY2soeyBjbGlja0NvdW50OiAzIH0pO1xuICAgICAgICAgICAgICBhd2FpdCBpbnB1dC5wcmVzcygnQmFja3NwYWNlJyk7XG5cbiAgICAgICAgICAgICAgYXdhaXQgaW5wdXQudHlwZSh0aXRsZSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBpbnB1dFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIEZhbGwgdGhyb3VnaCB0byBlcnJvclxuICAgIH1cblxuICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHRpdGxlIGlucHV0IGZpZWxkJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmluZENvbnRlbnRFbGVtZW50KHBhZ2U6IFBhZ2UpOiBQcm9taXNlPGFueSB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gU3RyYXRlZ3kgMTogVHJ5IGRpdltjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdIChzaW1wbGUgYW5kIGRpcmVjdClcbiAgICAgIGNvbnN0IGNvbnRlbnRFZGl0YWJsZSA9IGF3YWl0IHBhZ2UuJCgnZGl2W2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0nKTtcbiAgICAgIGlmIChjb250ZW50RWRpdGFibGUpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgY29udGVudEVkaXRhYmxlLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiBjb250ZW50RWRpdGFibGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgMjogVHJ5IGRpdi50aXB0YXAuUHJvc2VNaXJyb3IgKHByaW1hcnkgc2VsZWN0b3IgZm9yIGNyZWF0b3IgcGxhdGZvcm0pXG4gICAgICBjb25zdCB0aXB0YXBFZGl0b3IgPSBhd2FpdCBwYWdlLiQoJ2Rpdi50aXB0YXAuUHJvc2VNaXJyb3InKTtcbiAgICAgIGlmICh0aXB0YXBFZGl0b3IpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGlwdGFwRWRpdG9yLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiB0aXB0YXBFZGl0b3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgMzogVHJ5IGRpdltyb2xlPVwidGV4dGJveFwiXVtjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdIChzcGVjaWZpYyBzZWxlY3RvcilcbiAgICAgIGNvbnN0IHJvbGVUZXh0Ym94ID0gYXdhaXQgcGFnZS4kKCdkaXZbcm9sZT1cInRleHRib3hcIl1bY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXScpO1xuICAgICAgaWYgKHJvbGVUZXh0Ym94KSB7XG4gICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IHJvbGVUZXh0Ym94LmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiByb2xlVGV4dGJveDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSA0OiBUcnkgZGl2LnFsLWVkaXRvciAobGVnYWN5IHNlbGVjdG9yKVxuICAgICAgY29uc3QgcWxFZGl0b3IgPSBhd2FpdCBwYWdlLiQoJ2Rpdi5xbC1lZGl0b3InKTtcbiAgICAgIGlmIChxbEVkaXRvcikge1xuICAgICAgICByZXR1cm4gcWxFZGl0b3I7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDU6IFRyeSB0byBmaW5kIHRleHRhcmVhIG9yIGNvbnRlbnRlZGl0YWJsZVxuICAgICAgY29uc3QgY29udGVudFNlbGVjdG9ycyA9IFtcbiAgICAgICAgJy50aXB0YXAuUHJvc2VNaXJyb3InLFxuICAgICAgICAndGV4dGFyZWFbcGxhY2Vob2xkZXIqPVwi5q2j5paHXCJdJyxcbiAgICAgICAgJ3RleHRhcmVhW211bHRpbGluZV0nLFxuICAgICAgICAnZGl2W2RhdGEtcGxhY2Vob2xkZXIqPVwi5q2j5paHXCJdJyxcbiAgICAgICAgJy5jb250ZW50LWVkaXRvcicsXG4gICAgICAgICdkaXZbcm9sZT1cInRleHRib3hcIl0nLFxuICAgICAgICAndGV4dGJveFtyb2xlPVwidGV4dGJveFwiXScsXG4gICAgICAgICd0ZXh0Ym94W211bHRpbGluZV0nLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBjb250ZW50U2VsZWN0b3JzKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDY6IFRyeSB0byBmaW5kIGFueSBtdWx0aWxpbmUgdGV4dGJveCAoZmFsbGJhY2spXG4gICAgICBjb25zdCBtdWx0aWxpbmVUZXh0Ym94ZXMgPSBhd2FpdCBwYWdlLiQkKCd0ZXh0Ym94W211bHRpbGluZV0nKTtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBtdWx0aWxpbmVUZXh0Ym94ZXMpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgZWxlbWVudC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG4gICAgICAgIGlmIChpc1Zpc2libGUpIHtcbiAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGZpbmRUZXh0Ym94QnlQbGFjZWhvbGRlcihwYWdlOiBQYWdlKTogUHJvbWlzZTxhbnkgfCBudWxsPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEZpbmQgYWxsIHAgZWxlbWVudHNcbiAgICAgIGNvbnN0IHBFbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoJ3AnKTtcblxuICAgICAgLy8gTG9vayBmb3IgZWxlbWVudCB3aXRoIGRhdGEtcGxhY2Vob2xkZXIgY29udGFpbmluZyBcIui+k+WFpeato+aWh+aPj+i/sFwiXG4gICAgICBmb3IgKGNvbnN0IHAgb2YgcEVsZW1lbnRzKSB7XG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS1wbGFjZWhvbGRlcicpLCBwKTtcbiAgICAgICAgaWYgKHBsYWNlaG9sZGVyPy5pbmNsdWRlcygn6L6T5YWl5q2j5paH5o+P6L+wJykpIHtcbiAgICAgICAgICByZXR1cm4gcDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGZpbmRUZXh0Ym94UGFyZW50KHBhZ2U6IFBhZ2UsIGVsZW1lbnQ6IEVsZW1lbnQpOiBQcm9taXNlPGFueT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgcGFnZS5ldmFsdWF0ZUhhbmRsZSgoZWwpID0+IGVsLnBhcmVudEVsZW1lbnQsIGVsZW1lbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmlsbENvbnRlbnQocGFnZTogUGFnZSwgY29udGVudDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gV2FpdCBmb3IgY29udGVudCBhcmVhIHRvIGFwcGVhclxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBwYWdlLndhaXRGb3JTZWxlY3RvcihcbiAgICAgICAgJ2Rpdltyb2xlPVwidGV4dGJveFwiXVtjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdLCAudGlwdGFwLlByb3NlTWlycm9yLCBkaXZbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSwgdGV4dGFyZWEsIFtyb2xlPVwidGV4dGJveFwiXSwgLnFsLWVkaXRvciwgdGV4dGJveFttdWx0aWxpbmVdJyxcbiAgICAgICAgeyB0aW1lb3V0OiAxMDAwMCB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBDb250aW51ZSB3aXRob3V0IHdhaXRpbmdcbiAgICB9XG5cbiAgICBsZXQgY29udGVudEVsZW1lbnQgPSBhd2FpdCB0aGlzLmZpbmRDb250ZW50RWxlbWVudChwYWdlKTtcblxuICAgIGlmICghY29udGVudEVsZW1lbnQpIHtcbiAgICAgIC8vIFRyeSBhbHRlcm5hdGl2ZSBhcHByb2FjaFxuICAgICAgY29uc3QgdGV4dGJveEVsZW1lbnQgPSBhd2FpdCB0aGlzLmZpbmRUZXh0Ym94QnlQbGFjZWhvbGRlcihwYWdlKTtcbiAgICAgIGlmICh0ZXh0Ym94RWxlbWVudCkge1xuICAgICAgICBjb250ZW50RWxlbWVudCA9IGF3YWl0IHRoaXMuZmluZFRleHRib3hQYXJlbnQocGFnZSwgdGV4dGJveEVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghY29udGVudEVsZW1lbnQpIHtcbiAgICAgIC8vIFRyeSB0byBmaW5kIGFueSBjb250ZW50ZWRpdGFibGUgb3IgdGV4dGFyZWEgZWxlbWVudFxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYWxsQ29udGVudEVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJChcbiAgICAgICAgICAnZGl2W3JvbGU9XCJ0ZXh0Ym94XCJdW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIC50aXB0YXAuUHJvc2VNaXJyb3IsIGRpdltjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdLCB0ZXh0YXJlYSwgW3JvbGU9XCJ0ZXh0Ym94XCJdLCAucWwtZWRpdG9yLCBwW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIHRleHRib3hbbXVsdGlsaW5lXSdcbiAgICAgICAgKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFsbENvbnRlbnRFbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhbGxDb250ZW50RWxlbWVudHNbaV07XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IGVsZW1lbnQuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuICAgICAgICAgICAgY29uc3QgdGFnTmFtZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC50YWdOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRFZGl0YWJsZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoXG4gICAgICAgICAgICAgIChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnKSxcbiAgICAgICAgICAgICAgZWxlbWVudFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHJvbGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdyb2xlJyksIGVsZW1lbnQpO1xuICAgICAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLmNsYXNzTmFtZSwgZWxlbWVudCk7XG4gICAgICAgICAgICBjb25zdCBtdWx0aWxpbmUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdtdWx0aWxpbmUnKSwgZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgaXNWaXNpYmxlICYmXG4gICAgICAgICAgICAgIChjb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyB8fFxuICAgICAgICAgICAgICAgIHRhZ05hbWUgPT09ICdURVhUQVJFQScgfHxcbiAgICAgICAgICAgICAgICByb2xlID09PSAndGV4dGJveCcgfHxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUuaW5jbHVkZXMoJ3FsLWVkaXRvcicpIHx8XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lLmluY2x1ZGVzKCd0aXB0YXAnKSB8fFxuICAgICAgICAgICAgICAgIG11bHRpbGluZSA9PT0gJycpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgY29udGVudEVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBlbGVtZW50XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBDb250aW51ZSB0byBuZXh0IHN0cmF0ZWd5XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjb250ZW50RWxlbWVudCkge1xuICAgICAgLy8gTGFzdCByZXNvcnQ6IHRyeSB0byBmaW5kIGFueSBlbGVtZW50IHRoYXQgbWlnaHQgYmUgZm9yIGNvbnRlbnRcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGFsbEVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJCgnKicpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTWF0aC5taW4oYWxsRWxlbWVudHMubGVuZ3RoLCA1MCk7IGkrKykge1xuICAgICAgICAgIC8vIExpbWl0IHRvIGZpcnN0IDUwIGVsZW1lbnRzXG4gICAgICAgICAgY29uc3QgZWxlbWVudCA9IGFsbEVsZW1lbnRzW2ldO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCBlbGVtZW50LmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgICAgIGNvbnN0IHRhZ05hbWUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwudGFnTmFtZSwgZWxlbWVudCk7XG4gICAgICAgICAgICBjb25zdCBjb250ZW50RWRpdGFibGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKFxuICAgICAgICAgICAgICAoZWwpID0+IGVsLmdldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJyksXG4gICAgICAgICAgICAgIGVsZW1lbnRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBjbGFzc05hbWUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuY2xhc3NOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gYXdhaXQgcGFnZS5ldmFsdWF0ZShcbiAgICAgICAgICAgICAgKGVsKSA9PiBlbC5nZXRBdHRyaWJ1dGUoJ3BsYWNlaG9sZGVyJyksXG4gICAgICAgICAgICAgIGVsZW1lbnRcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgaXNWaXNpYmxlICYmXG4gICAgICAgICAgICAgIChjb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyB8fFxuICAgICAgICAgICAgICAgIHRhZ05hbWUgPT09ICdURVhUQVJFQScgfHxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUuaW5jbHVkZXMoJ2NvbnRlbnQnKSB8fFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZS5pbmNsdWRlcygnZWRpdG9yJykgfHxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj8uaW5jbHVkZXMoJ+WGheWuuScpIHx8XG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI/LmluY2x1ZGVzKCfmraPmlocnKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBjb250ZW50RWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzIGZvciBpbmRpdmlkdWFsIGVsZW1lbnRzXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBGYWxsIHRocm91Z2ggdG8gZXJyb3JcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWNvbnRlbnRFbGVtZW50KSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdDb3VsZCBub3QgZmluZCBjb250ZW50IGlucHV0IGZpZWxkJyk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNvbnRlbnRFbGVtZW50LmNsaWNrKCk7XG4gICAgICBhd2FpdCBzbGVlcCg1MDApOyAvLyBXYWl0IGZvciBmb2N1c1xuICAgICAgYXdhaXQgKGNvbnRlbnRFbGVtZW50IGFzIGFueSkudHlwZShjb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgRmFpbGVkIHRvIGZpbGwgY29udGVudDogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaW5wdXRUYWdzKHBhZ2U6IFBhZ2UsIGNvbnRlbnRFbGVtZW50OiBhbnksIHRhZ3M6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRhZ0xpc3QgPSB0YWdzXG4gICAgICAuc3BsaXQoJywnKVxuICAgICAgLm1hcCgodGFnKSA9PiB0YWcudHJpbSgpKVxuICAgICAgLmZpbHRlcigodGFnKSA9PiB0YWcubGVuZ3RoID4gMCk7XG5cbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdMaXN0KSB7XG4gICAgICBhd2FpdCB0aGlzLmlucHV0VGFnKHBhZ2UsIGNvbnRlbnRFbGVtZW50LCB0YWcpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBpbnB1dFRhZyhwYWdlOiBQYWdlLCBjb250ZW50RWxlbWVudDogYW55LCB0YWc6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBUeXBlIHRoZSB0YWdcbiAgICAgIGF3YWl0IGNvbnRlbnRFbGVtZW50LnR5cGUoYCMke3RhZ31gKTtcbiAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAvLyBUcnkgdG8gZmluZCB0b3BpYyBzdWdnZXN0aW9uIGNvbnRhaW5lclxuICAgICAgY29uc3QgdG9waWNDb250YWluZXIgPSBhd2FpdCBwYWdlLiQoJyNjcmVhdG9yLWVkaXRvci10b3BpYy1jb250YWluZXInKTtcblxuICAgICAgaWYgKHRvcGljQ29udGFpbmVyKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0SXRlbSA9IGF3YWl0IHRvcGljQ29udGFpbmVyLiQoJy5pdGVtJyk7XG4gICAgICAgIGlmIChmaXJzdEl0ZW0pIHtcbiAgICAgICAgICBhd2FpdCBmaXJzdEl0ZW0uY2xpY2soKTtcbiAgICAgICAgICBhd2FpdCBzbGVlcCg1MDApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBQcmVzcyBFbnRlciB0byBjb25maXJtIHRoZSB0YWdcbiAgICAgICAgYXdhaXQgY29udGVudEVsZW1lbnQucHJlc3MoJ0VudGVyJyk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDUwMCk7XG4gICAgICAgIC8vIFByZXNzIFNwYWNlIHRvIHNlcGFyYXRlIHRhZ3NcbiAgICAgICAgYXdhaXQgY29udGVudEVsZW1lbnQucHJlc3MoJ1NwYWNlJyk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDIwMCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gYWRkIHRhZyAke3RhZ306ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGFkZFRhZ3MocGFnZTogUGFnZSwgdGFnczogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbnRlbnRFbGVtZW50ID0gYXdhaXQgdGhpcy5maW5kQ29udGVudEVsZW1lbnQocGFnZSk7XG4gICAgICBpZiAoY29udGVudEVsZW1lbnQpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbnB1dFRhZ3MocGFnZSwgY29udGVudEVsZW1lbnQsIHRhZ3MpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGFkZCB0YWdzOiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzdWJtaXRQb3N0KHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgLy8gRmluZCB0aGUgc3VibWl0IGJ1dHRvbiBieSB0ZXh0IFwi5Y+R5biDXCJcbiAgICAgIGNvbnN0IGJ1dHRvbnMgPSBhd2FpdCBwYWdlLiQkKCdidXR0b24nKTtcbiAgICAgIGxldCBzdWJtaXRCdXR0b24gPSBudWxsO1xuICAgICAgZm9yIChjb25zdCBidG4gb2YgYnV0dG9ucykge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgYnRuLmV2YWx1YXRlKGVsID0+IGVsLnRleHRDb250ZW50Py50cmltKCkpO1xuICAgICAgICBpZiAodGV4dCA9PT0gJ+WPkeW4gycpIHtcbiAgICAgICAgICBzdWJtaXRCdXR0b24gPSBidG47XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFzdWJtaXRCdXR0b24pIHtcbiAgICAgICAgLy8gVHJ5IHNwYW4gb3IgZGl2IGFzIGZhbGxiYWNrXG4gICAgICAgIGNvbnN0IHN1Ym1pdFNlbGVjdG9yID0gJ2Rpdi5zdWJtaXQsIC5zdWJtaXQtYnRuLCAucHVibGlzaC1idG4nO1xuICAgICAgICBzdWJtaXRCdXR0b24gPSBhd2FpdCBwYWdlLiQoc3VibWl0U2VsZWN0b3IpO1xuICAgICAgICBpZiAoIXN1Ym1pdEJ1dHRvbikge1xuICAgICAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHN1Ym1pdCBidXR0b24nKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhd2FpdCBzdWJtaXRCdXR0b24uY2xpY2soKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ2xpY2tlZCBzdWJtaXQgYnV0dG9uIG5hdGl2ZWx5Jyk7XG4gICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgRmFpbGVkIHRvIGNsaWNrIHN1Ym1pdCBidXR0b246ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGlzRWxlbWVudFZpc2libGUoZWxlbWVudDogRWxlbWVudCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgKGVsZW1lbnQgYXMgYW55KS5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgd2FpdEZvclB1Ymxpc2hDb21wbGV0aW9uKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICBjb25zdCBtYXhXYWl0VGltZSA9IDYwMDAwOyAvLyA2MCBzZWNvbmRzXG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIC0gc3RhcnRUaW1lIDwgbWF4V2FpdFRpbWUpIHtcbiAgICAgIC8vIENoZWNrIGZvciBzdWNjZXNzIGluZGljYXRvcnNcbiAgICAgIGNvbnN0IHN1Y2Nlc3NJbmRpY2F0b3JzID0gW1xuICAgICAgICAnLnN1Y2Nlc3MtbWVzc2FnZScsXG4gICAgICAgICcucHVibGlzaC1zdWNjZXNzJyxcbiAgICAgICAgJ1tkYXRhLXRlc3RpZD1cInB1Ymxpc2gtc3VjY2Vzc1wiXScsXG4gICAgICAgICcudG9hc3Qtc3VjY2VzcycsXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHN1Y2Nlc3NJbmRpY2F0b3JzKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIGF3YWl0IHNsZWVwKDIwMDApOyAvLyBXYWl0IGEgYml0IG1vcmUgZm9yIGFueSBmaW5hbCBwcm9jZXNzaW5nXG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGZvciBlcnJvciBpbmRpY2F0b3JzXG4gICAgICBjb25zdCBlcnJvckluZGljYXRvcnMgPSBbXG4gICAgICAgICcuZXJyb3ItbWVzc2FnZScsXG4gICAgICAgICcucHVibGlzaC1lcnJvcicsXG4gICAgICAgICdbZGF0YS10ZXN0aWQ9XCJwdWJsaXNoLWVycm9yXCJdJyxcbiAgICAgICAgJy50b2FzdC1lcnJvcicsXG4gICAgICAgICcuZXJyb3ItdG9hc3QnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBlcnJvckluZGljYXRvcnMpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JUZXh0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLnRleHRDb250ZW50LCBlbGVtZW50KTtcbiAgICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBQdWJsaXNoIGZhaWxlZCB3aXRoIGVycm9yOiAke2Vycm9yVGV4dH1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBpZiB3ZSdyZSBzdGlsbCBvbiB0aGUgcHVibGlzaCBwYWdlXG4gICAgICBjb25zdCBwdWJsaXNoUGFnZUluZGljYXRvcnMgPSBbJ2Rpdi51cGxvYWQtY29udGVudCcsICdkaXYuc3VibWl0JywgJy5jcmVhdG9yLWVkaXRvciddO1xuXG4gICAgICBsZXQgc3RpbGxPblB1Ymxpc2hQYWdlID0gZmFsc2U7XG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHB1Ymxpc2hQYWdlSW5kaWNhdG9ycykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICBzdGlsbE9uUHVibGlzaFBhZ2UgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghc3RpbGxPblB1Ymxpc2hQYWdlKSB7XG4gICAgICAgIC8vIFdlJ3ZlIGxlZnQgdGhlIHB1Ymxpc2ggcGFnZSwgbGlrZWx5IHN1Y2Nlc3NmdWxcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdMZWZ0IHB1Ymxpc2ggcGFnZSwgYXNzdW1pbmcgc3VjY2VzcycpO1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5leHRyYWN0Tm90ZUlkRnJvbVBhZ2UocGFnZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGZvciB0b2FzdCBtZXNzYWdlc1xuICAgICAgY29uc3QgdG9hc3RTZWxlY3RvcnMgPSBbJy50b2FzdCcsICcubWVzc2FnZScsICcubm90aWZpY2F0aW9uJywgJ1tyb2xlPVwiYWxlcnRcIl0nXTtcblxuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiB0b2FzdFNlbGVjdG9ycykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICBjb25zdCB0b2FzdFRleHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwudGV4dENvbnRlbnQsIGVsZW1lbnQpO1xuICAgICAgICAgIGlmICh0b2FzdFRleHQpIHtcbiAgICAgICAgICAgIGlmICh0b2FzdFRleHQuaW5jbHVkZXMoJ+aIkOWKnycpIHx8IHRvYXN0VGV4dC5pbmNsdWRlcygnc3VjY2VzcycpKSB7XG4gICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgc3VjY2VzcyB0b2FzdDogJHt0b2FzdFRleHR9YCk7XG4gICAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmV4dHJhY3ROb3RlSWRGcm9tUGFnZShwYWdlKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIHRvYXN0VGV4dC5pbmNsdWRlcygn5aSx6LSlJykgfHxcbiAgICAgICAgICAgICAgdG9hc3RUZXh0LmluY2x1ZGVzKCdlcnJvcicpIHx8XG4gICAgICAgICAgICAgIHRvYXN0VGV4dC5pbmNsdWRlcygn6ZSZ6K+vJylcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBQdWJsaXNoIGZhaWxlZDogJHt0b2FzdFRleHR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHNsZWVwKDEwMDApOyAvLyBXYWl0IGJlZm9yZSBuZXh0IGNoZWNrXG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignUHVibGlzaCBjb21wbGV0aW9uIHRpbWVvdXQgLSBjb3VsZCBub3QgZGV0ZXJtaW5lIHJlc3VsdCcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGV4dHJhY3ROb3RlSWRGcm9tUGFnZShwYWdlOiBQYWdlKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIE1ldGhvZCAxOiBUcnkgdG8gZXh0cmFjdCBmcm9tIFVSTCBpZiByZWRpcmVjdGVkIHRvIG5vdGUgcGFnZVxuICAgICAgY29uc3QgY3VycmVudFVybCA9IHBhZ2UudXJsKCk7XG4gICAgICBsb2dnZXIuZGVidWcoYEN1cnJlbnQgVVJMIGFmdGVyIHB1Ymxpc2g6ICR7Y3VycmVudFVybH1gKTtcblxuICAgICAgLy8gQ2hlY2sgaWYgd2UncmUgb24gYSBub3RlIHBhZ2UgKFVSTCBjb250YWlucyAvZXhwbG9yZS8gb3IgL2Rpc2NvdmVyeS8pXG4gICAgICBjb25zdCBub3RlSWRNYXRjaCA9IGN1cnJlbnRVcmwubWF0Y2goL1xcL2V4cGxvcmVcXC8oW2EtZjAtOV0rKS9pKSB8fFxuICAgICAgICBjdXJyZW50VXJsLm1hdGNoKC9cXC9kaXNjb3ZlcnlcXC8oW2EtZjAtOV0rKS9pKTtcblxuICAgICAgaWYgKG5vdGVJZE1hdGNoICYmIG5vdGVJZE1hdGNoWzFdKSB7XG4gICAgICAgIGNvbnN0IG5vdGVJZCA9IG5vdGVJZE1hdGNoWzFdO1xuICAgICAgICBsb2dnZXIuZGVidWcoYEV4dHJhY3RlZCBub3RlIElEIGZyb20gVVJMOiAke25vdGVJZH1gKTtcbiAgICAgICAgcmV0dXJuIG5vdGVJZDtcbiAgICAgIH1cblxuICAgICAgLy8gTWV0aG9kIDI6IFRyeSB0byBmaW5kIG5vdGUgSUQgaW4gcGFnZSBjb250ZW50IG9yIGRhdGEgYXR0cmlidXRlc1xuICAgICAgY29uc3Qgbm90ZUlkRnJvbVBhZ2UgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHtcbiAgICAgICAgLy8gTG9vayBmb3IgZGF0YSBhdHRyaWJ1dGVzIHRoYXQgbWlnaHQgY29udGFpbiBub3RlIElEXG4gICAgICAgIGNvbnN0IGVsZW1lbnRzV2l0aERhdGEgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1ub3RlLWlkXSwgW2RhdGEtaWRdLCBbZGF0YS1pbXByZXNzaW9uXScpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzV2l0aERhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50ID0gZWxlbWVudHNXaXRoRGF0YVtpXTtcbiAgICAgICAgICBjb25zdCBub3RlSWQgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1ub3RlLWlkJykgfHxcbiAgICAgICAgICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJykgfHxcbiAgICAgICAgICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWltcHJlc3Npb24nKTtcbiAgICAgICAgICBpZiAobm90ZUlkICYmIG5vdGVJZC5sZW5ndGggPiAxMCkgeyAvLyBOb3RlIElEcyBhcmUgdHlwaWNhbGx5IGxvbmdcbiAgICAgICAgICAgIHJldHVybiBub3RlSWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTG9vayBmb3IgbGlua3MgdG8gbm90ZSBwYWdlc1xuICAgICAgICBjb25zdCBub3RlTGlua3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdhW2hyZWYqPVwiL2V4cGxvcmUvXCJdLCBhW2hyZWYqPVwiL2Rpc2NvdmVyeS9cIl0nKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub3RlTGlua3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBsaW5rID0gbm90ZUxpbmtzW2ldO1xuICAgICAgICAgIGNvbnN0IGhyZWYgPSBsaW5rLmdldEF0dHJpYnV0ZSgnaHJlZicpO1xuICAgICAgICAgIGlmIChocmVmKSB7XG4gICAgICAgICAgICBjb25zdCBtYXRjaCA9IGhyZWYubWF0Y2goL1xcL2V4cGxvcmVcXC8oW2EtZjAtOV0rKS9pKSB8fFxuICAgICAgICAgICAgICBocmVmLm1hdGNoKC9cXC9kaXNjb3ZlcnlcXC8oW2EtZjAtOV0rKS9pKTtcbiAgICAgICAgICAgIGlmIChtYXRjaCAmJiBtYXRjaFsxXSkge1xuICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hbMV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTG9vayBmb3IgYW55IHRleHQgdGhhdCBsb29rcyBsaWtlIGEgbm90ZSBJRCAobG9uZyBoZXggc3RyaW5nKVxuICAgICAgICBjb25zdCB0ZXh0Q29udGVudCA9IGRvY3VtZW50LmJvZHkudGV4dENvbnRlbnQgfHwgJyc7XG4gICAgICAgIGNvbnN0IG5vdGVJZFBhdHRlcm4gPSAvW2EtZjAtOV17MjAsfS9naTtcbiAgICAgICAgY29uc3QgbWF0Y2hlcyA9IHRleHRDb250ZW50Lm1hdGNoKG5vdGVJZFBhdHRlcm4pO1xuICAgICAgICBpZiAobWF0Y2hlcyAmJiBtYXRjaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAvLyBSZXR1cm4gdGhlIGZpcnN0IGxvbmcgaGV4IHN0cmluZyBmb3VuZFxuICAgICAgICAgIHJldHVybiBtYXRjaGVzWzBdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9KTtcblxuICAgICAgaWYgKG5vdGVJZEZyb21QYWdlKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgRXh0cmFjdGVkIG5vdGUgSUQgZnJvbSBwYWdlIGNvbnRlbnQ6ICR7bm90ZUlkRnJvbVBhZ2V9YCk7XG4gICAgICAgIHJldHVybiBub3RlSWRGcm9tUGFnZTtcbiAgICAgIH1cblxuICAgICAgLy8gTWV0aG9kIDM6IFRyeSB0byBnZXQgdGhlIGxhdGVzdCBub3RlIElEIHVzaW5nIE5vdGVTZXJ2aWNlIChmYWxsYmFjaylcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ291bGQgbm90IGV4dHJhY3Qgbm90ZSBJRCBmcm9tIHBhZ2UsIHRyeWluZyBmYWxsYmFjayBtZXRob2QnKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIFdhaXQgYSBiaXQgZm9yIHRoZSBub3RlIHRvIGJlIHByb2Nlc3NlZFxuICAgICAgICBhd2FpdCBzbGVlcCg1MDAwKTtcblxuICAgICAgICAvLyBVc2UgTm90ZVNlcnZpY2UgdG8gZ2V0IHRoZSBsYXRlc3Qgbm90ZSBJRFxuICAgICAgICBjb25zdCB7IE5vdGVTZXJ2aWNlIH0gPSBhd2FpdCBpbXBvcnQoJy4uL25vdGVzL25vdGUuc2VydmljZScpO1xuICAgICAgICBjb25zdCBub3RlU2VydmljZSA9IG5ldyBOb3RlU2VydmljZSh0aGlzLmdldENvbmZpZygpKTtcbiAgICAgICAgY29uc3QgdXNlck5vdGVzID0gYXdhaXQgbm90ZVNlcnZpY2UuZ2V0VXNlck5vdGVzKDEpOyAvLyBHZXQgb25seSB0aGUgbGF0ZXN0IG5vdGVcblxuICAgICAgICBpZiAodXNlck5vdGVzLnN1Y2Nlc3MgJiYgdXNlck5vdGVzLmRhdGEgJiYgdXNlck5vdGVzLmRhdGEubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IGxhdGVzdE5vdGVJZCA9IHVzZXJOb3Rlcy5kYXRhWzBdLmlkO1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRXh0cmFjdGVkIG5vdGUgSUQgZnJvbSBOb3RlU2VydmljZTogJHtsYXRlc3ROb3RlSWR9YCk7XG4gICAgICAgICAgcmV0dXJuIGxhdGVzdE5vdGVJZDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEZhbGxiYWNrIG5vdGUgSUQgZXh0cmFjdGlvbiBmYWlsZWQ6ICR7ZXJyb3J9YCk7XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ291bGQgbm90IGV4dHJhY3Qgbm90ZSBJRCBmcm9tIGFueSBtZXRob2QnKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGV4dHJhY3Qgbm90ZSBJRDogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCB2YWxpZGF0ZUNvbnRlbnRJbnB1dHMoXG4gICAgdHlwZTogJ2ltYWdlJyB8ICd2aWRlbycsXG4gICAgdGl0bGU6IHN0cmluZyxcbiAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgbWVkaWFQYXRoczogc3RyaW5nW11cbiAgKTogdm9pZCB7XG4gICAgaWYgKCF0aXRsZT8udHJpbSgpKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGAke3R5cGUgPT09ICdpbWFnZScgPyAnSW1hZ2UnIDogJ1ZpZGVvJ30gdGl0bGUgY2Fubm90IGJlIGVtcHR5YCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb250ZW50Py50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYCR7dHlwZSA9PT0gJ2ltYWdlJyA/ICdJbWFnZScgOiAnVmlkZW8nfSBjb250ZW50IGNhbm5vdCBiZSBlbXB0eWApO1xuICAgIH1cblxuICAgIGlmICghbWVkaWFQYXRocyB8fCBtZWRpYVBhdGhzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgJHt0eXBlID09PSAnaW1hZ2UnID8gJ0ltYWdlJyA6ICdWaWRlbyd9IHBhdGhzIGFyZSByZXF1aXJlZGApO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnaW1hZ2UnICYmIG1lZGlhUGF0aHMubGVuZ3RoID4gMTgpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ01heGltdW0gMTggaW1hZ2VzIGFsbG93ZWQgZm9yIGltYWdlIHBvc3RzJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICd2aWRlbycgJiYgbWVkaWFQYXRocy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ1ZpZGVvIHB1Ymxpc2hpbmcgcmVxdWlyZXMgZXhhY3RseSBvbmUgdmlkZW8gZmlsZScpO1xuICAgIH1cbiAgfVxufSIsImltcG9ydCB7IGFzc2VydFRpdGxlV2lkdGhWYWxpZCwgZ2V0VGl0bGVXaWR0aCB9IGZyb20gJy4uLy4uL3NoYXJlZC90aXRsZS12YWxpZGF0b3InO1xuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBQdWJsaXNoUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IFB1Ymxpc2hFcnJvciwgSW52YWxpZEltYWdlRXJyb3IgfSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgZXhpc3RzU3luYywgc3RhdFN5bmMsIHdyaXRlRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBQdWJsaXNoQmFzZVNlcnZpY2UgfSBmcm9tICcuL3B1Ymxpc2gtYmFzZS5zZXJ2aWNlJztcblxuZXhwb3J0IGNsYXNzIEltYWdlUHVibGlzaFNlcnZpY2UgZXh0ZW5kcyBQdWJsaXNoQmFzZVNlcnZpY2Uge1xuICBhc3luYyBwdWJsaXNoTm90ZShcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICBpbWFnZVBhdGhzOiBzdHJpbmdbXSxcbiAgICB0YWdzOiBzdHJpbmcgPSAnJyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPFB1Ymxpc2hSZXN1bHQ+IHtcbiAgICAvLyBWYWxpZGF0ZSBpbnB1dHNcbiAgICBpZiAoIXRpdGxlPy50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ05vdGUgdGl0bGUgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgdGl0bGUgd2lkdGggKENKSyBjaGFyYWN0ZXJzIGNvdW50IGFzIDIgdW5pdHMsIEFTQ0lJIGFzIDEpXG4gICAgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkKHRpdGxlKTtcbiAgICBsb2dnZXIuZGVidWcoYFRpdGxlIHdpZHRoIHZhbGlkYXRpb24gcGFzc2VkOiBcIiR7dGl0bGV9XCIgKCR7Z2V0VGl0bGVXaWR0aCh0aXRsZSl9IHVuaXRzKWApO1xuXG4gICAgaWYgKCFjb250ZW50Py50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ05vdGUgY29udGVudCBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICBpZiAoIWltYWdlUGF0aHMgfHwgaW1hZ2VQYXRocy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ0F0IGxlYXN0IG9uZSBpbWFnZSBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8vIFByb2Nlc3MgaW1hZ2UgcGF0aHMgLSBkb3dubG9hZCBVUkxzIGFuZCB2YWxpZGF0ZSBsb2NhbCBwYXRoc1xuICAgIGNvbnN0IHJlc29sdmVkUGF0aHMgPSBhd2FpdCB0aGlzLnZhbGlkYXRlQW5kUmVzb2x2ZUltYWdlUGF0aHMoaW1hZ2VQYXRocyk7XG5cbiAgICAvLyBXYWl0IGZvciB1cGxvYWQgY29udGFpbmVyIHNlbGVjdG9yXG4gICAgY29uc3QgdXBsb2FkU2VsZWN0b3IgPSAnZGl2LnVwbG9hZC1jb250ZW50JztcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UoZmFsc2UsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KFxuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgdGhpcy5nZXRDb25maWcoKS54aHMuY3JlYXRvclB1Ymxpc2hVcmxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBXYWl0IGZvciBwYWdlIHRvIGxvYWRcbiAgICAgICAgYXdhaXQgc2xlZXAoMzAwMCk7XG5cbiAgICAgICAgLy8gRmlyc3QsIHRyeSB0byBzd2l0Y2ggdG8gdGhlIGltYWdlL3RleHQgdXBsb2FkIHRhYlxuICAgICAgICBhd2FpdCB0aGlzLmNsaWNrVXBsb2FkVGFiKHBhZ2UpO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHRhYiBzd2l0Y2ggdG8gY29tcGxldGVcbiAgICAgICAgYXdhaXQgc2xlZXAoMzAwMCk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgdGFiIHN3aXRjaCB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmV0cnkgaWYgbmVlZGVkXG4gICAgICAgIGNvbnN0IHBhZ2VTdGF0ZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBidXR0b25UZXh0czogQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdidXR0b24sIGRpdltyb2xlPVwiYnV0dG9uXCJdJykpXG4gICAgICAgICAgICAgIC5tYXAoKGVsOiBFbGVtZW50KSA9PiBlbC50ZXh0Q29udGVudD8udHJpbSgpKVxuICAgICAgICAgICAgICAuZmlsdGVyKCh0OiBzdHJpbmcgfCB1bmRlZmluZWQpID0+IHQpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIElmIHN0aWxsIHNob3dpbmcgdmlkZW8gdXBsb2FkLCB0cnkgY2xpY2tpbmcgdGhlIHRhYiBhZ2FpblxuICAgICAgICBpZiAoXG4gICAgICAgICAgcGFnZVN0YXRlLmJ1dHRvblRleHRzLmluY2x1ZGVzKCfkuIrkvKDop4bpopEnKSAmJlxuICAgICAgICAgICFwYWdlU3RhdGUuYnV0dG9uVGV4dHMuaW5jbHVkZXMoJ+S4iuS8oOWbvuaWhycpXG4gICAgICAgICkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuY2xpY2tVcGxvYWRUYWIocGFnZSk7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoMzAwMCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgaGFzVXBsb2FkQ29udGFpbmVyID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLnRyeVdhaXRGb3JTZWxlY3RvcihcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIHVwbG9hZFNlbGVjdG9yLFxuICAgICAgICAgIDMwMDAwXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKCFoYXNVcGxvYWRDb250YWluZXIpIHtcbiAgICAgICAgICAvLyBUcnkgYWx0ZXJuYXRpdmUgc2VsZWN0b3JzIGZvciB1cGxvYWQgY29udGFpbmVyXG4gICAgICAgICAgY29uc3QgYWx0ZXJuYXRpdmVTZWxlY3RvcnMgPSBbXG4gICAgICAgICAgICAnZGl2LnVwbG9hZC1jb250ZW50JyxcbiAgICAgICAgICAgICcudXBsb2FkLWNvbnRlbnQnLFxuICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJ1cGxvYWRcIl0nLFxuICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJpbWFnZVwiXScsXG4gICAgICAgICAgICAnaW5wdXRbdHlwZT1cImZpbGVcIl0nLFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIGFsdGVybmF0aXZlU2VsZWN0b3JzKSB7XG4gICAgICAgICAgICBoYXNVcGxvYWRDb250YWluZXIgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkudHJ5V2FpdEZvclNlbGVjdG9yKFxuICAgICAgICAgICAgICBwYWdlLFxuICAgICAgICAgICAgICBzZWxlY3RvcixcbiAgICAgICAgICAgICAgMTAwMDBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoaGFzVXBsb2FkQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaGFzVXBsb2FkQ29udGFpbmVyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQ291bGQgbm90IGZpbmQgdXBsb2FkIGNvbnRhaW5lciBvbiBwdWJsaXNoIHBhZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwbG9hZCBpbWFnZXNcbiAgICAgICAgYXdhaXQgdGhpcy51cGxvYWRJbWFnZXMocGFnZSwgcmVzb2x2ZWRQYXRocyk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgaW1hZ2VzIHRvIGJlIHByb2Nlc3NlZCAobGFyZ2UgZmlsZXMgbmVlZCBtb3JlIHRpbWUgb24gWEhTKVxuICAgICAgICBsb2dnZXIuZGVidWcoJ1dhaXRpbmcgMTUgc2Vjb25kcyBmb3IgaW1hZ2VzIHRvIGJlIHVwbG9hZGVkIGFuZCBwcm9jZXNzZWQuLi4nKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTUwMDApO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHBhZ2UgdG8gdHJhbnNpdGlvbiB0byBlZGl0IG1vZGUgKGNoZWNrIGZvciB0aXRsZSBvciBjb250ZW50IGlucHV0KVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKFxuICAgICAgICAgICAgJ2lucHV0W3BsYWNlaG9sZGVyKj1cIuagh+mimFwiXSwgZGl2W2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIC50aXB0YXAuUHJvc2VNaXJyb3InLFxuICAgICAgICAgICAgeyB0aW1lb3V0OiAxNTAwMCB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAvLyBDb250aW51ZSB3aXRob3V0IHdhaXRpbmdcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdhaXQgYSBiaXQgZm9yIHRoZSBwYWdlIHRvIHNldHRsZSBhZnRlciBpbWFnZSB1cGxvYWRcbiAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG5cbiAgICAgICAgLy8gRmlsbCBpbiB0aXRsZVxuICAgICAgICBhd2FpdCB0aGlzLmZpbGxUaXRsZShwYWdlLCB0aXRsZSk7XG5cbiAgICAgICAgLy8gV2FpdCBhIGJpdCBtb3JlIGZvciBjb250ZW50IGFyZWEgdG8gYXBwZWFyXG4gICAgICAgIGF3YWl0IHNsZWVwKDIwMDApO1xuXG4gICAgICAgIC8vIEZpbGwgaW4gY29udGVudFxuICAgICAgICBhd2FpdCB0aGlzLmZpbGxDb250ZW50KHBhZ2UsIGNvbnRlbnQpO1xuXG4gICAgICAgIC8vIEFkZCB0YWdzIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0YWdzKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGRUYWdzKHBhZ2UsIHRhZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3VibWl0IHRoZSBub3RlXG4gICAgICAgIGF3YWl0IHRoaXMuc3VibWl0UG9zdChwYWdlKTtcblxuICAgICAgICAvLyBXYWl0IGZvciBjb21wbGV0aW9uIGFuZCBjaGVjayByZXN1bHRcbiAgICAgICAgY29uc3Qgbm90ZUlkID0gYXdhaXQgdGhpcy53YWl0Rm9yUHVibGlzaENvbXBsZXRpb24ocGFnZSk7XG5cbiAgICAgICAgLy8gU2F2ZSBjb29raWVzXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5zYXZlQ29va2llc0Zyb21QYWdlKHBhZ2UpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBtZXNzYWdlOiAnTm90ZSBwdWJsaXNoZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICBjb250ZW50LFxuICAgICAgICAgIGltYWdlQ291bnQ6IHJlc29sdmVkUGF0aHMubGVuZ3RoLFxuICAgICAgICAgIHRhZ3MsXG4gICAgICAgICAgdXJsOiB0aGlzLmdldENvbmZpZygpLnhocy5jcmVhdG9yUHVibGlzaFVybCxcbiAgICAgICAgICBub3RlSWQ6IG5vdGVJZCB8fCB1bmRlZmluZWQsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgUHVibGlzaCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzIGltYWdlIHBhdGhzIC0gZG93bmxvYWQgVVJMcyBhbmQgdmFsaWRhdGUgbG9jYWwgcGF0aHNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgdmFsaWRhdGVBbmRSZXNvbHZlSW1hZ2VQYXRocyhpbWFnZVBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAvLyBVc2UgSW1hZ2VEb3dubG9hZGVyIHRvIHByb2Nlc3MgcGF0aHMgKGRvd25sb2FkcyBVUkxzLCB2YWxpZGF0ZXMgbG9jYWwgcGF0aHMpXG4gICAgY29uc3QgcmVzb2x2ZWRQYXRocyA9IGF3YWl0IHRoaXMuaW1hZ2VEb3dubG9hZGVyLnByb2Nlc3NJbWFnZVBhdGhzKGltYWdlUGF0aHMpO1xuXG4gICAgLy8gVmFsaWRhdGUgcmVzb2x2ZWQgcGF0aHNcbiAgICBmb3IgKGNvbnN0IHJlc29sdmVkUGF0aCBvZiByZXNvbHZlZFBhdGhzKSB7XG4gICAgICAvLyBGb3IgbG9jYWwgcGF0aHMgdGhhdCBhcmVuJ3QgYWJzb2x1dGUsIHJlc29sdmUgdGhlbVxuICAgICAgY29uc3QgZnVsbFBhdGggPVxuICAgICAgICByZXNvbHZlZFBhdGguc3RhcnRzV2l0aCgnLycpIHx8IHJlc29sdmVkUGF0aC5tYXRjaCgvXlthLXpBLVpdOi8pXG4gICAgICAgICAgPyByZXNvbHZlZFBhdGhcbiAgICAgICAgICA6IGpvaW4ocHJvY2Vzcy5jd2QoKSwgcmVzb2x2ZWRQYXRoKTtcblxuICAgICAgaWYgKCFleGlzdHNTeW5jKGZ1bGxQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoYEltYWdlIGZpbGUgbm90IGZvdW5kOiAke3Jlc29sdmVkUGF0aH1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhmdWxsUGF0aCk7XG4gICAgICBpZiAoIXN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihgUGF0aCBpcyBub3QgYSBmaWxlOiAke3Jlc29sdmVkUGF0aH1gKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgZmlsZSBleHRlbnNpb25cbiAgICAgIGNvbnN0IGV4dCA9IHJlc29sdmVkUGF0aC50b0xvd2VyQ2FzZSgpLnNwbGl0KCcuJykucG9wKCk7XG4gICAgICBjb25zdCBhbGxvd2VkRXh0ZW5zaW9ucyA9IFsnanBnJywgJ2pwZWcnLCAncG5nJywgJ2dpZicsICd3ZWJwJywgJ2JtcCddO1xuICAgICAgaWYgKCFleHQgfHwgIWFsbG93ZWRFeHRlbnNpb25zLmluY2x1ZGVzKGV4dCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKFxuICAgICAgICAgIGBVbnN1cHBvcnRlZCBpbWFnZSBmb3JtYXQ6ICR7cmVzb2x2ZWRQYXRofS4gU3VwcG9ydGVkOiAke2FsbG93ZWRFeHRlbnNpb25zLmpvaW4oJywgJyl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZXNvbHZlZFBhdGhzLmxlbmd0aCA+IDE4KSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdNYXhpbXVtIDE4IGltYWdlcyBhbGxvd2VkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc29sdmVkUGF0aHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNsaWNrVXBsb2FkVGFiKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdBdHRlbXB0aW5nIHRvIHN3aXRjaCB0byBcIuS4iuS8oOWbvuaWh1wiIHRhYiB1c2luZyBQdXBwZXRlZXIgb3V0ZXIgbmF0aXZlIGNsaWNrJyk7XG5cbiAgICAgIC8vIFdhaXQgZm9yIHRhYnMgdG8gcmVuZGVyXG4gICAgICBhd2FpdCBwYWdlLndhaXRGb3JTZWxlY3RvcignLmNyZWF0b3ItdGFiJywgeyB0aW1lb3V0OiAxMDAwMCB9KTtcblxuICAgICAgY29uc3QgdGFicyA9IGF3YWl0IHBhZ2UuJCQoJy5jcmVhdG9yLXRhYicpO1xuICAgICAgbGV0IGNsaWNrZWQgPSBmYWxzZTtcblxuICAgICAgZm9yIChjb25zdCB0YWIgb2YgdGFicykge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgdGFiLmV2YWx1YXRlKGVsID0+IGVsLnRleHRDb250ZW50KTtcbiAgICAgICAgaWYgKHRleHQgJiYgKHRleHQuaW5jbHVkZXMoJ+S4iuS8oOWbvuaWhycpIHx8IHRleHQuaW5jbHVkZXMoJ+WbvuaWhycpKSkge1xuXG4gICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGFiLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgICBpZiAoIWlzVmlzaWJsZSkge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdGb3VuZCBhIG1hdGNoaW5nIHRhYiwgYnV0IGl0IGlzIG5vdCB2aXNpYmxlIGluIHRoZSB2aWV3cG9ydC4gU2tpcHBpbmcuLi4nKTtcbiAgICAgICAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIGhpZGRlbiBlbGVtZW50c1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFRyeSBuYXRpdmUgY2xpY2sgZmlyc3RcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgKHRhYiBhcyBhbnkpLmNsaWNrKHsgZGVsYXk6IDE1MCB9KTtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnTmF0aXZlIFB1cHBldGVlciBjbGljayBzdWNjZWVkZWQgb24gdGFiLicpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgUHVwcGV0ZWVyIG5hdGl2ZSBjbGljayBmYWlsZWQgb24gdmlzaWJsZSB0YWI6ICR7ZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcblxuICAgICAgICAgIC8vIEZvcmNlIGEgc2Vjb25kYXJ5IGNsaWNrIG9uIHRoZSB0ZXh0IGl0c2VsZiB2aWEgZXZhbHVhdGUganVzdCBpbiBjYXNlIGhpdCBhcmVhIG1pc3NlZFxuICAgICAgICAgIGF3YWl0IHRhYi5ldmFsdWF0ZSgoZWwpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNwYW4gPSBlbC5xdWVyeVNlbGVjdG9yKCdzcGFuJykgfHwgZWw7XG4gICAgICAgICAgICAoc3BhbiBhcyBIVE1MRWxlbWVudCkuY2xpY2soKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNsaWNrZWQgPSB0cnVlO1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnU3VjY2Vzc2Z1bGx5IGNsaWNrZWQgaW1hZ2UgdGFiIHRleHQgbWF0Y2guJyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFjbGlja2VkKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdDb3VsZCBub3QgZmluZCB2aXNpYmxlIGltYWdlIHRhYiB2aWEgdGV4dHVhbCBtYXRjaGluZy4nKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gY2xpY2sgdXBsb2FkIHRhYjogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwbG9hZEltYWdlcyhwYWdlOiBQYWdlLCBpbWFnZVBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ1VwbG9hZGluZyBpbWFnZXMgdXNpbmcgZGlyZWN0IGlucHV0IGVsZW1lbnQgdGFyZ2V0aW5nJyk7XG5cbiAgICAgIGNvbnN0IGZpbGVJbnB1dCA9IGF3YWl0IHBhZ2UuJCgnaW5wdXRbdHlwZT1cImZpbGVcIl0nKTtcbiAgICAgIGlmICghZmlsZUlucHV0KSB7XG4gICAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIGZpbGUgdXBsb2FkIGlucHV0IG9uIHBhZ2UnKTtcbiAgICAgIH1cblxuICAgICAgLy8gRW5zdXJlIHRoZSBpbnB1dCBhY2NlcHRzIG11bHRpcGxlIGZpbGVzIGFuZCBhbnkgdHlwZSB0byBhdm9pZCBmcm9udGVuZCBibG9ja3NcbiAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsOiBFbGVtZW50IHwgbnVsbCkgPT4ge1xuICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ211bHRpcGxlJywgJ211bHRpcGxlJyk7XG4gICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCdhY2NlcHQnKTtcbiAgICAgICAgfVxuICAgICAgfSwgZmlsZUlucHV0KTtcblxuICAgICAgbG9nZ2VyLmRlYnVnKGBTdWJtaXR0aW5nICR7aW1hZ2VQYXRocy5sZW5ndGh9IGltYWdlIHBhdGhzIHRvIGZpbGUgaW5wdXQgZWxlbWVudGApO1xuICAgICAgYXdhaXQgZmlsZUlucHV0LnVwbG9hZEZpbGUoLi4uaW1hZ2VQYXRocyk7XG5cbiAgICAgIC8vIERpc3BhdGNoIGEgY2hhbmdlIGV2ZW50IG1hbnVhbGx5IGluIGNhc2UgdGhlIGZyYW1ld29yayBtaXNzZWQgaXRcbiAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsOiBFbGVtZW50IHwgbnVsbCkgPT4ge1xuICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnY2hhbmdlJywgeyBidWJibGVzOiB0cnVlIH0pKTtcbiAgICAgICAgfVxuICAgICAgfSwgZmlsZUlucHV0KTtcblxuICAgICAgYXdhaXQgc2xlZXAoMTUwMDApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBGYWlsZWQgdG8gdXBsb2FkIGltYWdlczogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBhc3NlcnRUaXRsZVdpZHRoVmFsaWQsIGdldFRpdGxlV2lkdGggfSBmcm9tICcuLi8uLi9zaGFyZWQvdGl0bGUtdmFsaWRhdG9yJztcbmltcG9ydCB7IFNFTEVDVE9SUywgVEVYVF9QQVRURVJOUywgVklERU9fVElNRU9VVFMgfSBmcm9tICcuL3B1Ymxpc2gtYmFzZS5zZXJ2aWNlJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IFB1Ymxpc2hSZXN1bHQgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgUHVibGlzaEVycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IGV4aXN0c1N5bmMsIHN0YXRTeW5jIH0gZnJvbSAnZnMnO1xuaW1wb3J0IHsgUHVibGlzaEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi9wdWJsaXNoLWJhc2Uuc2VydmljZSc7XG5cbmV4cG9ydCBjbGFzcyBWaWRlb1B1Ymxpc2hTZXJ2aWNlIGV4dGVuZHMgUHVibGlzaEJhc2VTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yVmlkZW9QdWJsaXNoQ29tcGxldGlvbihwYWdlOiBQYWdlKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgbG9nZ2VyLmRlYnVnKCdXYWl0aW5nIGZvciB2aWRlbyBwdWJsaXNoIGNvbXBsZXRpb24uLi4nKTtcblxuICAgIGxldCBpc1Byb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAgIGF3YWl0IHRoaXMud2FpdEZvckNvbmRpdGlvbihcbiAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gQ2hlY2sgZm9yIHN1Y2Nlc3MgaW5kaWNhdG9yc1xuICAgICAgICBjb25zdCBzdWNjZXNzUmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0VsZW1lbnRGb3JQYXR0ZXJucyhcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIFNFTEVDVE9SUy5TVUNDRVNTX0lORElDQVRPUlMsXG4gICAgICAgICAgVEVYVF9QQVRURVJOUy5TVUNDRVNTXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHN1Y2Nlc3NSZXN1bHQuZm91bmQpIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIHN1Y2Nlc3MgaW5kaWNhdG9yOiAke3N1Y2Nlc3NSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgICBhd2FpdCBzbGVlcChWSURFT19USU1FT1VUUy5DT01QTEVUSU9OX0NIRUNLKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGZvciBlcnJvciBpbmRpY2F0b3JzXG4gICAgICAgIGNvbnN0IGVycm9yUmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0VsZW1lbnRGb3JQYXR0ZXJucyhcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIFNFTEVDVE9SUy5FUlJPUl9JTkRJQ0FUT1JTLFxuICAgICAgICAgIFRFWFRfUEFUVEVSTlMuRVJST1JcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZXJyb3JSZXN1bHQuZm91bmQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBWaWRlbyBwdWJsaXNoIGZhaWxlZCB3aXRoIGVycm9yOiAke2Vycm9yUmVzdWx0LnRleHR9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBpZiB3ZSd2ZSBsZWZ0IHRoZSBwdWJsaXNoIHBhZ2UgKGxpa2VseSBzdWNjZXNzKVxuICAgICAgICBjb25zdCBzdGlsbE9uUGFnZSA9IGF3YWl0IHRoaXMuZmluZEVsZW1lbnRCeVNlbGVjdG9ycyhcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIFNFTEVDVE9SUy5QVUJMSVNIX1BBR0VfSU5ESUNBVE9SU1xuICAgICAgICApO1xuICAgICAgICBpZiAoIXN0aWxsT25QYWdlKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdMZWZ0IHB1Ymxpc2ggcGFnZSwgYXNzdW1pbmcgdmlkZW8gcHVibGlzaCBzdWNjZXNzJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBmb3IgcHJvY2Vzc2luZyBzdGF0dXNcbiAgICAgICAgY29uc3QgcHJvY2Vzc2luZ1Jlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuUFJPQ0VTU0lOR19JTkRJQ0FUT1JTLFxuICAgICAgICAgIFRFWFRfUEFUVEVSTlMuUFJPQ0VTU0lOR1xuICAgICAgICApO1xuXG4gICAgICAgIGlzUHJvY2Vzc2luZyA9IHByb2Nlc3NpbmdSZXN1bHQuZm91bmQ7XG4gICAgICAgIGlmIChpc1Byb2Nlc3NpbmcpIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoYFZpZGVvIHN0aWxsIHByb2Nlc3Npbmc6ICR7cHJvY2Vzc2luZ1Jlc3VsdC50ZXh0fWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIHRvYXN0IG1lc3NhZ2VzXG4gICAgICAgIGNvbnN0IHRvYXN0UmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0VsZW1lbnRGb3JQYXR0ZXJucyhcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIFNFTEVDVE9SUy5UT0FTVF9TRUxFQ1RPUlMsXG4gICAgICAgICAgVEVYVF9QQVRURVJOUy5TVUNDRVNTXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHRvYXN0UmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCBzdWNjZXNzIHRvYXN0OiAke3RvYXN0UmVzdWx0LnRleHR9YCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBlcnJvclRvYXN0UmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0VsZW1lbnRGb3JQYXR0ZXJucyhcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIFNFTEVDVE9SUy5UT0FTVF9TRUxFQ1RPUlMsXG4gICAgICAgICAgVEVYVF9QQVRURVJOUy5FUlJPUlxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChlcnJvclRvYXN0UmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgVmlkZW8gcHVibGlzaCBmYWlsZWQ6ICR7ZXJyb3JUb2FzdFJlc3VsdC50ZXh0fWApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSxcbiAgICAgIFZJREVPX1RJTUVPVVRTLkNPTVBMRVRJT05fVElNRU9VVCxcbiAgICAgIGlzUHJvY2Vzc2luZyA/IDUwMDAgOiBWSURFT19USU1FT1VUUy5DT01QTEVUSU9OX0NIRUNLLFxuICAgICAgJ1ZpZGVvIHB1Ymxpc2ggY29tcGxldGlvbiB0aW1lb3V0IC0gY291bGQgbm90IGRldGVybWluZSByZXN1bHQgYWZ0ZXIgNSBtaW51dGVzJ1xuICAgICk7XG5cbiAgICAvLyBFeHRyYWN0IG5vdGUgSUQgYWZ0ZXIgc3VjY2Vzc2Z1bCBjb21wbGV0aW9uXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICB9XG5cbiAgYXN5bmMgcHVibGlzaFZpZGVvKFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIHZpZGVvUGF0aDogc3RyaW5nLFxuICAgIHRhZ3M6IHN0cmluZyA9ICcnLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8UHVibGlzaFJlc3VsdD4ge1xuICAgIC8vIFZhbGlkYXRlIGlucHV0c1xuICAgIHRoaXMudmFsaWRhdGVWaWRlb0lucHV0cyh0aXRsZSwgY29udGVudCwgdmlkZW9QYXRoKTtcblxuICAgIC8vIFZhbGlkYXRlIGFuZCByZXNvbHZlIHZpZGVvIHBhdGhcbiAgICBjb25zdCByZXNvbHZlZFZpZGVvUGF0aCA9IHRoaXMudmFsaWRhdGVBbmRSZXNvbHZlVmlkZW9QYXRoKHZpZGVvUGF0aCk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKGZhbHNlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG5vdGVJZCA9IGF3YWl0IHRoaXMuZXhlY3V0ZVZpZGVvUHVibGlzaFdvcmtmbG93KHBhZ2UsIHRpdGxlLCBjb250ZW50LCByZXNvbHZlZFZpZGVvUGF0aCwgdGFncyk7XG5cbiAgICAgICAgLy8gU2F2ZSBjb29raWVzXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5zYXZlQ29va2llc0Zyb21QYWdlKHBhZ2UpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBtZXNzYWdlOiAnVmlkZW8gcHVibGlzaGVkIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgdGl0bGUsXG4gICAgICAgICAgY29udGVudCxcbiAgICAgICAgICBpbWFnZUNvdW50OiAwLCAvLyBWaWRlb3MgZG9uJ3QgaGF2ZSBpbWFnZSBjb3VudFxuICAgICAgICAgIHRhZ3MsXG4gICAgICAgICAgdXJsOiB0aGlzLmdldENvbmZpZygpLnhocy5jcmVhdG9yVmlkZW9QdWJsaXNoVXJsLFxuICAgICAgICAgIG5vdGVJZDogbm90ZUlkIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBWaWRlbyBwdWJsaXNoIGVycm9yOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZVZpZGVvSW5wdXRzKHRpdGxlOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZywgdmlkZW9QYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXRpdGxlPy50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ1ZpZGVvIHRpdGxlIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIHRpdGxlIHdpZHRoIGZvciB2aWRlbyBwb3N0cyB0b29cbiAgICBhc3NlcnRUaXRsZVdpZHRoVmFsaWQodGl0bGUpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgVmlkZW8gdGl0bGUgd2lkdGggdmFsaWRhdGlvbiBwYXNzZWQ6IFwiJHt0aXRsZX1cIiAoJHtnZXRUaXRsZVdpZHRoKHRpdGxlKX0gdW5pdHMpYCk7XG5cbiAgICBpZiAoIWNvbnRlbnQ/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignVmlkZW8gY29udGVudCBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICBpZiAoIXZpZGVvUGF0aD8udHJpbSgpKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdWaWRlbyBwYXRoIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlVmlkZW9QdWJsaXNoV29ya2Zsb3coXG4gICAgcGFnZTogUGFnZSxcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICB2aWRlb1BhdGg6IHN0cmluZyxcbiAgICB0YWdzOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgLy8gTmF2aWdhdGUgdG8gdmlkZW8gdXBsb2FkIHBhZ2VcbiAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkoXG4gICAgICBwYWdlLFxuICAgICAgdGhpcy5nZXRDb25maWcoKS54aHMuY3JlYXRvclZpZGVvUHVibGlzaFVybFxuICAgICk7XG5cbiAgICAvLyBXYWl0IGZvciBwYWdlIHRvIGxvYWRcbiAgICBhd2FpdCBzbGVlcChWSURFT19USU1FT1VUUy5QQUdFX0xPQUQpO1xuXG4gICAgLy8gU3dpdGNoIHRvIHZpZGVvIHVwbG9hZCB0YWIgaWYgbmVlZGVkXG4gICAgYXdhaXQgdGhpcy5jbGlja1ZpZGVvVXBsb2FkVGFiKHBhZ2UpO1xuXG4gICAgLy8gV2FpdCBmb3IgdGFiIHN3aXRjaCB0byBjb21wbGV0ZVxuICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlRBQl9TV0lUQ0gpO1xuXG4gICAgLy8gVXBsb2FkIHZpZGVvXG4gICAgYXdhaXQgdGhpcy51cGxvYWRWaWRlbyhwYWdlLCB2aWRlb1BhdGgpO1xuXG4gICAgLy8gV2FpdCBmb3IgdmlkZW8gdG8gYmUgcHJvY2Vzc2VkICh2aWRlb3MgdGFrZSBsb25nZXIgdGhhbiBpbWFnZXMpXG4gICAgYXdhaXQgc2xlZXAoVklERU9fVElNRU9VVFMuVklERU9fUFJPQ0VTU0lORyk7XG5cbiAgICAvLyBGaWxsIGluIHRpdGxlXG4gICAgYXdhaXQgdGhpcy5maWxsVGl0bGUocGFnZSwgdGl0bGUpO1xuXG4gICAgLy8gV2FpdCBhIGJpdCBmb3IgY29udGVudCBhcmVhIHRvIGFwcGVhclxuICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLkNPTlRFTlRfV0FJVCk7XG5cbiAgICAvLyBGaWxsIGluIGNvbnRlbnRcbiAgICBhd2FpdCB0aGlzLmZpbGxDb250ZW50KHBhZ2UsIGNvbnRlbnQpO1xuXG4gICAgLy8gQWRkIHRhZ3MgaWYgcHJvdmlkZWRcbiAgICBpZiAodGFncykge1xuICAgICAgYXdhaXQgdGhpcy5hZGRUYWdzKHBhZ2UsIHRhZ3MpO1xuICAgIH1cblxuICAgIC8vIFN1Ym1pdCB0aGUgdmlkZW9cbiAgICBhd2FpdCB0aGlzLnN1Ym1pdFBvc3QocGFnZSk7XG5cbiAgICAvLyBXYWl0IGZvciBjb21wbGV0aW9uIGFuZCBjaGVjayByZXN1bHQgKHZpZGVvcyBuZWVkIGxvbmdlciB0aW1lb3V0KVxuICAgIHJldHVybiBhd2FpdCB0aGlzLndhaXRGb3JWaWRlb1B1Ymxpc2hDb21wbGV0aW9uKHBhZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUFuZFJlc29sdmVWaWRlb1BhdGgodmlkZW9QYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHJlc29sdmVkUGF0aCA9IGpvaW4ocHJvY2Vzcy5jd2QoKSwgdmlkZW9QYXRoKTtcblxuICAgIGlmICghZXhpc3RzU3luYyhyZXNvbHZlZFBhdGgpKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBWaWRlbyBmaWxlIG5vdCBmb3VuZDogJHt2aWRlb1BhdGh9YCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhyZXNvbHZlZFBhdGgpO1xuICAgIGlmICghc3RhdHMuaXNGaWxlKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYFBhdGggaXMgbm90IGEgZmlsZTogJHt2aWRlb1BhdGh9YCk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZmlsZSBleHRlbnNpb25cbiAgICBjb25zdCBleHQgPSB2aWRlb1BhdGgudG9Mb3dlckNhc2UoKS5zcGxpdCgnLicpLnBvcCgpO1xuICAgIGNvbnN0IGFsbG93ZWRFeHRlbnNpb25zID0gWydtcDQnLCAnbW92JywgJ2F2aScsICdta3YnLCAnd2VibScsICdmbHYnLCAnd212J107XG4gICAgaWYgKCFleHQgfHwgIWFsbG93ZWRFeHRlbnNpb25zLmluY2x1ZGVzKGV4dCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoXG4gICAgICAgIGBVbnN1cHBvcnRlZCB2aWRlbyBmb3JtYXQ6ICR7dmlkZW9QYXRofS4gU3VwcG9ydGVkOiAke2FsbG93ZWRFeHRlbnNpb25zLmpvaW4oJywgJyl9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmaWxlIHNpemUgKFhIUyB0eXBpY2FsbHkgaGFzIGxpbWl0cylcbiAgICBjb25zdCBtYXhTaXplSW5NQiA9IDUwMDsgLy8gNTAwTUIgbGltaXRcbiAgICBjb25zdCBmaWxlU2l6ZUluTUIgPSBzdGF0cy5zaXplIC8gKDEwMjQgKiAxMDI0KTtcbiAgICBpZiAoZmlsZVNpemVJbk1CID4gbWF4U2l6ZUluTUIpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoXG4gICAgICAgIGBWaWRlbyBmaWxlIHRvbyBsYXJnZTogJHtmaWxlU2l6ZUluTUIudG9GaXhlZCgyKX1NQi4gTWF4aW11bSBhbGxvd2VkOiAke21heFNpemVJbk1CfU1CYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZWRQYXRoO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjbGlja1ZpZGVvVXBsb2FkVGFiKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgLy8gVHJ5IG11bHRpcGxlIHNlbGVjdG9ycyBmb3IgdmlkZW8gdGFiXG4gICAgICBjb25zdCB2aWRlb1RhYlNlbGVjdG9ycyA9IFtcbiAgICAgICAgJ2Rpdi5jcmVhdG9yLXRhYicsXG4gICAgICAgICcuY3JlYXRvci10YWInLFxuICAgICAgICAnW3JvbGU9XCJ0YWJcIl0nLFxuICAgICAgICAnLnRhYicsXG4gICAgICAgICdkaXZbY2xhc3MqPVwidGFiXCJdJyxcbiAgICAgIF07XG5cbiAgICAgIGxldCB0YWJzOiBhbnlbXSA9IFtdO1xuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiB2aWRlb1RhYlNlbGVjdG9ycykge1xuICAgICAgICBjb25zdCBmb3VuZFRhYnMgPSBhd2FpdCBwYWdlLiQkKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGZvdW5kVGFicy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGFicyA9IGZvdW5kVGFicztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGFicy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ05vIHRhYnMgZm91bmQgZm9yIHZpZGVvIHVwbG9hZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIExvb2sgZm9yIHRoZSB2aWRlbyB1cGxvYWQgdGFiIHNwZWNpZmljYWxseVxuICAgICAgbGV0IHZpZGVvVGFiOiBhbnkgPSBudWxsO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHRhYiA9IHRhYnNbaV07XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGFiLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgICBpZiAoIWlzVmlzaWJsZSkgY29udGludWU7XG5cbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLnRleHRDb250ZW50LCB0YWIpO1xuXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyB0aGUgdmlkZW8gdXBsb2FkIHRhYlxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRleHQgJiZcbiAgICAgICAgICAgICh0ZXh0LmluY2x1ZGVzKCfkuIrkvKDop4bpopEnKSB8fCB0ZXh0LmluY2x1ZGVzKCfop4bpopEnKSB8fCB0ZXh0LmluY2x1ZGVzKCd2aWRlbycpKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdmlkZW9UYWIgPSB0YWI7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgLy8gSWdub3JlIGluZGl2aWR1YWwgdGFiIGVycm9yc1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh2aWRlb1RhYikge1xuICAgICAgICBhd2FpdCB2aWRlb1RhYi5jbGljaygpO1xuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTsgLy8gV2FpdCBmb3IgdGFiIHN3aXRjaFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRmFsbGJhY2s6IGNsaWNrIHRoZSBmaXJzdCB0YWIgKHVzdWFsbHkgdmlkZW8gdXBsb2FkKVxuICAgICAgICBjb25zdCB2aXNpYmxlVGFiczogYW55W10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCB0YWIgb2YgdGFicykge1xuICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IHRhYi5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG4gICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgdmlzaWJsZVRhYnMucHVzaCh0YWIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2aXNpYmxlVGFicy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgYXdhaXQgdmlzaWJsZVRhYnNbMF0uY2xpY2soKTsgLy8gVXN1YWxseSB0aGUgZmlyc3QgdGFiIGlzIHZpZGVvIHVwbG9hZFxuICAgICAgICAgIGF3YWl0IHNsZWVwKDIwMDApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gY2xpY2sgdmlkZW8gdXBsb2FkIHRhYjogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwbG9hZFZpZGVvKHBhZ2U6IFBhZ2UsIHZpZGVvUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nZ2VyLmRlYnVnKGBVcGxvYWRpbmcgdmlkZW86ICR7dmlkZW9QYXRofWApO1xuXG4gICAgLy8gRmluZCBmaWxlIGlucHV0IGVsZW1lbnRcbiAgICBjb25zdCBmaWxlSW5wdXQgPSBhd2FpdCB0aGlzLmZpbmRFbGVtZW50QnlTZWxlY3RvcnMocGFnZSwgU0VMRUNUT1JTLkZJTEVfSU5QVVQpO1xuICAgIGlmICghZmlsZUlucHV0KSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdDb3VsZCBub3QgZmluZCBmaWxlIHVwbG9hZCBpbnB1dCBvbiB2aWRlbyB1cGxvYWQgcGFnZScpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBXYWl0IGZvciB0aGUgaW5wdXQgdG8gYmUgcmVhZHlcbiAgICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlVQTE9BRF9SRUFEWSk7XG5cbiAgICAgIC8vIFVwbG9hZCB0aGUgdmlkZW8gZmlsZVxuICAgICAgYXdhaXQgZmlsZUlucHV0LnVwbG9hZEZpbGUodmlkZW9QYXRoKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnVmlkZW8gZmlsZSB1cGxvYWRlZCwgd2FpdGluZyBmb3IgcHJvY2Vzc2luZy4uLicpO1xuXG4gICAgICAvLyBXYWl0IGZvciB1cGxvYWQgdG8gc3RhcnQgYW5kIHNob3cgcHJvZ3Jlc3NcbiAgICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlVQTE9BRF9TVEFSVCk7XG5cbiAgICAgIC8vIFdhaXQgZm9yIHZpZGVvIHByb2Nlc3NpbmcgdG8gY29tcGxldGUgKHRoaXMgY2FuIHRha2UgYSB3aGlsZSlcbiAgICAgIGF3YWl0IHRoaXMud2FpdEZvclZpZGVvUHJvY2Vzc2luZyhwYWdlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgRmFpbGVkIHRvIHVwbG9hZCB2aWRlbyAke3ZpZGVvUGF0aH06ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yVmlkZW9Qcm9jZXNzaW5nKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2dnZXIuZGVidWcoJ1dhaXRpbmcgZm9yIHZpZGVvIHByb2Nlc3NpbmcgdG8gY29tcGxldGUuLi4nKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JDb25kaXRpb24oXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAvLyBDaGVjayBpZiBwcm9jZXNzaW5nIGlzIGNvbXBsZXRlXG4gICAgICAgICAgY29uc3QgY29tcGxldGVSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgICAgcGFnZSxcbiAgICAgICAgICAgIFNFTEVDVE9SUy5DT01QTEVUSU9OX0lORElDQVRPUlMsXG4gICAgICAgICAgICBURVhUX1BBVFRFUk5TLlNVQ0NFU1NcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKGNvbXBsZXRlUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYFZpZGVvIHByb2Nlc3NpbmcgY29tcGxldGU6ICR7Y29tcGxldGVSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIENoZWNrIGlmIHN0aWxsIHByb2Nlc3NpbmdcbiAgICAgICAgICBjb25zdCBwcm9jZXNzaW5nUmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0VsZW1lbnRGb3JQYXR0ZXJucyhcbiAgICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgICBTRUxFQ1RPUlMuUFJPQ0VTU0lOR19JTkRJQ0FUT1JTLFxuICAgICAgICAgICAgVEVYVF9QQVRURVJOUy5QUk9DRVNTSU5HXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChwcm9jZXNzaW5nUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYFZpZGVvIHByb2Nlc3Npbmc6ICR7cHJvY2Vzc2luZ1Jlc3VsdC50ZXh0fWApO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBTdGlsbCBwcm9jZXNzaW5nLCBjb250aW51ZSB3YWl0aW5nXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gSWYgbm90IHByb2Nlc3NpbmcgYW5kIG5vIGNvbXBsZXRpb24gaW5kaWNhdG9yLCBhc3N1bWUgaXQncyBkb25lXG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdObyBwcm9jZXNzaW5nIGluZGljYXRvcnMgZm91bmQsIGFzc3VtaW5nIHZpZGVvIHByb2Nlc3NpbmcgY29tcGxldGUnKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgVklERU9fVElNRU9VVFMuUFJPQ0VTU0lOR19USU1FT1VULFxuICAgICAgICBWSURFT19USU1FT1VUUy5QUk9DRVNTSU5HX0NIRUNLLFxuICAgICAgICAnVmlkZW8gcHJvY2Vzc2luZyB0aW1lb3V0J1xuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oJ1ZpZGVvIHByb2Nlc3NpbmcgdGltZW91dCwgY29udGludWluZyBhbnl3YXkuLi4nKTtcbiAgICB9XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBDb25maWcsIFB1Ymxpc2hSZXN1bHQgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvYmFzZS5zZXJ2aWNlJztcbmltcG9ydCB7IEltYWdlUHVibGlzaFNlcnZpY2UgfSBmcm9tICcuL3B1Ymxpc2gtaW1hZ2Uuc2VydmljZSc7XG5pbXBvcnQgeyBWaWRlb1B1Ymxpc2hTZXJ2aWNlIH0gZnJvbSAnLi9wdWJsaXNoLXZpZGVvLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgUHVibGlzaFNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIHByaXZhdGUgaW1hZ2VTZXJ2aWNlOiBJbWFnZVB1Ymxpc2hTZXJ2aWNlO1xuICBwcml2YXRlIHZpZGVvU2VydmljZTogVmlkZW9QdWJsaXNoU2VydmljZTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IENvbmZpZykge1xuICAgIHN1cGVyKGNvbmZpZyk7XG4gICAgdGhpcy5pbWFnZVNlcnZpY2UgPSBuZXcgSW1hZ2VQdWJsaXNoU2VydmljZShjb25maWcpO1xuICAgIHRoaXMudmlkZW9TZXJ2aWNlID0gbmV3IFZpZGVvUHVibGlzaFNlcnZpY2UoY29uZmlnKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBwdWJsaXNoTm90ZShcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICBpbWFnZVBhdGhzOiBzdHJpbmdbXSxcbiAgICB0YWdzOiBzdHJpbmcgPSAnJyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPFB1Ymxpc2hSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5pbWFnZVNlcnZpY2UucHVibGlzaE5vdGUodGl0bGUsIGNvbnRlbnQsIGltYWdlUGF0aHMsIHRhZ3MsIGJyb3dzZXJQYXRoKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBwdWJsaXNoVmlkZW8oXG4gICAgdGl0bGU6IHN0cmluZyxcbiAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgdmlkZW9QYXRoOiBzdHJpbmcsXG4gICAgdGFnczogc3RyaW5nID0gJycsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxQdWJsaXNoUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMudmlkZW9TZXJ2aWNlLnB1Ymxpc2hWaWRlbyh0aXRsZSwgY29udGVudCwgdmlkZW9QYXRoLCB0YWdzLCBicm93c2VyUGF0aCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcHVibGlzaENvbnRlbnQoXG4gICAgdHlwZTogJ2ltYWdlJyB8ICd2aWRlbycsXG4gICAgdGl0bGU6IHN0cmluZyxcbiAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgbWVkaWFQYXRoczogc3RyaW5nW10sXG4gICAgdGFnczogc3RyaW5nID0gJycsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxQdWJsaXNoUmVzdWx0PiB7XG4gICAgaWYgKHR5cGUgPT09ICdpbWFnZScpIHtcbiAgICAgIHJldHVybiB0aGlzLnB1Ymxpc2hOb3RlKHRpdGxlLCBjb250ZW50LCBtZWRpYVBhdGhzLCB0YWdzLCBicm93c2VyUGF0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnB1Ymxpc2hWaWRlbyh0aXRsZSwgY29udGVudCwgbWVkaWFQYXRoc1swXSwgdGFncywgYnJvd3NlclBhdGgpO1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBUb29sIHJlcXVlc3QgaGFuZGxlcnMgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL2F1dGgvYXV0aC5zZXJ2aWNlJztcbmltcG9ydCB7IEZlZWRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9mZWVkcy9mZWVkLnNlcnZpY2UnO1xuaW1wb3J0IHsgUHVibGlzaFNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL3B1Ymxpc2hpbmcvcHVibGlzaC5zZXJ2aWNlJztcbmltcG9ydCB7IE5vdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9ub3Rlcy9ub3RlLnNlcnZpY2UnO1xuaW1wb3J0IHsgZ2V0Q29uZmlnIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2NvbmZpZyc7XG5pbXBvcnQgeyBYSFNFcnJvciB9IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHtcbiAgdmFsaWRhdGVSZXF1aXJlZFBhcmFtcyxcbiAgdmFsaWRhdGVQdWJsaXNoTm90ZVBhcmFtcyxcbiAgc2FmZUVycm9ySGFuZGxlcixcbiAgY3JlYXRlTWNwVG9vbFJlc3BvbnNlLFxuICBjcmVhdGVNY3BFcnJvclJlc3BvbnNlLFxufSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBhc3NlcnRUaXRsZVdpZHRoVmFsaWQgfSBmcm9tICcuLi8uLi9zaGFyZWQvdGl0bGUtdmFsaWRhdG9yJztcblxuLyoqXG4gKiBUb29sIHJlcXVlc3QgYXJndW1lbnRzIGludGVyZmFjZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRvb2xSZXF1ZXN0QXJncyB7XG4gIGJyb3dzZXJfcGF0aD86IHN0cmluZztcbiAga2V5d29yZD86IHN0cmluZztcbiAgZmVlZF9pZD86IHN0cmluZztcbiAgeHNlY190b2tlbj86IHN0cmluZztcbiAgbm90ZT86IHN0cmluZztcbiAgdHlwZT86IHN0cmluZztcbiAgdGl0bGU/OiBzdHJpbmc7XG4gIGNvbnRlbnQ/OiBzdHJpbmc7XG4gIG1lZGlhX3BhdGhzPzogc3RyaW5nW107XG4gIHRhZ3M/OiBzdHJpbmc7XG4gIGxpbWl0PzogbnVtYmVyO1xuICBjdXJzb3I/OiBzdHJpbmc7XG4gIG5vdGVfaWQ/OiBzdHJpbmc7XG4gIGxhc3RfcHVibGlzaGVkPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIFRvb2xIYW5kbGVycyB7XG4gIHByaXZhdGUgYXV0aFNlcnZpY2U6IEF1dGhTZXJ2aWNlO1xuICBwcml2YXRlIGZlZWRTZXJ2aWNlOiBGZWVkU2VydmljZTtcbiAgcHJpdmF0ZSBwdWJsaXNoU2VydmljZTogUHVibGlzaFNlcnZpY2U7XG4gIHByaXZhdGUgbm90ZVNlcnZpY2U6IE5vdGVTZXJ2aWNlO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgIHRoaXMuYXV0aFNlcnZpY2UgPSBuZXcgQXV0aFNlcnZpY2UoY29uZmlnKTtcbiAgICB0aGlzLmZlZWRTZXJ2aWNlID0gbmV3IEZlZWRTZXJ2aWNlKGNvbmZpZyk7XG4gICAgdGhpcy5wdWJsaXNoU2VydmljZSA9IG5ldyBQdWJsaXNoU2VydmljZShjb25maWcpO1xuICAgIHRoaXMubm90ZVNlcnZpY2UgPSBuZXcgTm90ZVNlcnZpY2UoY29uZmlnKTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUF1dGhMb2dpbihcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgLy8gU3RhcnQgbG9naW4gcHJvY2VzcyBpbiBiYWNrZ3JvdW5kIGFuZCByZXR1cm4gaW1tZWRpYXRlbHlcbiAgICAvLyBUaGlzIGZvbGxvd3MgdGhlIFwiaW5zdGFudCByZXNwb25zZVwiIHBhdHRlcm4gZGVzY3JpYmVkIGluIFJFQURNRVxuICAgIHRoaXMuYXV0aFNlcnZpY2UubG9naW4oYnJvd3NlclBhdGgpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgc2FmZUVycm9ySGFuZGxlcihlcnJvciwgJ0JhY2tncm91bmQgbG9naW4gZXJyb3InLCBsb2dnZXIpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICB0ZXh0OiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAnTG9naW4gcHJvY2VzcyBzdGFydGVkLiBBIGJyb3dzZXIgd2luZG93IHdpbGwgb3BlbiBmb3IgeW91IHRvIGNvbXBsZXRlIHRoZSBsb2dpbi4nLFxuICAgICAgICAgICAgICBzdGF0dXM6ICdsb2dpbl9zdGFydGVkJyxcbiAgICAgICAgICAgICAgYWN0aW9uOiAnYnJvd3Nlcl9vcGVuZWQnLFxuICAgICAgICAgICAgICBpbnN0cnVjdGlvbnM6IFtcbiAgICAgICAgICAgICAgICAnMS4gQ29tcGxldGUgdGhlIGxvZ2luIHByb2Nlc3MgaW4gdGhlIG9wZW5lZCBicm93c2VyIHdpbmRvdycsXG4gICAgICAgICAgICAgICAgJzIuIFNjYW4gUVIgY29kZSBvciBlbnRlciB5b3VyIGNyZWRlbnRpYWxzJyxcbiAgICAgICAgICAgICAgICAnMy4gTG9naW4gd2lsbCBiZSBhdXRvbWF0aWNhbGx5IHZlcmlmaWVkIGFuZCBjb29raWVzIHNhdmVkJyxcbiAgICAgICAgICAgICAgICAnNC4gVXNlIHhoc19hdXRoX3N0YXR1cyB0byBjaGVjayBpZiBsb2dpbiBjb21wbGV0ZWQnLFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICBub3RlOiAnVGhlIGxvZ2luIHByb2Nlc3MgcnVucyBpbiB0aGUgYmFja2dyb3VuZC4gWW91IGNhbiBjb250aW51ZSB1c2luZyBvdGhlciB0b29scyB3aGlsZSBsb2dpbiBjb21wbGV0ZXMuJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgMlxuICAgICAgICAgICksXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBoYW5kbGVBdXRoTG9nb3V0KCk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmF1dGhTZXJ2aWNlLmxvZ291dCgpO1xuICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUF1dGhTdGF0dXMoXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UuY2hlY2tTdGF0dXMoYnJvd3NlclBhdGgpO1xuICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZURpc2NvdmVyRmVlZHMoXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZmVlZFNlcnZpY2UuZ2V0RmVlZExpc3QoYnJvd3NlclBhdGgpO1xuICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZVNlYXJjaE5vdGUoXG4gICAga2V5d29yZD86IHN0cmluZyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgdmFsaWRhdGVSZXF1aXJlZFBhcmFtcyh7IGtleXdvcmQgfSwgWydrZXl3b3JkJ10pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZmVlZFNlcnZpY2Uuc2VhcmNoRmVlZHMoa2V5d29yZCEsIGJyb3dzZXJQYXRoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVHZXROb3RlRGV0YWlsKFxuICAgIGZlZWRJZD86IHN0cmluZyxcbiAgICB4c2VjVG9rZW4/OiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIHZhbGlkYXRlUmVxdWlyZWRQYXJhbXMoeyBmZWVkSWQsIHhzZWNUb2tlbiB9LCBbJ2ZlZWRJZCcsICd4c2VjVG9rZW4nXSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5mZWVkU2VydmljZS5nZXRGZWVkRGV0YWlsKGZlZWRJZCEsIHhzZWNUb2tlbiEsIGJyb3dzZXJQYXRoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVDb21tZW50T25Ob3RlKFxuICAgIGZlZWRJZD86IHN0cmluZyxcbiAgICB4c2VjVG9rZW4/OiBzdHJpbmcsXG4gICAgbm90ZT86IHN0cmluZyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgdmFsaWRhdGVSZXF1aXJlZFBhcmFtcyh7IGZlZWRJZCwgeHNlY1Rva2VuLCBub3RlIH0sIFsnZmVlZElkJywgJ3hzZWNUb2tlbicsICdub3RlJ10pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZmVlZFNlcnZpY2UuY29tbWVudE9uRmVlZChmZWVkSWQhLCB4c2VjVG9rZW4hLCBub3RlISwgYnJvd3NlclBhdGgpO1xuICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZVB1Ymxpc2hDb250ZW50KFxuICAgIHR5cGU/OiBzdHJpbmcsXG4gICAgdGl0bGU/OiBzdHJpbmcsXG4gICAgY29udGVudD86IHN0cmluZyxcbiAgICBtZWRpYVBhdGhzPzogc3RyaW5nW10sXG4gICAgdGFncz86IHN0cmluZyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgdmFsaWRhdGVSZXF1aXJlZFBhcmFtcyh7IHR5cGUsIHRpdGxlLCBjb250ZW50LCBtZWRpYVBhdGhzIH0sIFtcbiAgICAgICd0eXBlJyxcbiAgICAgICd0aXRsZScsXG4gICAgICAnY29udGVudCcsXG4gICAgICAnbWVkaWFQYXRocycsXG4gICAgXSk7XG5cbiAgICAvLyBWYWxpZGF0ZSBjb250ZW50IHR5cGVcbiAgICBpZiAodHlwZSAhPT0gJ2ltYWdlJyAmJiB0eXBlICE9PSAndmlkZW8nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnRlbnQgdHlwZSBtdXN0IGJlIFwiaW1hZ2VcIiBvciBcInZpZGVvXCInKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBwYXJhbWV0ZXIgY29uc3RyYWludHMgdXNpbmcgd2lkdGgtYXdhcmUgdGl0bGUgdmFsaWRhdGlvblxuICAgIGFzc2VydFRpdGxlV2lkdGhWYWxpZCh0aXRsZSEpO1xuICAgIGlmIChjb250ZW50IS5sZW5ndGggPiAxMDAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnRlbnQgbXVzdCBiZSAxMDAwIGNoYXJhY3RlcnMgb3IgbGVzcycpO1xuICAgIH1cblxuICAgIC8vIEV4ZWN1dGUgdW5pZmllZCBwdWJsaXNoaW5nIHByb2Nlc3NcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnB1Ymxpc2hTZXJ2aWNlLnB1Ymxpc2hDb250ZW50KFxuICAgICAgdHlwZSBhcyAnaW1hZ2UnIHwgJ3ZpZGVvJyxcbiAgICAgIHRpdGxlISxcbiAgICAgIGNvbnRlbnQhLFxuICAgICAgbWVkaWFQYXRocyEsXG4gICAgICB0YWdzLFxuICAgICAgYnJvd3NlclBhdGhcbiAgICApO1xuICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUdldFVzZXJOb3RlcyhcbiAgICBsaW1pdD86IG51bWJlcixcbiAgICBjdXJzb3I/OiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMubm90ZVNlcnZpY2UuZ2V0VXNlck5vdGVzKGxpbWl0LCBjdXJzb3IsIGJyb3dzZXJQYXRoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVEZWxldGVOb3RlKFxuICAgIG5vdGVJZD86IHN0cmluZyxcbiAgICBsYXN0UHVibGlzaGVkPzogYm9vbGVhbixcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgaWYgKGxhc3RQdWJsaXNoZWQpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMubm90ZVNlcnZpY2UuZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUoYnJvd3NlclBhdGgpO1xuICAgICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICAgIH0gZWxzZSBpZiAobm90ZUlkKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm5vdGVTZXJ2aWNlLmRlbGV0ZU5vdGUobm90ZUlkLCBicm93c2VyUGF0aCk7XG4gICAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRWl0aGVyIG5vdGVfaWQgb3IgbGFzdF9wdWJsaXNoZWQgbXVzdCBiZSBzcGVjaWZpZWQnKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYW5kbGVUb29sUmVxdWVzdChcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgYXJnczogVG9vbFJlcXVlc3RBcmdzID0ge31cbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIHRyeSB7XG4gICAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgICAgY2FzZSAneGhzX2F1dGhfbG9naW4nOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZUF1dGhMb2dpbihhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nKTtcblxuICAgICAgICBjYXNlICd4aHNfYXV0aF9sb2dvdXQnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZUF1dGhMb2dvdXQoKTtcblxuICAgICAgICBjYXNlICd4aHNfYXV0aF9zdGF0dXMnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZUF1dGhTdGF0dXMoYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZyk7XG5cbiAgICAgICAgY2FzZSAneGhzX2Rpc2NvdmVyX2ZlZWRzJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVEaXNjb3ZlckZlZWRzKGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmcpO1xuXG4gICAgICAgIGNhc2UgJ3hoc19zZWFyY2hfbm90ZSc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlU2VhcmNoTm90ZShhcmdzPy5rZXl3b3JkIGFzIHN0cmluZywgYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZyk7XG5cbiAgICAgICAgY2FzZSAneGhzX2dldF9ub3RlX2RldGFpbCc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlR2V0Tm90ZURldGFpbChcbiAgICAgICAgICAgIGFyZ3M/LmZlZWRfaWQgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8ueHNlY190b2tlbiBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nXG4gICAgICAgICAgKTtcblxuICAgICAgICBjYXNlICd4aHNfY29tbWVudF9vbl9ub3RlJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVDb21tZW50T25Ob3RlKFxuICAgICAgICAgICAgYXJncz8uZmVlZF9pZCBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy54c2VjX3Rva2VuIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/Lm5vdGUgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZ1xuICAgICAgICAgICk7XG5cbiAgICAgICAgY2FzZSAneGhzX3B1Ymxpc2hfY29udGVudCc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlUHVibGlzaENvbnRlbnQoXG4gICAgICAgICAgICBhcmdzPy50eXBlIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LnRpdGxlIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LmNvbnRlbnQgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8ubWVkaWFfcGF0aHMgYXMgc3RyaW5nW10sXG4gICAgICAgICAgICBhcmdzPy50YWdzIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmdcbiAgICAgICAgICApO1xuXG4gICAgICAgIGNhc2UgJ3hoc19nZXRfdXNlcl9ub3Rlcyc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlR2V0VXNlck5vdGVzKFxuICAgICAgICAgICAgYXJncz8ubGltaXQgYXMgbnVtYmVyLFxuICAgICAgICAgICAgYXJncz8uY3Vyc29yIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmdcbiAgICAgICAgICApO1xuXG4gICAgICAgIGNhc2UgJ3hoc19kZWxldGVfbm90ZSc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlRGVsZXRlTm90ZShcbiAgICAgICAgICAgIGFyZ3M/Lm5vdGVfaWQgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8ubGFzdF9wdWJsaXNoZWQgYXMgYm9vbGVhbixcbiAgICAgICAgICAgIGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmdcbiAgICAgICAgICApO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRvb2w6ICR7bmFtZX1gKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgWEhTRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShlcnJvci50b0pTT04oKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3JlYXRlTWNwRXJyb3JSZXNwb25zZShlcnJvcik7XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIFNoYXJlZCB1dGlsaXRpZXMsIHR5cGVzLCBhbmQgc2VydmljZXMgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuLy8gQ29uZmlndXJhdGlvbiBhbmQgdHlwZXNcbmV4cG9ydCAqIGZyb20gJy4vY29uZmlnJztcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMnO1xuXG4vLyBVdGlsaXRpZXNcbmV4cG9ydCAqIGZyb20gJy4vdXRpbHMnO1xuZXhwb3J0ICogZnJvbSAnLi94aHMudXRpbHMnO1xuZXhwb3J0ICogZnJvbSAnLi9jb29raWVzJztcbmV4cG9ydCAqIGZyb20gJy4vaW1hZ2UtZG93bmxvYWRlcic7XG5leHBvcnQgKiBmcm9tICcuL3RpdGxlLXZhbGlkYXRvcic7XG5cbi8vIEVycm9yIGhhbmRsaW5nIGFuZCBsb2dnaW5nXG5leHBvcnQgKiBmcm9tICcuL2Vycm9ycyc7XG5leHBvcnQgKiBmcm9tICcuL2xvZ2dlcic7XG5cbi8vIEJhc2Ugc2VydmljZVxuZXhwb3J0ICogZnJvbSAnLi9iYXNlLnNlcnZpY2UnO1xuIiwiLyoqXG4gKiBSZXNvdXJjZSByZXF1ZXN0IGhhbmRsZXJzIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9hdXRoL2F1dGguc2VydmljZSc7XG5pbXBvcnQgeyBnZXRDb25maWcsIGdldENvb2tpZXNJbmZvIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2luZGV4JztcblxuZXhwb3J0IGNsYXNzIFJlc291cmNlSGFuZGxlcnMge1xuICBwcml2YXRlIGF1dGhTZXJ2aWNlOiBBdXRoU2VydmljZTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcbiAgICB0aGlzLmF1dGhTZXJ2aWNlID0gbmV3IEF1dGhTZXJ2aWNlKGNvbmZpZyk7XG4gIH1cblxuICBhc3luYyBnZXRDb29raWVzUmVzb3VyY2UoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29va2llc0luZm8gPSBnZXRDb29raWVzSW5mbygpO1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGNvb2tpZXNJbmZvLCBudWxsLCAyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6IFN0cmluZyhlcnJvcikgfSwgbnVsbCwgMik7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0Q29uZmlnUmVzb3VyY2UoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29uZmlnRGljdCA9IGdldENvbmZpZygpO1xuICAgICAgY29uc3QgY29uZmlnV2l0aEZyYW1ld29yayA9IHtcbiAgICAgICAgLi4uY29uZmlnRGljdCxcbiAgICAgICAgZnJhbWV3b3JrOiAnTUNQIFR5cGVTY3JpcHQnLFxuICAgICAgICB2ZXJzaW9uOiBjb25maWdEaWN0LnNlcnZlci52ZXJzaW9uLFxuICAgICAgfTtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShjb25maWdXaXRoRnJhbWV3b3JrLCBudWxsLCAyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6IFN0cmluZyhlcnJvcikgfSwgbnVsbCwgMik7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0U3RhdHVzUmVzb3VyY2UoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICB0cnkge1xuICAgICAgLy8gUXVpY2sgc3RhdHVzIGNoZWNrIChidXQgZG9uJ3QgZmFpbCBpZiBpdCBlcnJvcnMpXG4gICAgICBsZXQgYXV0aFN0YXR1czogYW55ID0geyBzdGF0dXM6ICd1bmtub3duJywgZXJyb3I6ICdTdGF0dXMgY2hlY2sgbm90IHBlcmZvcm1lZCcgfTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF1dGhTdGF0dXMgPSBhd2FpdCB0aGlzLmF1dGhTZXJ2aWNlLmNoZWNrU3RhdHVzKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBhdXRoU3RhdHVzID0geyBzdGF0dXM6ICdlcnJvcicsIGVycm9yOiBTdHJpbmcoZXJyb3IpIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvb2tpZXNJbmZvID0gZ2V0Q29va2llc0luZm8oKTtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuXG4gICAgICBjb25zdCBzdGF0dXNEYXRhID0ge1xuICAgICAgICBzZXJ2ZXI6IHtcbiAgICAgICAgICBzdGF0dXM6ICdydW5uaW5nJyxcbiAgICAgICAgICBuYW1lOiBjb25maWcuc2VydmVyLm5hbWUsXG4gICAgICAgICAgdmVyc2lvbjogY29uZmlnLnNlcnZlci52ZXJzaW9uLFxuICAgICAgICAgIGZyYW1ld29yazogJ01DUCBUeXBlU2NyaXB0JyxcbiAgICAgICAgfSxcbiAgICAgICAgYXV0aGVudGljYXRpb246IGF1dGhTdGF0dXMsXG4gICAgICAgIGNvb2tpZXM6IHtcbiAgICAgICAgICBmaWxlRXhpc3RzOiBjb29raWVzSW5mby5maWxlRXhpc3RzLFxuICAgICAgICAgIGNvb2tpZUNvdW50OiBjb29raWVzSW5mby5jb29raWVDb3VudCxcbiAgICAgICAgfSxcbiAgICAgICAgY2FwYWJpbGl0aWVzOiB7XG4gICAgICAgICAgdG9vbHNBdmFpbGFibGU6IDgsXG4gICAgICAgICAgcHJvbXB0c0F2YWlsYWJsZTogMCxcbiAgICAgICAgICByZXNvdXJjZXNBdmFpbGFibGU6IDMsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc3RhdHVzRGF0YSwgbnVsbCwgMik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAge1xuICAgICAgICAgIHNlcnZlcjogeyBzdGF0dXM6ICdlcnJvcicsIGVycm9yOiBTdHJpbmcoZXJyb3IpIH0sXG4gICAgICAgICAgZnJhbWV3b3JrOiAnTUNQIFR5cGVTY3JpcHQnLFxuICAgICAgICB9LFxuICAgICAgICBudWxsLFxuICAgICAgICAyXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGhhbmRsZVJlc291cmNlUmVxdWVzdCh1cmk6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICBsZXQgY29udGVudDogc3RyaW5nO1xuXG4gICAgICBzd2l0Y2ggKHVyaSkge1xuICAgICAgICBjYXNlICd4aHM6Ly9jb29raWVzJzpcbiAgICAgICAgICBjb250ZW50ID0gYXdhaXQgdGhpcy5nZXRDb29raWVzUmVzb3VyY2UoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICd4aHM6Ly9jb25maWcnOlxuICAgICAgICAgIGNvbnRlbnQgPSBhd2FpdCB0aGlzLmdldENvbmZpZ1Jlc291cmNlKCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAneGhzOi8vc3RhdHVzJzpcbiAgICAgICAgICBjb250ZW50ID0gYXdhaXQgdGhpcy5nZXRTdGF0dXNSZXNvdXJjZSgpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHJlc291cmNlOiAke3VyaX1gKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBtaW1lVHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgdGV4dDogY29udGVudCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBtaW1lVHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoeyBlcnJvcjogU3RyaW5nKGVycm9yKSB9LCBudWxsLCAyKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogVG9vbCBzY2hlbWFzIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgVG9vbFNjaGVtYSB7XG4gIG5hbWU6IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgaW5wdXRTY2hlbWE6IHtcbiAgICB0eXBlOiAnb2JqZWN0JztcbiAgICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgIHJlcXVpcmVkPzogc3RyaW5nW107XG4gIH07XG59XG5cbmV4cG9ydCBjb25zdCBYSFNfVE9PTF9TQ0hFTUFTOiBUb29sU2NoZW1hW10gPSBbXG4gIHtcbiAgICBuYW1lOiAneGhzX2F1dGhfbG9naW4nLFxuICAgIGRlc2NyaXB0aW9uOiAnU3RhcnQgWGlhb0hvbmdTaHUgbG9naW4gcHJvY2Vzcy4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX2F1dGhfbG9nb3V0JyxcbiAgICBkZXNjcmlwdGlvbjogJ0xvZ291dCBmcm9tIFhpYW9Ib25nU2h1IChjbGVhcnMgc2F2ZWQgY29va2llcykuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7fSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19hdXRoX3N0YXR1cycsXG4gICAgZGVzY3JpcHRpb246ICdDaGVjayBYaWFvSG9uZ1NodSBsb2dpbiBzdGF0dXMgKGZhc3QgY2hlY2sgd2l0aCBicm93c2VyKS4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX2Rpc2NvdmVyX2ZlZWRzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0dldCBob21lIHBhZ2UgZmVlZCBsaXN0LicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfc2VhcmNoX25vdGUnLFxuICAgIGRlc2NyaXB0aW9uOiAnU2VhcmNoIGZvciBub3RlcyBieSBrZXl3b3JkLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBrZXl3b3JkOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdTZWFyY2gga2V5d29yZCAocmVxdWlyZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcmVxdWlyZWQ6IFsna2V5d29yZCddLFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX2dldF9ub3RlX2RldGFpbCcsXG4gICAgZGVzY3JpcHRpb246ICdHZXQgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBzcGVjaWZpYyBub3RlLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBmZWVkX2lkOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdGZWVkIElEIChyZXF1aXJlZCknLFxuICAgICAgICB9LFxuICAgICAgICB4c2VjX3Rva2VuOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdTZWN1cml0eSB0b2tlbiBmb3IgdGhlIGZlZWQgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2ZlZWRfaWQnLCAneHNlY190b2tlbiddLFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX2NvbW1lbnRfb25fbm90ZScsXG4gICAgZGVzY3JpcHRpb246ICdDb21tZW50IG9uIGEgbm90ZS4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgZmVlZF9pZDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRmVlZCBJRCAocmVxdWlyZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgeHNlY190b2tlbjoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU2VjdXJpdHkgdG9rZW4gZm9yIHRoZSBmZWVkIChyZXF1aXJlZCknLFxuICAgICAgICB9LFxuICAgICAgICBub3RlOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdDb21tZW50IG5vdGUgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2ZlZWRfaWQnLCAneHNlY190b2tlbicsICdub3RlJ10sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfcHVibGlzaF9jb250ZW50JyxcbiAgICBkZXNjcmlwdGlvbjogJ1B1Ymxpc2ggY29udGVudCB0byBYaWFvSG9uZ1NodSAoc3VwcG9ydHMgYm90aCBpbWFnZXMgYW5kIHZpZGVvcykuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIHR5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBlbnVtOiBbJ2ltYWdlJywgJ3ZpZGVvJ10sXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdDb250ZW50IHR5cGU6IFwiaW1hZ2VcIiBmb3IgaW1hZ2VzLCBcInZpZGVvXCIgZm9yIHZpZGVvcyAocmVxdWlyZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0NvbnRlbnQgdGl0bGUgKHJlcXVpcmVkLCBtYXggMjAgY2hhcmFjdGVycyknLFxuICAgICAgICAgIG1heExlbmd0aDogMjAsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbnRlbnQ6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0NvbnRlbnQgZGVzY3JpcHRpb24gKHJlcXVpcmVkLCBtYXggMTAwMCBjaGFyYWN0ZXJzKScsXG4gICAgICAgICAgbWF4TGVuZ3RoOiAxMDAwLFxuICAgICAgICB9LFxuICAgICAgICBtZWRpYV9wYXRoczoge1xuICAgICAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICAgICAgaXRlbXM6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICdMaXN0IG9mIG1lZGlhIGZpbGUgcGF0aHMgKHJlcXVpcmVkLCBub24tZW1wdHkpLiBGb3IgaW1hZ2VzOiAxLTE4IGltYWdlIGZpbGVzLiBGb3IgdmlkZW9zOiBleGFjdGx5IDEgdmlkZW8gZmlsZS4nLFxuICAgICAgICAgIG1heEl0ZW1zOiAxOCxcbiAgICAgICAgfSxcbiAgICAgICAgdGFnczoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQ29tbWEtc2VwYXJhdGVkIHRhZ3MgKG9wdGlvbmFsKScsXG4gICAgICAgIH0sXG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ3R5cGUnLCAndGl0bGUnLCAnY29udGVudCcsICdtZWRpYV9wYXRocyddLFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX2dldF91c2VyX25vdGVzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0dldCBjdXJyZW50IHVzZXIgbm90ZXMgbGlzdC4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgbGltaXQ6IHtcbiAgICAgICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ051bWJlciBvZiBub3RlcyB0byBmZXRjaCAoZGVmYXVsdDogMjApJyxcbiAgICAgICAgfSxcbiAgICAgICAgY3Vyc29yOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdQYWdpbmF0aW9uIGN1cnNvciBmb3IgbmV4dCBwYWdlJyxcbiAgICAgICAgfSxcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX2RlbGV0ZV9ub3RlJyxcbiAgICBkZXNjcmlwdGlvbjogJ0RlbGV0ZSBhIHVzZXIgbm90ZSBieSBJRCBvciBkZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGUuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIG5vdGVfaWQ6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1NwZWNpZmljIG5vdGUgSUQgdG8gZGVsZXRlIChvcHRpb25hbCBpZiBsYXN0X3B1Ymxpc2hlZCBpcyB0cnVlKScsXG4gICAgICAgIH0sXG4gICAgICAgIGxhc3RfcHVibGlzaGVkOiB7XG4gICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRGVsZXRlIHRoZSBsYXN0IHB1Ymxpc2hlZCBub3RlIChvcHRpb25hbCBpZiBub3RlX2lkIGlzIHByb3ZpZGVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IFhIU19SRVNPVVJDRV9TQ0hFTUFTID0gW1xuICB7XG4gICAgdXJpOiAneGhzOi8vY29va2llcycsXG4gICAgbmFtZTogJ1hIUyBBdXRoZW50aWNhdGlvbiBDb29raWVzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0N1cnJlbnQgWGlhb0hvbmdTaHUgYXV0aGVudGljYXRpb24gY29va2llcyBhbmQgaW5mbycsXG4gICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgfSxcbiAge1xuICAgIHVyaTogJ3hoczovL2NvbmZpZycsXG4gICAgbmFtZTogJ1hIUyBTZXJ2ZXIgQ29uZmlndXJhdGlvbicsXG4gICAgZGVzY3JpcHRpb246ICdYSFMgTUNQIHNlcnZlciBjb25maWd1cmF0aW9uJyxcbiAgICBtaW1lVHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICB9LFxuICB7XG4gICAgdXJpOiAneGhzOi8vc3RhdHVzJyxcbiAgICBuYW1lOiAnWEhTIFNlcnZlciBTdGF0dXMnLFxuICAgIGRlc2NyaXB0aW9uOiAnQ3VycmVudCBzZXJ2ZXIgYW5kIGF1dGhlbnRpY2F0aW9uIHN0YXR1cycsXG4gICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgfSxcbl07XG4iLCIvKipcbiAqIE1DUCBTZXJ2ZXIgZm9yIFhpYW9Ib25nU2h1IE9wZXJhdGlvbnNcbiAqL1xuXG5pbXBvcnQgeyBTZXJ2ZXIgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9pbmRleC5qcyc7XG5pbXBvcnQgeyBTdGRpb1NlcnZlclRyYW5zcG9ydCB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL3N0ZGlvLmpzJztcbmltcG9ydCB7XG4gIENhbGxUb29sUmVxdWVzdFNjaGVtYSxcbiAgTGlzdFRvb2xzUmVxdWVzdFNjaGVtYSxcbiAgTGlzdFJlc291cmNlc1JlcXVlc3RTY2hlbWEsXG4gIFJlYWRSZXNvdXJjZVJlcXVlc3RTY2hlbWEsXG59IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvdHlwZXMuanMnO1xuaW1wb3J0IHsgZ2V0Q29uZmlnIH0gZnJvbSAnLi4vc2hhcmVkL2NvbmZpZyc7XG5pbXBvcnQgeyBUb29sSGFuZGxlcnMgfSBmcm9tICcuL2hhbmRsZXJzL3Rvb2wuaGFuZGxlcnMnO1xuaW1wb3J0IHsgUmVzb3VyY2VIYW5kbGVycyB9IGZyb20gJy4vaGFuZGxlcnMvcmVzb3VyY2UuaGFuZGxlcnMnO1xuaW1wb3J0IHsgWEhTX1RPT0xfU0NIRU1BUywgWEhTX1JFU09VUkNFX1NDSEVNQVMgfSBmcm9tICcuL3NjaGVtYXMvdG9vbC5zY2hlbWFzJztcblxuZXhwb3J0IGNsYXNzIFhIU01DUFNlcnZlciB7XG4gIHByaXZhdGUgc2VydmVyOiBTZXJ2ZXI7XG4gIHByaXZhdGUgdG9vbEhhbmRsZXJzOiBUb29sSGFuZGxlcnM7XG4gIHByaXZhdGUgcmVzb3VyY2VIYW5kbGVyczogUmVzb3VyY2VIYW5kbGVycztcbiAgcHJpdmF0ZSBjb25maWc6IFJldHVyblR5cGU8dHlwZW9mIGdldENvbmZpZz47XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5jb25maWcgPSBnZXRDb25maWcoKTtcbiAgICB0aGlzLnRvb2xIYW5kbGVycyA9IG5ldyBUb29sSGFuZGxlcnMoKTtcbiAgICB0aGlzLnJlc291cmNlSGFuZGxlcnMgPSBuZXcgUmVzb3VyY2VIYW5kbGVycygpO1xuICAgIHRoaXMuc2VydmVyID0gbmV3IFNlcnZlcihcbiAgICAgIHtcbiAgICAgICAgbmFtZTogdGhpcy5jb25maWcuc2VydmVyLm5hbWUsXG4gICAgICAgIHZlcnNpb246IHRoaXMuY29uZmlnLnNlcnZlci52ZXJzaW9uLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgY2FwYWJpbGl0aWVzOiB7XG4gICAgICAgICAgdG9vbHM6IHt9LFxuICAgICAgICAgIHJlc291cmNlczoge30sXG4gICAgICAgIH0sXG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMuc2V0dXBUb29sSGFuZGxlcnMoKTtcbiAgICB0aGlzLnNldHVwUmVzb3VyY2VIYW5kbGVycygpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cFRvb2xIYW5kbGVycygpOiB2b2lkIHtcbiAgICB0aGlzLnNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihDYWxsVG9vbFJlcXVlc3RTY2hlbWEsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICBjb25zdCB7IG5hbWUsIGFyZ3VtZW50czogYXJncyB9ID0gcmVxdWVzdC5wYXJhbXM7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy50b29sSGFuZGxlcnMuaGFuZGxlVG9vbFJlcXVlc3QobmFtZSwgYXJncyk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihMaXN0VG9vbHNSZXF1ZXN0U2NoZW1hLCBhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b29sczogWEhTX1RPT0xfU0NIRU1BUyxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldHVwUmVzb3VyY2VIYW5kbGVycygpOiB2b2lkIHtcbiAgICB0aGlzLnNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihMaXN0UmVzb3VyY2VzUmVxdWVzdFNjaGVtYSwgYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVzb3VyY2VzOiBYSFNfUkVTT1VSQ0VfU0NIRU1BUyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICB0aGlzLnNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihSZWFkUmVzb3VyY2VSZXF1ZXN0U2NoZW1hLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgY29uc3QgeyB1cmkgfSA9IHJlcXVlc3QucGFyYW1zO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVzb3VyY2VIYW5kbGVycy5oYW5kbGVSZXNvdXJjZVJlcXVlc3QodXJpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRyYW5zcG9ydCA9IG5ldyBTdGRpb1NlcnZlclRyYW5zcG9ydCgpO1xuICAgIGF3YWl0IHRoaXMuc2VydmVyLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICAvLyBEb24ndCBsb2cgdG8gc3RkZXJyIGluIHN0ZGlvIG1vZGUgdG8gYXZvaWQgaW50ZXJmZXJpbmcgd2l0aCBNQ1AgcHJvdG9jb2xcbiAgfVxufVxuIiwiY29uc3QgX19XRUJQQUNLX05BTUVTUEFDRV9PQkpFQ1RfXyA9IHJlcXVpcmUoXCJleHByZXNzXCIpOyIsImNvbnN0IF9fV0VCUEFDS19OQU1FU1BBQ0VfT0JKRUNUX18gPSByZXF1aXJlKFwiY29yc1wiKTsiLCIvKipcbiAqIEhUVFAgU2VydmVyIHdpdGggU1NFIGFuZCBTdHJlYW1hYmxlIEhUVFAgVHJhbnNwb3J0IFN1cHBvcnRcbiAqL1xuXG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBjb3JzIGZyb20gJ2NvcnMnO1xuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ25vZGU6Y3J5cHRvJztcbmltcG9ydCB7IFNlcnZlciB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL2luZGV4LmpzJztcbmltcG9ydCB7IFNTRVNlcnZlclRyYW5zcG9ydCB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL3NzZS5qcyc7XG5pbXBvcnQgeyBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydCB9IGZyb20gJ0Btb2RlbGNvbnRleHRwcm90b2NvbC9zZGsvc2VydmVyL3N0cmVhbWFibGVIdHRwLmpzJztcbmltcG9ydCB7IGlzSW5pdGlhbGl6ZVJlcXVlc3QgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3R5cGVzLmpzJztcbmltcG9ydCB7IGdldENvbmZpZyB9IGZyb20gJy4uL3NoYXJlZC9jb25maWcnO1xuaW1wb3J0IHsgVG9vbEhhbmRsZXJzIH0gZnJvbSAnLi9oYW5kbGVycy90b29sLmhhbmRsZXJzJztcbmltcG9ydCB7IFJlc291cmNlSGFuZGxlcnMgfSBmcm9tICcuL2hhbmRsZXJzL3Jlc291cmNlLmhhbmRsZXJzJztcbmltcG9ydCB7IFhIU19UT09MX1NDSEVNQVMsIFhIU19SRVNPVVJDRV9TQ0hFTUFTIH0gZnJvbSAnLi9zY2hlbWFzL3Rvb2wuc2NoZW1hcyc7XG5pbXBvcnQge1xuICBDYWxsVG9vbFJlcXVlc3RTY2hlbWEsXG4gIExpc3RUb29sc1JlcXVlc3RTY2hlbWEsXG4gIExpc3RSZXNvdXJjZXNSZXF1ZXN0U2NoZW1hLFxuICBSZWFkUmVzb3VyY2VSZXF1ZXN0U2NoZW1hLFxufSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3R5cGVzLmpzJztcblxuZXhwb3J0IGNsYXNzIFhIU0hUVFBNQ1BTZXJ2ZXIge1xuICBwcml2YXRlIGFwcDogZXhwcmVzcy5BcHBsaWNhdGlvbjtcbiAgcHJpdmF0ZSBjb25maWc6IFJldHVyblR5cGU8dHlwZW9mIGdldENvbmZpZz47XG4gIHByaXZhdGUgdG9vbEhhbmRsZXJzOiBUb29sSGFuZGxlcnM7XG4gIHByaXZhdGUgcmVzb3VyY2VIYW5kbGVyczogUmVzb3VyY2VIYW5kbGVycztcbiAgcHJpdmF0ZSB0cmFuc3BvcnRzOiBNYXA8c3RyaW5nLCBTU0VTZXJ2ZXJUcmFuc3BvcnQgfCBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydD4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgcG9ydDogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHBvcnQ6IG51bWJlciA9IDMwMDApIHtcbiAgICB0aGlzLnBvcnQgPSBwb3J0O1xuICAgIHRoaXMuY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy50b29sSGFuZGxlcnMgPSBuZXcgVG9vbEhhbmRsZXJzKCk7XG4gICAgdGhpcy5yZXNvdXJjZUhhbmRsZXJzID0gbmV3IFJlc291cmNlSGFuZGxlcnMoKTtcbiAgICB0aGlzLmFwcCA9IGV4cHJlc3MoKTtcblxuICAgIHRoaXMuc2V0dXBNaWRkbGV3YXJlKCk7XG4gICAgdGhpcy5zZXR1cFJvdXRlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cE1pZGRsZXdhcmUoKTogdm9pZCB7XG4gICAgLy8gUGFyc2UgSlNPTiBib2RpZXNcbiAgICB0aGlzLmFwcC51c2UoZXhwcmVzcy5qc29uKCkpO1xuXG4gICAgLy8gQ29uZmlndXJlIENPUlMgdG8gZXhwb3NlIE1jcC1TZXNzaW9uLUlkIGhlYWRlciBmb3IgYnJvd3Nlci1iYXNlZCBjbGllbnRzXG4gICAgdGhpcy5hcHAudXNlKFxuICAgICAgY29ycyh7XG4gICAgICAgIG9yaWdpbjogJyonLCAvLyBBbGxvdyBhbGwgb3JpZ2lucyAtIGFkanVzdCBhcyBuZWVkZWQgZm9yIHByb2R1Y3Rpb25cbiAgICAgICAgZXhwb3NlZEhlYWRlcnM6IFsnTWNwLVNlc3Npb24tSWQnXSxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBSb3V0ZXMoKTogdm9pZCB7XG4gICAgLy8gU3RyZWFtYWJsZSBIVFRQIFRyYW5zcG9ydCAoUHJvdG9jb2wgdmVyc2lvbiAyMDI1LTAzLTI2KVxuICAgIHRoaXMuYXBwLmFsbCgnL21jcCcsIHRoaXMuaGFuZGxlU3RyZWFtYWJsZUhUVFAuYmluZCh0aGlzKSk7XG5cbiAgICAvLyBEZXByZWNhdGVkIEhUVFArU1NFIFRyYW5zcG9ydCAoUHJvdG9jb2wgdmVyc2lvbiAyMDI0LTExLTA1KVxuICAgIHRoaXMuYXBwLmdldCgnL3NzZScsIHRoaXMuaGFuZGxlU1NFQ29ubmVjdGlvbi5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLmFwcC5wb3N0KCcvbWVzc2FnZXMnLCB0aGlzLmhhbmRsZVNTRU1lc3NhZ2UuYmluZCh0aGlzKSk7XG5cbiAgICAvLyBIZWFsdGggY2hlY2sgZW5kcG9pbnRcbiAgICB0aGlzLmFwcC5nZXQoJy9oZWFsdGgnLCAocmVxLCByZXMpID0+IHtcbiAgICAgIHJlcy5qc29uKHtcbiAgICAgICAgc3RhdHVzOiAnaGVhbHRoeScsXG4gICAgICAgIHNlcnZlcjogdGhpcy5jb25maWcuc2VydmVyLm5hbWUsXG4gICAgICAgIHZlcnNpb246IHRoaXMuY29uZmlnLnNlcnZlci52ZXJzaW9uLFxuICAgICAgICB0cmFuc3BvcnRzOiBbJ3N0cmVhbWFibGUtaHR0cCcsICdzc2UnXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVTdHJlYW1hYmxlSFRUUChyZXE6IGV4cHJlc3MuUmVxdWVzdCwgcmVzOiBleHByZXNzLlJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc29sZS5sb2coYFJlY2VpdmVkICR7cmVxLm1ldGhvZH0gcmVxdWVzdCB0byAvbWNwYCk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gQ2hlY2sgZm9yIGV4aXN0aW5nIHNlc3Npb24gSURcbiAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHJlcS5oZWFkZXJzWydtY3Atc2Vzc2lvbi1pZCddIGFzIHN0cmluZztcbiAgICAgIGxldCB0cmFuc3BvcnQ6IFN0cmVhbWFibGVIVFRQU2VydmVyVHJhbnNwb3J0IHwgdW5kZWZpbmVkO1xuXG4gICAgICBpZiAoc2Vzc2lvbklkICYmIHRoaXMudHJhbnNwb3J0cy5oYXMoc2Vzc2lvbklkKSkge1xuICAgICAgICBjb25zdCBleGlzdGluZ1RyYW5zcG9ydCA9IHRoaXMudHJhbnNwb3J0cy5nZXQoc2Vzc2lvbklkKTtcbiAgICAgICAgaWYgKGV4aXN0aW5nVHJhbnNwb3J0IGluc3RhbmNlb2YgU3RyZWFtYWJsZUhUVFBTZXJ2ZXJUcmFuc3BvcnQpIHtcbiAgICAgICAgICB0cmFuc3BvcnQgPSBleGlzdGluZ1RyYW5zcG9ydDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMuc3RhdHVzKDQwMCkuanNvbih7XG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICAgIGNvZGU6IC0zMjAwMCxcbiAgICAgICAgICAgICAgbWVzc2FnZTogJ0JhZCBSZXF1ZXN0OiBTZXNzaW9uIGV4aXN0cyBidXQgdXNlcyBhIGRpZmZlcmVudCB0cmFuc3BvcnQgcHJvdG9jb2wnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghc2Vzc2lvbklkICYmIHJlcS5tZXRob2QgPT09ICdQT1NUJyAmJiBpc0luaXRpYWxpemVSZXF1ZXN0KHJlcS5ib2R5KSkge1xuICAgICAgICAvLyBDcmVhdGUgbmV3IFN0cmVhbWFibGUgSFRUUCB0cmFuc3BvcnRcbiAgICAgICAgdHJhbnNwb3J0ID0gbmV3IFN0cmVhbWFibGVIVFRQU2VydmVyVHJhbnNwb3J0KHtcbiAgICAgICAgICBzZXNzaW9uSWRHZW5lcmF0b3I6ICgpOiBzdHJpbmcgPT4gcmFuZG9tVVVJRCgpLFxuICAgICAgICAgIG9uc2Vzc2lvbmluaXRpYWxpemVkOiAoc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBTdHJlYW1hYmxlSFRUUCBzZXNzaW9uIGluaXRpYWxpemVkIHdpdGggSUQ6ICR7c2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgdGhpcy50cmFuc3BvcnRzLnNldChzZXNzaW9uSWQsIHRyYW5zcG9ydCEpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgb25zZXNzaW9uY2xvc2VkOiAoc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBTdHJlYW1hYmxlSFRUUCBzZXNzaW9uIGNsb3NlZDogJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICB0aGlzLnRyYW5zcG9ydHMuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIG9uY2xvc2UgaGFuZGxlciB0byBjbGVhbiB1cCB0cmFuc3BvcnQgd2hlbiBjbG9zZWRcbiAgICAgICAgdHJhbnNwb3J0Lm9uY2xvc2UgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgY29uc3Qgc2lkID0gdHJhbnNwb3J0IS5zZXNzaW9uSWQ7XG4gICAgICAgICAgaWYgKHNpZCAmJiB0aGlzLnRyYW5zcG9ydHMuaGFzKHNpZCkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBUcmFuc3BvcnQgY2xvc2VkIGZvciBzZXNzaW9uICR7c2lkfSwgcmVtb3ZpbmcgZnJvbSB0cmFuc3BvcnRzIG1hcGApO1xuICAgICAgICAgICAgdGhpcy50cmFuc3BvcnRzLmRlbGV0ZShzaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBDb25uZWN0IHRoZSB0cmFuc3BvcnQgdG8gdGhlIE1DUCBzZXJ2ZXJcbiAgICAgICAgY29uc3Qgc2VydmVyID0gdGhpcy5jcmVhdGVNQ1BTZXJ2ZXIoKTtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEludmFsaWQgcmVxdWVzdCAtIG5vIHNlc3Npb24gSUQgb3Igbm90IGluaXRpYWxpemF0aW9uIHJlcXVlc3RcbiAgICAgICAgcmVzLnN0YXR1cyg0MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzIwMDAsXG4gICAgICAgICAgICBtZXNzYWdlOiAnQmFkIFJlcXVlc3Q6IE5vIHZhbGlkIHNlc3Npb24gSUQgcHJvdmlkZWQnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSB0aGUgcmVxdWVzdCB3aXRoIHRoZSB0cmFuc3BvcnRcbiAgICAgIGF3YWl0IHRyYW5zcG9ydC5oYW5kbGVSZXF1ZXN0KHJlcSwgcmVzLCByZXEuYm9keSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGhhbmRsaW5nIFN0cmVhbWFibGUgSFRUUCByZXF1ZXN0OicsIGVycm9yKTtcbiAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHtcbiAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgY29kZTogLTMyNjAzLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0ludGVybmFsIHNlcnZlciBlcnJvcicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpZDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVTU0VDb25uZWN0aW9uKHJlcTogZXhwcmVzcy5SZXF1ZXN0LCByZXM6IGV4cHJlc3MuUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zb2xlLmxvZygnUmVjZWl2ZWQgR0VUIHJlcXVlc3QgdG8gL3NzZSAoZGVwcmVjYXRlZCBTU0UgdHJhbnNwb3J0KScpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRyYW5zcG9ydCA9IG5ldyBTU0VTZXJ2ZXJUcmFuc3BvcnQoJy9tZXNzYWdlcycsIHJlcyk7XG4gICAgICB0aGlzLnRyYW5zcG9ydHMuc2V0KHRyYW5zcG9ydC5zZXNzaW9uSWQsIHRyYW5zcG9ydCk7XG5cbiAgICAgIHJlcy5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0cy5kZWxldGUodHJhbnNwb3J0LnNlc3Npb25JZCk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc2VydmVyID0gdGhpcy5jcmVhdGVNQ1BTZXJ2ZXIoKTtcbiAgICAgIGF3YWl0IHNlcnZlci5jb25uZWN0KHRyYW5zcG9ydCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGhhbmRsaW5nIFNTRSBjb25uZWN0aW9uOicsIGVycm9yKTtcbiAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNTAwKS5qc29uKHtcbiAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgY29kZTogLTMyNjAzLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0ludGVybmFsIHNlcnZlciBlcnJvcicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpZDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVTU0VNZXNzYWdlKHJlcTogZXhwcmVzcy5SZXF1ZXN0LCByZXM6IGV4cHJlc3MuUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzZXNzaW9uSWQgPSByZXEucXVlcnkuc2Vzc2lvbklkIGFzIHN0cmluZztcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0cmFuc3BvcnQgPSB0aGlzLnRyYW5zcG9ydHMuZ2V0KHNlc3Npb25JZCk7XG5cbiAgICAgIGlmICghdHJhbnNwb3J0IHx8ICEodHJhbnNwb3J0IGluc3RhbmNlb2YgU1NFU2VydmVyVHJhbnNwb3J0KSkge1xuICAgICAgICByZXMuc3RhdHVzKDQwMCkuanNvbih7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgIGNvZGU6IC0zMjAwMCxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdCYWQgUmVxdWVzdDogU2Vzc2lvbiBleGlzdHMgYnV0IHVzZXMgYSBkaWZmZXJlbnQgdHJhbnNwb3J0IHByb3RvY29sJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCB0cmFuc3BvcnQuaGFuZGxlUG9zdE1lc3NhZ2UocmVxLCByZXMsIHJlcS5ib2R5KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaGFuZGxpbmcgU1NFIG1lc3NhZ2U6JywgZXJyb3IpO1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzI2MDMsXG4gICAgICAgICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU1DUFNlcnZlcigpOiBTZXJ2ZXIge1xuICAgIGNvbnN0IHNlcnZlciA9IG5ldyBTZXJ2ZXIoXG4gICAgICB7XG4gICAgICAgIG5hbWU6IHRoaXMuY29uZmlnLnNlcnZlci5uYW1lLFxuICAgICAgICB2ZXJzaW9uOiB0aGlzLmNvbmZpZy5zZXJ2ZXIudmVyc2lvbixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIHRvb2xzOiB7fSxcbiAgICAgICAgICByZXNvdXJjZXM6IHt9LFxuICAgICAgICB9LFxuICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBTZXR1cCB0b29sIGhhbmRsZXJzXG4gICAgc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKENhbGxUb29sUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgIGNvbnN0IHsgbmFtZSwgYXJndW1lbnRzOiBhcmdzIH0gPSByZXF1ZXN0LnBhcmFtcztcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnRvb2xIYW5kbGVycy5oYW5kbGVUb29sUmVxdWVzdChuYW1lLCBhcmdzKTtcbiAgICB9KTtcblxuICAgIHNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihMaXN0VG9vbHNSZXF1ZXN0U2NoZW1hLCBhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b29sczogWEhTX1RPT0xfU0NIRU1BUyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBTZXR1cCByZXNvdXJjZSBoYW5kbGVyc1xuICAgIHNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihMaXN0UmVzb3VyY2VzUmVxdWVzdFNjaGVtYSwgYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVzb3VyY2VzOiBYSFNfUkVTT1VSQ0VfU0NIRU1BUyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBzZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoUmVhZFJlc291cmNlUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgIGNvbnN0IHsgdXJpIH0gPSByZXF1ZXN0LnBhcmFtcztcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlc291cmNlSGFuZGxlcnMuaGFuZGxlUmVzb3VyY2VSZXF1ZXN0KHVyaSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2VydmVyO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHNlcnZlciA9IHRoaXMuYXBwLmxpc3Rlbih0aGlzLnBvcnQsIChlcnJvcj86IEVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBzdGFydCBIVFRQIHNlcnZlcjonLCBlcnJvcik7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmxvZyhgWEhTIE1DUCBIVFRQIFNlcnZlciBsaXN0ZW5pbmcgb24gcG9ydCAke3RoaXMucG9ydH1gKTtcbiAgICAgICAgY29uc29sZS5sb2coYFxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuU1VQUE9SVEVEIFRSQU5TUE9SVCBPUFRJT05TOlxuXG4xLiBTdHJlYW1hYmxlIEhUVFAgKFByb3RvY29sIHZlcnNpb246IDIwMjUtMDMtMjYpXG4gICBFbmRwb2ludDogL21jcFxuICAgTWV0aG9kczogR0VULCBQT1NULCBERUxFVEVcbiAgIFVzYWdlOlxuICAgICAtIEluaXRpYWxpemUgd2l0aCBQT1NUIHRvIC9tY3BcbiAgICAgLSBFc3RhYmxpc2ggU1NFIHN0cmVhbSB3aXRoIEdFVCB0byAvbWNwXG4gICAgIC0gU2VuZCByZXF1ZXN0cyB3aXRoIFBPU1QgdG8gL21jcFxuICAgICAtIFRlcm1pbmF0ZSBzZXNzaW9uIHdpdGggREVMRVRFIHRvIC9tY3BcblxuMi4gSFRUUCArIFNTRSAoUHJvdG9jb2wgdmVyc2lvbjogMjAyNC0xMS0wNSlcbiAgIEVuZHBvaW50czogL3NzZSAoR0VUKSBhbmQgL21lc3NhZ2VzIChQT1NUKVxuICAgVXNhZ2U6XG4gICAgIC0gRXN0YWJsaXNoIFNTRSBzdHJlYW0gd2l0aCBHRVQgdG8gL3NzZVxuICAgICAtIFNlbmQgcmVxdWVzdHMgd2l0aCBQT1NUIHRvIC9tZXNzYWdlcz9zZXNzaW9uSWQ9PGlkPlxuXG4zLiBIZWFsdGggQ2hlY2tcbiAgIEVuZHBvaW50OiAvaGVhbHRoXG4gICBNZXRob2Q6IEdFVFxuICAgVXNhZ2U6IENoZWNrIHNlcnZlciBzdGF0dXMgYW5kIHN1cHBvcnRlZCB0cmFuc3BvcnRzXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5gKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEhhbmRsZSBzZXJ2ZXIgc2h1dGRvd25cbiAgICAgIHByb2Nlc3Mub24oJ1NJR0lOVCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coJ1NodXR0aW5nIGRvd24gSFRUUCBzZXJ2ZXIuLi4nKTtcblxuICAgICAgICAvLyBDbG9zZSBhbGwgYWN0aXZlIHRyYW5zcG9ydHMgdG8gcHJvcGVybHkgY2xlYW4gdXAgcmVzb3VyY2VzXG4gICAgICAgIGZvciAoY29uc3QgW3Nlc3Npb25JZCwgdHJhbnNwb3J0XSBvZiB0aGlzLnRyYW5zcG9ydHMpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYENsb3NpbmcgdHJhbnNwb3J0IGZvciBzZXNzaW9uICR7c2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgYXdhaXQgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGNsb3NpbmcgdHJhbnNwb3J0IGZvciBzZXNzaW9uICR7c2Vzc2lvbklkfTpgLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy50cmFuc3BvcnRzLmNsZWFyKCk7XG4gICAgICAgIHNlcnZlci5jbG9zZSgoKSA9PiB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ0hUVFAgc2VydmVyIHNodXRkb3duIGNvbXBsZXRlJyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBwcm9jZXNzLm9uKCdTSUdURVJNJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnU2h1dHRpbmcgZG93biBIVFRQIHNlcnZlci4uLicpO1xuXG4gICAgICAgIC8vIENsb3NlIGFsbCBhY3RpdmUgdHJhbnNwb3J0cyB0byBwcm9wZXJseSBjbGVhbiB1cCByZXNvdXJjZXNcbiAgICAgICAgZm9yIChjb25zdCBbc2Vzc2lvbklkLCB0cmFuc3BvcnRdIG9mIHRoaXMudHJhbnNwb3J0cykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgQ2xvc2luZyB0cmFuc3BvcnQgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICBhd2FpdCB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgY2xvc2luZyB0cmFuc3BvcnQgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9OmAsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRyYW5zcG9ydHMuY2xlYXIoKTtcbiAgICAgICAgc2VydmVyLmNsb3NlKCgpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnSFRUUCBzZXJ2ZXIgc2h1dGRvd24gY29tcGxldGUnKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIENsb3NlIGFsbCBhY3RpdmUgdHJhbnNwb3J0c1xuICAgIGZvciAoY29uc3QgW3Nlc3Npb25JZCwgdHJhbnNwb3J0XSBvZiB0aGlzLnRyYW5zcG9ydHMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRyYW5zcG9ydC5jbG9zZSgpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgY2xvc2luZyB0cmFuc3BvcnQgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9OmAsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy50cmFuc3BvcnRzLmNsZWFyKCk7XG4gIH1cbn1cbiIsIi8qKlxuICogUmVxdWVzdCBoYW5kbGVycyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL3Rvb2wuaGFuZGxlcnMnO1xuZXhwb3J0ICogZnJvbSAnLi9yZXNvdXJjZS5oYW5kbGVycyc7XG4iLCIvKipcbiAqIFNlcnZlciBpbXBsZW1lbnRhdGlvbiBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL21jcC5zZXJ2ZXInO1xuZXhwb3J0ICogZnJvbSAnLi9odHRwLnNlcnZlcic7XG5leHBvcnQgKiBmcm9tICcuL2hhbmRsZXJzL2luZGV4JztcbiIsIiMhL3Vzci9iaW4vZW52IG5vZGVcblxuLyoqXG4gKiBVbmlmaWVkIENMSSBmb3IgWGlhb0hvbmdTaHUgb3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IHsgZ2V0Q29uZmlnIH0gZnJvbSAnLi4vc2hhcmVkL2NvbmZpZyc7XG5pbXBvcnQgeyBBdXRoU2VydmljZSB9IGZyb20gJy4uL2NvcmUvYXV0aC9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHB1cHBldGVlciBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgc3Bhd25TeW5jIH0gZnJvbSAnbm9kZTpjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB7IFhIU01DUFNlcnZlciwgWEhTSFRUUE1DUFNlcnZlciB9IGZyb20gJy4uL3NlcnZlci9pbmRleCc7XG5pbXBvcnQgeyBYSFNfVE9PTF9TQ0hFTUFTIH0gZnJvbSAnLi4vc2VydmVyL3NjaGVtYXMvdG9vbC5zY2hlbWFzJztcbmltcG9ydCB7IEZlZWRTZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9mZWVkcy9mZWVkLnNlcnZpY2UnO1xuaW1wb3J0IHsgUHVibGlzaFNlcnZpY2UgfSBmcm9tICcuLi9jb3JlL3B1Ymxpc2hpbmcvcHVibGlzaC5zZXJ2aWNlJztcbmltcG9ydCB7IE5vdGVTZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9ub3Rlcy9ub3RlLnNlcnZpY2UnO1xuXG4vKipcbiAqIENMSSB1dGlsaXR5IGZ1bmN0aW9uc1xuICovXG5jbGFzcyBDTElVdGlscyB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcHJvZ3JhbTogQ29tbWFuZCkge31cblxuICBmb3JtYXRFcnJvck1lc3NhZ2UoZXJyb3I6IHVua25vd24pOiBzdHJpbmcge1xuICAgIGNvbnN0IHJhdyA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyAoZXJyb3Iuc3RhY2sgPz8gZXJyb3IubWVzc2FnZSkgOiBTdHJpbmcoZXJyb3IpO1xuXG4gICAgLy8gSGFuZGxlIHNwZWNpZmljIGVycm9yIHBhdHRlcm5zXG4gICAgaWYgKC9FeGVjdXRhYmxlIGRvZXNuJ3QgZXhpc3R8cHVwcGV0ZWVyIGJyb3dzZXJzIGluc3RhbGwvaS50ZXN0KHJhdykpIHtcbiAgICAgIHJldHVybiAnQ2hyb21pdW0gaXMgbm90IGluc3RhbGxlZC4gUnVuOiBucHggcHVwcGV0ZWVyIGJyb3dzZXJzIGluc3RhbGwgY2hyb21lIG9yIHhocy1tY3AgYnJvd3Nlcic7XG4gICAgfVxuXG4gICAgLy8gRm9yIHVzZXItZmFjaW5nIGVycm9ycywganVzdCByZXR1cm4gdGhlIG1lc3NhZ2Ugd2l0aG91dCBzdGFjayB0cmFjZVxuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAvLyBDaGVjayBpZiBpdCdzIGEga25vd24gZXJyb3IgdHlwZSB0aGF0IHNob3VsZCBzaG93IGp1c3QgdGhlIG1lc3NhZ2VcbiAgICAgIGlmIChcbiAgICAgICAgZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnRWl0aGVyIC0tbm90ZS1pZCBvciAtLWxhc3QtcHVibGlzaGVkIG11c3QgYmUgc3BlY2lmaWVkJykgfHxcbiAgICAgICAgZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnUGxlYXNlIHNwZWNpZnkgZWl0aGVyJykgfHxcbiAgICAgICAgZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnVXNlciBub3QgbG9nZ2VkIGluJykgfHxcbiAgICAgICAgZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnTm90ZSBub3QgZm91bmQnKSB8fFxuICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKCdEZWxldGUgYnV0dG9uIG5vdCBmb3VuZCcpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIGVycm9yLm1lc3NhZ2U7XG4gICAgICB9XG5cbiAgICAgIC8vIEZvciBvdGhlciBlcnJvcnMsIHNob3cgYSBjbGVhbmVyIHZlcnNpb25cbiAgICAgIGNvbnN0IGNvbmRlbnNlZCA9IHJhd1xuICAgICAgICAucmVwbGFjZShcbiAgICAgICAgICAvW1xcc1xcU10qP0xvb2tzIGxpa2UgUHVwcGV0ZWVyW1xcc1xcU10qP1BsZWFzZSBydW4gdGhlIGZvbGxvd2luZyBjb21tYW5kIHRvIGRvd25sb2FkIG5ldyBicm93c2VyczpbXFxzXFxTXSo/bnB4IHB1cHBldGVlciBicm93c2VycyBpbnN0YWxsW1xcc1xcU10qPyhQdXBwZXRlZXIgVGVhbVtcXHNcXFNdKj8pKj8vbSxcbiAgICAgICAgICAnJ1xuICAgICAgICApXG4gICAgICAgIC5yZXBsYWNlKC9bXFx1MjUwMC1cXHUyNTdGXSsvZywgJycpIC8vIGJveC1kcmF3aW5nIGNoYXJhY3RlcnNcbiAgICAgICAgLnJlcGxhY2UoL1xccythdFxccysuKiQvZ20sICcnKSAvLyBSZW1vdmUgc3RhY2sgdHJhY2UgbGluZXNcbiAgICAgICAgLnRyaW0oKTtcblxuICAgICAgcmV0dXJuIGNvbmRlbnNlZCB8fCBlcnJvci5tZXNzYWdlO1xuICAgIH1cblxuICAgIHJldHVybiBTdHJpbmcoZXJyb3IpO1xuICB9XG5cbiAgd3JpdGVKc29uKG91dHB1dDogdW5rbm93biwgZXhpdENvZGUgPSAwKTogdm9pZCB7XG4gICAgY29uc3QgY29tcGFjdCA9IHRoaXMucHJvZ3JhbS5nZXRPcHRpb25WYWx1ZT8uKCdjb21wYWN0JykgPT09IHRydWU7XG4gICAgY29uc3QganNvbiA9IGNvbXBhY3QgPyBKU09OLnN0cmluZ2lmeShvdXRwdXQpIDogSlNPTi5zdHJpbmdpZnkob3V0cHV0LCBudWxsLCAyKTtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShgJHtqc29ufVxcbmApO1xuICAgIHByb2Nlc3MuZXhpdChleGl0Q29kZSk7XG4gIH1cblxuICBwcmludFN1Y2Nlc3MocmVzdWx0OiB1bmtub3duLCBtZXNzYWdlPzogc3RyaW5nKTogdm9pZCB7XG4gICAgLy8gSWYgcmVzdWx0IGFscmVhZHkgaGFzIHN1Y2Nlc3MgZmllbGQsIHByaW50IGl0IGRpcmVjdGx5XG4gICAgaWYgKHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0ID09PSAnb2JqZWN0JyAmJiAnc3VjY2VzcycgaW4gcmVzdWx0KSB7XG4gICAgICB0aGlzLndyaXRlSnNvbihyZXN1bHQsIDApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBPdGhlcndpc2UsIHdyYXAgaXRcbiAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UgPz8gKHJlc3VsdCBhcyB7IG1lc3NhZ2U/OiBzdHJpbmcgfSk/Lm1lc3NhZ2UgPz8gdW5kZWZpbmVkLFxuICAgICAgICBkYXRhOiByZXN1bHQsXG4gICAgICB9O1xuICAgICAgdGhpcy53cml0ZUpzb24ocGF5bG9hZCwgMCk7XG4gICAgfVxuICB9XG5cbiAgcHJpbnRFcnJvcihlcnJvcjogdW5rbm93biwgY29kZT86IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLmZvcm1hdEVycm9yTWVzc2FnZShlcnJvcik7XG4gICAgY29uc3QgcGF5bG9hZCA9IHsgc3VjY2VzczogZmFsc2UsIG1lc3NhZ2UsIGNvZGU6IGNvZGUgPz8gdW5kZWZpbmVkLCBzdGF0dXM6ICdlcnJvcicgfSBhcyBjb25zdDtcbiAgICB0aGlzLndyaXRlSnNvbihwYXlsb2FkLCAxKTtcbiAgfVxuXG4gIHByaW50VXNhZ2VFcnJvcihjb21tYW5kOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICB1c2FnZTogYFVzZSAneGhzLW1jcCAke2NvbW1hbmR9IC0taGVscCcgZm9yIG1vcmUgaW5mb3JtYXRpb25gLFxuICAgIH0gYXMgY29uc3Q7XG4gICAgdGhpcy53cml0ZUpzb24ocGF5bG9hZCwgMSk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gbWFpbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gIGNvbnN0IHByb2dyYW0gPSBuZXcgQ29tbWFuZCgpO1xuICBjb25zdCB1dGlscyA9IG5ldyBDTElVdGlscyhwcm9ncmFtKTtcblxuICBwcm9ncmFtXG4gICAgLm5hbWUoJ3hocy1tY3AnKVxuICAgIC5kZXNjcmlwdGlvbignWGlhb0hvbmdTaHUgQ0xJIHdpdGggc3ViY29tbWFuZHMnKVxuICAgIC5vcHRpb24oJy0tY29tcGFjdCcsICdPdXRwdXQgY29tcGFjdCBvbmUtbGluZSBKU09OIChubyBwcmV0dHkgcHJpbnQpJylcbiAgICAuc2hvd0hlbHBBZnRlckVycm9yKCk7XG5cbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCdsb2dpbicpXG4gICAgLmRlc2NyaXB0aW9uKCdTdGFydCBYaWFvSG9uZ1NodSBsb2dpbiBmbG93IChvcGVucyBicm93c2VyLCBzYXZlcyBjb29raWVzKScpXG4gICAgLm9wdGlvbignLXQsIC0tdGltZW91dCA8c2Vjb25kcz4nLCAnTG9naW4gdGltZW91dCBpbiBzZWNvbmRzJywgYCR7Y29uZmlnLmJyb3dzZXIubG9naW5UaW1lb3V0fWApXG4gICAgLmFjdGlvbihhc3luYyAob3B0czogeyB0aW1lb3V0Pzogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IGJyb3dzZXJQYXRoID0gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgdGltZW91dFNlYyA9IG9wdHMudGltZW91dCA/IHBhcnNlSW50KG9wdHMudGltZW91dCwgMTApIDogY29uZmlnLmJyb3dzZXIubG9naW5UaW1lb3V0O1xuICAgICAgY29uc3QgYXV0aFNlcnZpY2UgPSBuZXcgQXV0aFNlcnZpY2UoY29uZmlnKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGF1dGhTZXJ2aWNlLmxvZ2luKGJyb3dzZXJQYXRoLCB0aW1lb3V0U2VjKTtcbiAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ2xvZ291dCcpXG4gICAgLmRlc2NyaXB0aW9uKCdMb2dvdXQgZnJvbSBYaWFvSG9uZ1NodSBhbmQgY2xlYXIgc2F2ZWQgY29va2llcycpXG4gICAgLmFjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBhdXRoU2VydmljZSA9IG5ldyBBdXRoU2VydmljZShjb25maWcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXV0aFNlcnZpY2UubG9nb3V0KCk7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhyZXN1bHQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCdzdGF0dXMnKVxuICAgIC5kZXNjcmlwdGlvbignQ2hlY2sgY3VycmVudCBYaWFvSG9uZ1NodSBsb2dpbiBzdGF0dXMnKVxuICAgIC5hY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYnJvd3NlclBhdGggPSB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBhdXRoU2VydmljZSA9IG5ldyBBdXRoU2VydmljZShjb25maWcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXV0aFNlcnZpY2UuY2hlY2tTdGF0dXMoYnJvd3NlclBhdGgpO1xuICAgICAgICB1dGlscy5wcmludFN1Y2Nlc3MocmVzdWx0KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHV0aWxzLnByaW50RXJyb3IoZXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnYnJvd3NlcicpXG4gICAgLmRlc2NyaXB0aW9uKCdFbnN1cmUgUHVwcGV0ZWVyIENocm9taXVtIGlzIGluc3RhbGxlZCBhbmQgbGF1bmNoYWJsZTsgaW5zdGFsbHMgaWYgbWlzc2luZycpXG4gICAgLm9wdGlvbignLS13aXRoLWRlcHMnLCAnSW5zdGFsbCBPUy1sZXZlbCBkZXBlbmRlbmNpZXMgYXMgd2VsbCAobWF5IHJlcXVpcmUgc3VkbyknKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdHM6IHsgd2l0aERlcHM/OiBib29sZWFuIH0pID0+IHtcbiAgICAgIGFzeW5jIGZ1bmN0aW9uIGNhbkxhdW5jaENocm9taXVtKCk6IFByb21pc2U8eyBjYW5MYXVuY2g6IGJvb2xlYW47IGV4ZWN1dGFibGVQYXRoPzogc3RyaW5nIH0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBHZXQgdGhlIGV4ZWN1dGFibGUgcGF0aCBiZWZvcmUgbGF1bmNoaW5nXG4gICAgICAgICAgY29uc3QgZXhlY3V0YWJsZVBhdGggPSBwdXBwZXRlZXIuZXhlY3V0YWJsZVBhdGgoKTtcblxuICAgICAgICAgIGNvbnN0IGJyb3dzZXIgPSBhd2FpdCBwdXBwZXRlZXIubGF1bmNoKHsgaGVhZGxlc3M6IHRydWUgfSk7XG4gICAgICAgICAgYXdhaXQgYnJvd3Nlci5jbG9zZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgY2FuTGF1bmNoOiB0cnVlLCBleGVjdXRhYmxlUGF0aCB9O1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICByZXR1cm4geyBjYW5MYXVuY2g6IGZhbHNlIH07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgYnJvd3NlckluZm8gPSBhd2FpdCBjYW5MYXVuY2hDaHJvbWl1bSgpO1xuICAgICAgaWYgKGJyb3dzZXJJbmZvLmNhbkxhdW5jaCkge1xuICAgICAgICB1dGlscy5wcmludFN1Y2Nlc3MoXG4gICAgICAgICAge1xuICAgICAgICAgICAgaW5zdGFsbGVkOiB0cnVlLFxuICAgICAgICAgICAgZXhlY3V0YWJsZVBhdGg6IGJyb3dzZXJJbmZvLmV4ZWN1dGFibGVQYXRoLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgJ0Nocm9taXVtIGlzIHJlYWR5J1xuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFyZ3MgPSBbJ3B1cHBldGVlcicsICdicm93c2VycycsICdpbnN0YWxsJywgJ2Nocm9tZSddO1xuICAgICAgaWYgKG9wdHMud2l0aERlcHMpIGFyZ3MucHVzaCgnLS13aXRoLWRlcHMnKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHNwYXduU3luYygnbnB4JywgYXJncywgeyBzdGRpbzogJ2luaGVyaXQnLCBlbnY6IHByb2Nlc3MuZW52IH0pO1xuXG4gICAgICBjb25zdCBhZnRlckluc3RhbGxJbmZvID0gYXdhaXQgY2FuTGF1bmNoQ2hyb21pdW0oKTtcbiAgICAgIGlmIChhZnRlckluc3RhbGxJbmZvLmNhbkxhdW5jaCkge1xuICAgICAgICB1dGlscy5wcmludFN1Y2Nlc3MoXG4gICAgICAgICAge1xuICAgICAgICAgICAgaW5zdGFsbGVkOiB0cnVlLFxuICAgICAgICAgICAgZXhlY3V0YWJsZVBhdGg6IGFmdGVySW5zdGFsbEluZm8uZXhlY3V0YWJsZVBhdGgsXG4gICAgICAgICAgICBleGl0Q29kZTogcmVzdWx0LnN0YXR1cyA/PyBudWxsLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgJ0Nocm9taXVtIGluc3RhbGxlZCBhbmQgcmVhZHknXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKG5ldyBFcnJvcignRmFpbGVkIHRvIGluc3RhbGwgb3IgbGF1bmNoIENocm9taXVtJykpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gIC8vIEZlZWRzOiBkaXNjb3ZlclxuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ2ZlZWRzJylcbiAgICAuZGVzY3JpcHRpb24oJ0Rpc2NvdmVyIGhvbWUgcGFnZSBmZWVkcycpXG4gICAgLm9wdGlvbignLWIsIC0tYnJvd3Nlci1wYXRoIDxwYXRoPicsICdDdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcpXG4gICAgLmFjdGlvbihhc3luYyAob3B0czogeyBicm93c2VyUGF0aD86IHN0cmluZyB9KSA9PiB7XG4gICAgICBjb25zdCBmZWVkU2VydmljZSA9IG5ldyBGZWVkU2VydmljZShjb25maWcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmVlZFNlcnZpY2UuZ2V0RmVlZExpc3Qob3B0cy5icm93c2VyUGF0aCk7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhyZXN1bHQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLy8gRmVlZHM6IHNlYXJjaCBub3RlXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnc2VhcmNoJylcbiAgICAuZGVzY3JpcHRpb24oJ1NlYXJjaCBub3RlcyBieSBrZXl3b3JkJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy1rLCAtLWtleXdvcmQgPGtleXdvcmQ+JywgJ1NlYXJjaCBrZXl3b3JkJylcbiAgICAub3B0aW9uKCctYiwgLS1icm93c2VyLXBhdGggPHBhdGg+JywgJ0N1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJylcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7IGtleXdvcmQ6IHN0cmluZzsgYnJvd3NlclBhdGg/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgY29uc3QgZmVlZFNlcnZpY2UgPSBuZXcgRmVlZFNlcnZpY2UoY29uZmlnKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZlZWRTZXJ2aWNlLnNlYXJjaEZlZWRzKG9wdHMua2V5d29yZCwgb3B0cy5icm93c2VyUGF0aCk7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhyZXN1bHQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLy8gVXNlciBOb3RlczogdW5pZmllZCBjb21tYW5kIHdpdGggc3ViY29tbWFuZHNcbiAgY29uc3QgdXNlck5vdGVDb21tYW5kID0gcHJvZ3JhbVxuICAgIC5jb21tYW5kKCd1c2Vybm90ZScpXG4gICAgLmRlc2NyaXB0aW9uKFwiQ3VycmVudCB1c2VyJ3Mgbm90ZSBtYW5hZ2VtZW50IG9wZXJhdGlvbnNcIik7XG5cbiAgLy8gVXNlciBOb3RlIGxpc3Qgc3ViY29tbWFuZFxuICB1c2VyTm90ZUNvbW1hbmRcbiAgICAuY29tbWFuZCgnbGlzdCcpXG4gICAgLmRlc2NyaXB0aW9uKFwiTGlzdCBjdXJyZW50IHVzZXIncyBwdWJsaXNoZWQgbm90ZXNcIilcbiAgICAub3B0aW9uKCctbCwgLS1saW1pdCA8bnVtYmVyPicsICdNYXhpbXVtIG51bWJlciBvZiBub3RlcyB0byByZXRyaWV2ZScsICcyMCcpXG4gICAgLm9wdGlvbignLWMsIC0tY3Vyc29yIDxjdXJzb3I+JywgJ1BhZ2luYXRpb24gY3Vyc29yIGZvciBuZXh0IHBhZ2UnKVxuICAgIC5vcHRpb24oJy1iLCAtLWJyb3dzZXItcGF0aCA8cGF0aD4nLCAnQ3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdHM6IHsgbGltaXQ6IHN0cmluZzsgY3Vyc29yPzogc3RyaW5nOyBicm93c2VyUGF0aD86IHN0cmluZyB9KSA9PiB7XG4gICAgICBjb25zdCBub3RlU2VydmljZSA9IG5ldyBOb3RlU2VydmljZShjb25maWcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbGltaXQgPSBwYXJzZUludChvcHRzLmxpbWl0KSB8fCAyMDtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbm90ZVNlcnZpY2UuZ2V0VXNlck5vdGVzKGxpbWl0LCBvcHRzLmN1cnNvciwgb3B0cy5icm93c2VyUGF0aCk7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhyZXN1bHQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLy8gVXNlciBOb3RlIGRlbGV0ZSBzdWJjb21tYW5kXG4gIHVzZXJOb3RlQ29tbWFuZFxuICAgIC5jb21tYW5kKCdkZWxldGUnKVxuICAgIC5kZXNjcmlwdGlvbignRGVsZXRlIHVzZXIgbm90ZXMnKVxuICAgIC5vcHRpb24oJy0tbm90ZS1pZCA8aWQ+JywgJ1NwZWNpZmljIG5vdGUgSUQgdG8gZGVsZXRlJylcbiAgICAub3B0aW9uKCctLWxhc3QtcHVibGlzaGVkJywgJ0RlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZScpXG4gICAgLm9wdGlvbignLWIsIC0tYnJvd3Nlci1wYXRoIDxwYXRoPicsICdDdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcpXG4gICAgLmFjdGlvbihhc3luYyAob3B0czogeyBub3RlSWQ/OiBzdHJpbmc7IGxhc3RQdWJsaXNoZWQ/OiBib29sZWFuOyBicm93c2VyUGF0aD86IHN0cmluZyB9KSA9PiB7XG4gICAgICBjb25zdCBub3RlU2VydmljZSA9IG5ldyBOb3RlU2VydmljZShjb25maWcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKG9wdHMubGFzdFB1Ymxpc2hlZCkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG5vdGVTZXJ2aWNlLmRlbGV0ZUxhc3RQdWJsaXNoZWROb3RlKG9wdHMuYnJvd3NlclBhdGgpO1xuICAgICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgaWYgKG9wdHMubm90ZUlkKSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbm90ZVNlcnZpY2UuZGVsZXRlTm90ZShvcHRzLm5vdGVJZCwgb3B0cy5icm93c2VyUGF0aCk7XG4gICAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gU2hvdyBoZWxwIGluc3RlYWQgb2YgSlNPTiBlcnJvciB3aGVuIG5vIGFyZ3VtZW50cyBwcm92aWRlZFxuICAgICAgICAgIGNvbnNvbGUubG9nKCdVc2FnZTogeGhzLW1jcCB1c2Vybm90ZSBkZWxldGUgW29wdGlvbnNdXFxuJyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ0RlbGV0ZSB1c2VyIG5vdGVzXFxuJyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ09wdGlvbnM6Jyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJyAgLS1ub3RlLWlkIDxpZD4gICAgICAgICAgICAgU3BlY2lmaWMgbm90ZSBJRCB0byBkZWxldGUnKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnICAtLWxhc3QtcHVibGlzaGVkICAgICAgICAgICBEZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGUnKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnICAtYiwgLS1icm93c2VyLXBhdGggPHBhdGg+ICBDdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcgIC1oLCAtLWhlbHAgICAgICAgICAgICAgICAgIGRpc3BsYXkgaGVscCBmb3IgY29tbWFuZCcpO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLy8gRmVlZHM6IGNvbW1lbnQgb24gbm90ZVxuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ2NvbW1lbnQnKVxuICAgIC5kZXNjcmlwdGlvbignQ29tbWVudCBvbiBhIG5vdGUnKVxuICAgIC5yZXF1aXJlZE9wdGlvbignLS1mZWVkLWlkIDxpZD4nLCAnRmVlZCBJRCcpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctLXhzZWMtdG9rZW4gPHRva2VuPicsICdTZWN1cml0eSB0b2tlbiBmb3IgdGhlIGZlZWQnKVxuICAgIC5yZXF1aXJlZE9wdGlvbignLW4sIC0tbm90ZSA8dGV4dD4nLCAnQ29tbWVudCBjb250ZW50JylcbiAgICAub3B0aW9uKCctYiwgLS1icm93c2VyLXBhdGggPHBhdGg+JywgJ0N1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJylcbiAgICAuYWN0aW9uKFxuICAgICAgYXN5bmMgKG9wdHM6IHsgZmVlZElkOiBzdHJpbmc7IHhzZWNUb2tlbjogc3RyaW5nOyBub3RlOiBzdHJpbmc7IGJyb3dzZXJQYXRoPzogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgY29uc3QgZmVlZFNlcnZpY2UgPSBuZXcgRmVlZFNlcnZpY2UoY29uZmlnKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmZWVkU2VydmljZS5jb21tZW50T25GZWVkKFxuICAgICAgICAgICAgb3B0cy5mZWVkSWQsXG4gICAgICAgICAgICBvcHRzLnhzZWNUb2tlbixcbiAgICAgICAgICAgIG9wdHMubm90ZSxcbiAgICAgICAgICAgIG9wdHMuYnJvd3NlclBhdGhcbiAgICAgICAgICApO1xuICAgICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhyZXN1bHQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHV0aWxzLnByaW50RXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKTtcblxuICAvLyBQdWJsaXNoaW5nOiB1bmlmaWVkIHB1Ymxpc2ggY29tbWFuZFxuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ3B1Ymxpc2gnKVxuICAgIC5kZXNjcmlwdGlvbignUHVibGlzaCBjb250ZW50IHRvIFhpYW9Ib25nU2h1IChzdXBwb3J0cyBib3RoIGltYWdlcyBhbmQgdmlkZW9zKScpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctdCwgLS10eXBlIDx0eXBlPicsICdDb250ZW50IHR5cGU6IFwiaW1hZ2VcIiBmb3IgaW1hZ2VzLCBcInZpZGVvXCIgZm9yIHZpZGVvcycpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctLXRpdGxlIDx0aXRsZT4nLCAnQ29udGVudCB0aXRsZSAoPD0gMjAgY2hhcnMpJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy0tY29udGVudCA8Y29udGVudD4nLCAnQ29udGVudCBkZXNjcmlwdGlvbiAoPD0gMTAwMCBjaGFycyknKVxuICAgIC5yZXF1aXJlZE9wdGlvbihcbiAgICAgICctbSwgLS1tZWRpYSA8cGF0aHM+JyxcbiAgICAgICdDb21tYS1zZXBhcmF0ZWQgbWVkaWEgZmlsZSBwYXRocyAoMS0xOCBpbWFnZXMgZm9yIGltYWdlIHBvc3RzLCBleGFjdGx5IDEgdmlkZW8gZm9yIHZpZGVvcyknXG4gICAgKVxuICAgIC5vcHRpb24oJy0tdGFncyA8dGFncz4nLCAnQ29tbWEtc2VwYXJhdGVkIHRhZ3MnKVxuICAgIC5vcHRpb24oJy1iLCAtLWJyb3dzZXItcGF0aCA8cGF0aD4nLCAnQ3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnKVxuICAgIC5hY3Rpb24oXG4gICAgICBhc3luYyAob3B0czoge1xuICAgICAgICB0eXBlOiBzdHJpbmc7XG4gICAgICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgICAgIGNvbnRlbnQ6IHN0cmluZztcbiAgICAgICAgbWVkaWE6IHN0cmluZztcbiAgICAgICAgdGFncz86IHN0cmluZztcbiAgICAgICAgYnJvd3NlclBhdGg/OiBzdHJpbmc7XG4gICAgICB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHB1Ymxpc2hTZXJ2aWNlID0gbmV3IFB1Ymxpc2hTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKG9wdHMudHlwZSAhPT0gJ2ltYWdlJyAmJiBvcHRzLnR5cGUgIT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgIHV0aWxzLnByaW50RXJyb3IobmV3IEVycm9yKCdUeXBlIG11c3QgYmUgXCJpbWFnZVwiIG9yIFwidmlkZW9cIicpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBtZWRpYVBhdGhzID0gb3B0cy5tZWRpYVxuICAgICAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgICAgIC5tYXAoKHMpID0+IHMudHJpbSgpKVxuICAgICAgICAgICAgLmZpbHRlcihCb29sZWFuKTtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwdWJsaXNoU2VydmljZS5wdWJsaXNoQ29udGVudChcbiAgICAgICAgICAgIG9wdHMudHlwZSxcbiAgICAgICAgICAgIG9wdHMudGl0bGUsXG4gICAgICAgICAgICBvcHRzLmNvbnRlbnQsXG4gICAgICAgICAgICBtZWRpYVBhdGhzLFxuICAgICAgICAgICAgb3B0cy50YWdzLFxuICAgICAgICAgICAgb3B0cy5icm93c2VyUGF0aFxuICAgICAgICAgICk7XG4gICAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnbWNwJylcbiAgICAuZGVzY3JpcHRpb24oJ1N0YXJ0IFhIUyBNQ1Agc2VydmVyIChzdGRpbyBvciBodHRwIG1vZGUpJylcbiAgICAub3B0aW9uKCctbSwgLS1tb2RlIDxtb2RlPicsICdTZXJ2ZXIgbW9kZTogc3RkaW8gb3IgaHR0cCcsICdzdGRpbycpXG4gICAgLm9wdGlvbignLXAsIC0tcG9ydCA8cG9ydD4nLCAnSFRUUCBzZXJ2ZXIgcG9ydCAob25seSBmb3IgaHR0cCBtb2RlKScsICczMDAwJylcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7IG1vZGU/OiBzdHJpbmc7IHBvcnQ/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKG9wdHMubW9kZSA9PT0gJ2h0dHAnKSB7XG4gICAgICAgICAgY29uc3QgcG9ydCA9IG9wdHMucG9ydCA/IHBhcnNlSW50KG9wdHMucG9ydCwgMTApIDogMzAwMDtcbiAgICAgICAgICBjb25zdCBodHRwU2VydmVyID0gbmV3IFhIU0hUVFBNQ1BTZXJ2ZXIocG9ydCk7XG4gICAgICAgICAgYXdhaXQgaHR0cFNlcnZlci5zdGFydCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEluIHN0ZGlvIG1vZGUsIHdlIG11c3Qgbm90IG91dHB1dCBhbnl0aGluZyB0byBzdGRvdXQvc3RkZXJyIGV4Y2VwdCBNQ1AgcHJvdG9jb2wgbWVzc2FnZXNcbiAgICAgICAgICAvLyBUaGlzIHByZXZlbnRzIGludGVyZmVyZW5jZSB3aXRoIE1DUCBjb21tdW5pY2F0aW9uXG4gICAgICAgICAgY29uc3Qgc2VydmVyID0gbmV3IFhIU01DUFNlcnZlcigpO1xuICAgICAgICAgIGF3YWl0IHNlcnZlci5zdGFydCgpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBPbmx5IGxvZyB0byBzdGRlcnIgaWYgbG9nZ2luZyBpcyBleHBsaWNpdGx5IGVuYWJsZWRcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52LlhIU19FTkFCTEVfTE9HR0lORyA9PT0gJ3RydWUnKSB7XG4gICAgICAgICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoYFNlcnZlciBmYWlsZWQgdG8gc3RhcnQ6ICR7ZXJyb3J9XFxuYCk7XG4gICAgICAgIH1cbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gIC8vIExpc3QgTUNQIHRvb2xzXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgndG9vbHMnKVxuICAgIC5kZXNjcmlwdGlvbignTGlzdCBhdmFpbGFibGUgTUNQIHRvb2xzJylcbiAgICAub3B0aW9uKCctaiwgLS1qc29uJywgJ091dHB1dCBpbiBKU09OIGZvcm1hdCcpXG4gICAgLm9wdGlvbignLWQsIC0tZGV0YWlsZWQnLCAnU2hvdyBkZXRhaWxlZCB0b29sIGluZm9ybWF0aW9uJylcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7IGpzb24/OiBib29sZWFuOyBkZXRhaWxlZD86IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgdG9vbFNjaGVtYXMgPSBYSFNfVE9PTF9TQ0hFTUFTO1xuXG4gICAgICAgIGlmIChvcHRzLmpzb24pIHtcbiAgICAgICAgICBpZiAob3B0cy5kZXRhaWxlZCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkodG9vbFNjaGVtYXMsIG51bGwsIDIpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdG9vbE5hbWVzID0gdG9vbFNjaGVtYXMubWFwKCh0b29sKSA9PiAoe1xuICAgICAgICAgICAgICBuYW1lOiB0b29sLm5hbWUsXG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiB0b29sLmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkodG9vbE5hbWVzLCBudWxsLCAyKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdcXG7wn5OLIEF2YWlsYWJsZSBNQ1AgVG9vbHM6XFxuJyk7XG5cbiAgICAgICAgICB0b29sU2NoZW1hcy5mb3JFYWNoKCh0b29sLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYCR7aW5kZXggKyAxfS4gJHt0b29sLm5hbWV9YCk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgICAgJHt0b29sLmRlc2NyaXB0aW9ufWApO1xuXG4gICAgICAgICAgICBpZiAob3B0cy5kZXRhaWxlZCkge1xuICAgICAgICAgICAgICBjb25zdCByZXF1aXJlZCA9IHRvb2wuaW5wdXRTY2hlbWEucmVxdWlyZWQgPz8gW107XG4gICAgICAgICAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB0b29sLmlucHV0U2NoZW1hLnByb3BlcnRpZXMgPz8ge307XG5cbiAgICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnICAgUGFyYW1ldGVyczonKTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZW50cmllcyhwcm9wZXJ0aWVzKS5mb3JFYWNoKChba2V5LCBwcm9wXTogW3N0cmluZywgdW5rbm93bl0pID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcXVpcmVkTWFyayA9IHJlcXVpcmVkLmluY2x1ZGVzKGtleSkgPyAnIChyZXF1aXJlZCknIDogJyAob3B0aW9uYWwpJztcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHByb3BEZXNjID0gKHByb3AgYXMgeyBkZXNjcmlwdGlvbj86IHN0cmluZyB9KS5kZXNjcmlwdGlvbjtcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGAgICAgIC0gJHtrZXl9OiAke3Byb3BEZXNjID8/ICdObyBkZXNjcmlwdGlvbid9JHtyZXF1aXJlZE1hcmt9YCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnNvbGUubG9nKGBUb3RhbDogJHt0b29sU2NoZW1hcy5sZW5ndGh9IHRvb2xzIGF2YWlsYWJsZWApO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdcXG5Vc2UgLS1kZXRhaWxlZCBmb3IgcGFyYW1ldGVyIGluZm9ybWF0aW9uJyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1VzZSAtLWpzb24gZm9yIG1hY2hpbmUtcmVhZGFibGUgb3V0cHV0Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHV0aWxzLnByaW50RXJyb3IoZXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gIHByb2dyYW0ucGFyc2VBc3luYyhwcm9jZXNzLmFyZ3YpO1xufVxuXG4vLyBIYW5kbGUgZ3JhY2VmdWwgc2h1dGRvd24gZm9yIE1DUCBzZXJ2ZXIgbW9kZVxucHJvY2Vzcy5vbignU0lHSU5UJywgKCkgPT4ge1xuICAvLyBEb24ndCBsb2cgdG8gc3RkZXJyIGluIHN0ZGlvIG1vZGUgdG8gYXZvaWQgaW50ZXJmZXJpbmcgd2l0aCBNQ1AgcHJvdG9jb2xcbiAgcHJvY2Vzcy5leGl0KDApO1xufSk7XG5cbnByb2Nlc3Mub24oJ1NJR1RFUk0nLCAoKSA9PiB7XG4gIC8vIERvbid0IGxvZyB0byBzdGRlcnIgaW4gc3RkaW8gbW9kZSB0byBhdm9pZCBpbnRlcmZlcmluZyB3aXRoIE1DUCBwcm90b2NvbFxuICBwcm9jZXNzLmV4aXQoMCk7XG59KTtcblxuLy8gU3RhcnQgdGhlIENMSVxubWFpbigpLmNhdGNoKChlcnJvcikgPT4ge1xuICAvLyBPbmx5IGxvZyB0byBzdGRlcnIgaWYgbG9nZ2luZyBpcyBleHBsaWNpdGx5IGVuYWJsZWRcbiAgaWYgKHByb2Nlc3MuZW52LlhIU19FTkFCTEVfTE9HR0lORyA9PT0gJ3RydWUnKSB7XG4gICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoYEZhdGFsIGVycm9yOiAke2Vycm9yfVxcbmApO1xuICB9XG4gIHByb2Nlc3MuZXhpdCgxKTtcbn0pO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5582\n\n}");
94
+ eval("{\n;// external \"commander\"\nconst external_commander_namespaceObject = require(\"commander\");\n// EXTERNAL MODULE: ./src/shared/config.ts + 1 modules\nvar shared_config = __webpack_require__(2207);\n// EXTERNAL MODULE: ./src/shared/errors.ts\nvar shared_errors = __webpack_require__(7636);\n// EXTERNAL MODULE: ./src/shared/base.service.ts\nvar base_service = __webpack_require__(103);\n// EXTERNAL MODULE: ./src/shared/cookies.ts\nvar cookies = __webpack_require__(4760);\n// EXTERNAL MODULE: ./src/shared/logger.ts\nvar logger = __webpack_require__(9135);\n;// ./src/shared/xhs.utils.ts\n/**\n * Utility functions for XHS operations\n */\n\nconst XHS_HOME_URL = 'https://www.xiaohongshu.com';\nconst XHS_EXPLORE_URL = `${XHS_HOME_URL}/explore`;\nconst XHS_SEARCH_URL = `${XHS_HOME_URL}/search_result`;\nconst XHS_CREATOR_PUBLISH_URL = 'https://creator.xiaohongshu.com/publish/publish?source=official';\nconst LOGIN_OK_SELECTOR = '.main-container .user .link-wrapper .channel';\nfunction makeSearchUrl(keyword) {\n const params = new URLSearchParams({\n keyword,\n source: 'web_explore_feed',\n });\n return `${XHS_SEARCH_URL}?${params.toString()}`;\n}\nfunction makeFeedDetailUrl(feedId, xsecToken) {\n const params = new URLSearchParams({\n xsec_token: xsecToken,\n xsec_source: 'pc_feed',\n });\n return `${XHS_EXPLORE_URL}/${feedId}?${params.toString()}`;\n}\nasync function extractInitialState(page) {\n try {\n // Wait for page to be fully loaded - Puppeteer doesn't have waitForLoadState\n // We'll just wait a bit for the page to settle\n await new Promise((resolve) => globalThis.setTimeout(resolve, 1000));\n }\n catch {\n // Ignore load state errors\n }\n try {\n const result = await page.evaluate(`\n (() => {\n // Try multiple possible state objects\n const possibleStates = [\n window.__INITIAL_STATE__,\n window.__INITIAL_SSR_STATE__,\n window.__NEXT_DATA__,\n window.__NUXT__,\n window.__VUE__,\n window.__REACT_QUERY_STATE__\n ];\n\n for (const state of possibleStates) {\n if (state && typeof state === 'object') {\n try {\n // Use a more robust JSON serialization that handles circular references\n const seen = new WeakSet();\n return JSON.stringify(state, (key, val) => {\n if (val != null && typeof val === \"object\") {\n if (seen.has(val)) {\n return \"[Circular]\";\n }\n seen.add(val);\n }\n return val;\n });\n } catch (e) {\n logger.warn('JSON.stringify failed for state:', e.message);\n continue;\n }\n }\n }\n\n // If no state found, try to find any global state\n const globalKeys = Object.keys(window).filter(key =>\n key.includes('STATE') || key.includes('DATA') || key.includes('INITIAL')\n );\n\n for (const key of globalKeys) {\n const value = window[key];\n if (value && typeof value === 'object') {\n try {\n const seen = new WeakSet();\n return JSON.stringify(value, (key, val) => {\n if (val != null && typeof val === \"object\") {\n if (seen.has(val)) {\n return \"[Circular]\";\n }\n seen.add(val);\n }\n return val;\n });\n } catch (e) {\n logger.warn('JSON.stringify failed for global key:', key, e.message);\n continue;\n }\n }\n }\n\n return '';\n })()\n `);\n if (!result) {\n return null;\n }\n return JSON.parse(result);\n }\n catch {\n return null;\n }\n}\nasync function isLoggedIn(page) {\n try {\n const elements = await page.$$(LOGIN_OK_SELECTOR);\n return elements.length > 0;\n }\n catch {\n return false;\n }\n}\nasync function getLoginStatusWithProfile(page) {\n try {\n // First check if logged in using the existing method\n const elements = await page.$$(LOGIN_OK_SELECTOR);\n const isLoggedIn = elements.length > 0;\n if (!isLoggedIn) {\n return { isLoggedIn: false };\n }\n // If logged in, try to extract profile information from current page\n let profileData = {};\n try {\n profileData = await page.evaluate(() => {\n const profile = {};\n // Extract user ID from URL if on profile page\n // eslint-disable-next-line no-undef\n const urlMatch = window.location.href.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (urlMatch) {\n profile.userId = urlMatch[1];\n }\n // Try to find user nickname\n // eslint-disable-next-line no-undef\n const nameElement = document.querySelector('.user-name, [class*=\"user-name\"], [class*=\"nickname\"]');\n if (nameElement) {\n profile.nickname = nameElement.textContent?.trim();\n }\n // Try to find user info text that might contain stats\n // eslint-disable-next-line no-undef\n const infoElement = document.querySelector('.user-info, [class*=\"user-info\"]');\n if (infoElement) {\n const infoText = infoElement.textContent || '';\n profile.infoText = infoText;\n // Try to extract numbers from the info text (followers, following, likes)\n const numbers = infoText.match(/\\d+/g);\n if (numbers && numbers.length >= 3) {\n // Common pattern: followers, following, likes\n profile.following = parseInt(numbers[0]) || 0;\n profile.followers = parseInt(numbers[1]) || 0;\n profile.likes = parseInt(numbers[2]) || 0;\n }\n // Extract 小红书号 (XHS number)\n const xhsMatch = infoText.match(/小红书号:(\\d+)/);\n if (xhsMatch) {\n profile.xhsNumber = xhsMatch[1];\n }\n // Extract IP属地 (IP location)\n const ipMatch = infoText.match(/IP属地:([^0-9]+)/);\n if (ipMatch) {\n profile.ipLocation = ipMatch[1].trim();\n }\n }\n // Try to find avatar\n // eslint-disable-next-line no-undef\n const avatarElement = document.querySelector('img[class*=\"avatar\"], img[class*=\"profile\"], .avatar img, .profile img');\n if (avatarElement) {\n profile.avatar = avatarElement.src;\n }\n return profile;\n });\n }\n catch {\n logger/* logger */.v.error('Error in page.evaluate');\n profileData = {};\n }\n return {\n isLoggedIn: true,\n profile: Object.keys(profileData).length > 0 ? profileData : undefined,\n };\n }\n catch {\n // If there's an error, fall back to basic login check\n try {\n const elements = await page.$$(LOGIN_OK_SELECTOR);\n return { isLoggedIn: elements.length > 0 };\n }\n catch {\n return { isLoggedIn: false };\n }\n }\n}\n\n// EXTERNAL MODULE: ./src/shared/utils.ts\nvar utils = __webpack_require__(2094);\n;// ./src/core/auth/auth.service.ts\n/**\n * Authentication service for XHS MCP Server\n */\n\n\n\n\n\n\nclass AuthService extends base_service/* BaseService */.d {\n constructor(config, browserManager) {\n super(config, browserManager);\n }\n /**\n * Extract profile URL and user ID from the current page\n */\n async extractProfileFromPage(page) {\n try {\n const profileUrl = await page.evaluate(() => {\n const userLinks = Array.from(document.querySelectorAll('a[href*=\"/user/profile/\"]'));\n const currentUserLink = userLinks.find((link) => {\n const text = link.textContent?.trim();\n return (text === '我' ||\n (text && text.includes('profile')) ||\n (text && text.includes('用户')));\n });\n return currentUserLink ? currentUserLink.href : null;\n });\n if (profileUrl) {\n const userIdMatch = profileUrl.match(/\\/user\\/profile\\/([a-f0-9]+)/);\n if (userIdMatch) {\n return { userId: userIdMatch[1], profileUrl };\n }\n }\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get profile information:', profileError);\n }\n return undefined;\n }\n async login(browserPath, timeout = 300) {\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n // Navigate to explore page\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.exploreUrl);\n // Check if already logged in\n if (await isLoggedIn(page)) {\n let profile = undefined;\n try {\n const extracted = await this.extractProfileFromPage(page);\n const loginStatus = await getLoginStatusWithProfile(page);\n profile = { ...extracted, ...loginStatus.profile };\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get profile information:', profileError);\n }\n return {\n success: true,\n message: 'Already logged in',\n status: 'logged_in',\n action: 'none',\n profile,\n };\n }\n // Wait for login completion\n const checkInterval = 5;\n const maxChecks = timeout / checkInterval;\n for (let checkCount = 0; checkCount < maxChecks; checkCount++) {\n try {\n await page.waitForSelector(this.getConfig().xhs.loginOkSelector, {\n timeout: checkInterval * 1000,\n });\n break;\n }\n catch (error) {\n const elapsed = (checkCount + 1) * checkInterval;\n if (checkCount === maxChecks - 1) {\n throw new shared_errors/* LoginTimeoutError */.H7(`Login timed out after ${timeout} seconds. Please complete QR code scanning or manual login in the browser window.`, {\n timeout,\n url: this.getConfig().xhs.exploreUrl,\n elapsedTime: elapsed,\n suggestion: 'Increase timeout parameter or complete login faster',\n });\n }\n }\n }\n // Save cookies after successful login\n await this.getBrowserManager().saveCookiesFromPage(page);\n // Verify login success and get profile information\n await (0,utils/* sleep */.yy)(1000);\n const loginStatus = await getLoginStatusWithProfile(page);\n if (loginStatus.isLoggedIn) {\n let profile = loginStatus.profile;\n try {\n const extracted = await this.extractProfileFromPage(page);\n if (extracted) {\n profile = { ...profile, ...extracted };\n }\n }\n catch (profileError) {\n logger/* logger */.v.warn('Failed to get additional profile information:', profileError);\n }\n return {\n success: true,\n message: 'Login successful',\n status: 'logged_in',\n action: 'logged_in',\n profile,\n };\n }\n else {\n throw new shared_errors/* LoginFailedError */.f6('Login process completed but authentication verification failed');\n }\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* LoginTimeoutError */.H7 || error instanceof shared_errors/* LoginFailedError */.f6) {\n throw error;\n }\n logger/* logger */.v.error(`Login failed with unexpected error: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Login failed: ${error}`, 'LoginError', { timeout }, error);\n }\n }\n async logout() {\n try {\n const success = (0,cookies/* deleteCookiesFile */.ZR)();\n if (success) {\n return {\n success: true,\n message: 'Logged out successfully (cookies deleted)',\n status: 'logged_out',\n action: 'logged_out',\n };\n }\n else {\n return {\n success: false,\n message: 'Failed to delete cookies file',\n status: 'logged_out',\n action: 'none',\n };\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Logout failed: ${error}`);\n return {\n success: false,\n message: `Logout failed: ${error}`,\n status: 'logged_out',\n action: 'none',\n };\n }\n }\n async checkStatus(browserPath) {\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.exploreUrl);\n await (0,utils/* sleep */.yy)(1000);\n const loggedIn = await isLoggedIn(page);\n if (!loggedIn) {\n return {\n success: true,\n loggedIn: false,\n status: 'logged_out',\n urlChecked: this.getConfig().xhs.exploreUrl,\n };\n }\n const profile = await this.extractProfileFromPage(page);\n return {\n success: true,\n loggedIn: true,\n status: 'logged_in',\n urlChecked: this.getConfig().xhs.exploreUrl,\n profile,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Status check failed: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Status check failed: ${error}`, 'StatusCheckError', {}, error);\n }\n }\n}\n\n// EXTERNAL MODULE: external \"puppeteer\"\nvar external_puppeteer_ = __webpack_require__(9916);\nvar external_puppeteer_default = /*#__PURE__*/__webpack_require__.n(external_puppeteer_);\n;// external \"node:child_process\"\nconst external_node_child_process_namespaceObject = require(\"node:child_process\");\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js + 1 modules\nvar esm_server = __webpack_require__(2028);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js + 1 modules\nvar stdio = __webpack_require__(7862);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/types.js + 7 modules\nvar types = __webpack_require__(2780);\n;// ./src/core/feeds/feed.service.ts\n/**\n * Feed operations service for XHS MCP Server\n */\n\n\n\n\n\nclass FeedService extends base_service/* BaseService */.d {\n constructor(config, browserManager) {\n super(config, browserManager);\n }\n async getFeedList(browserPath) {\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.homeUrl);\n await (0,utils/* sleep */.yy)(1000);\n // Check if logged in\n if (!(await isLoggedIn(page))) {\n throw new shared_errors/* NotLoggedInError */.bG('Must be logged in to access feed list', {\n operation: 'get_feed_list',\n });\n }\n // Extract feed data using a more targeted approach\n let feedData = null;\n let attempts = 0;\n const maxAttempts = 10;\n while (attempts < maxAttempts && !feedData) {\n await (0,utils/* sleep */.yy)(2000); // Wait 2 seconds between attempts\n attempts++;\n feedData = (await page.evaluate(`\n (() => {\n if (window.__INITIAL_STATE__ && window.__INITIAL_STATE__.feed && window.__INITIAL_STATE__.feed.feeds && window.__INITIAL_STATE__.feed.feeds._value) {\n try {\n // Try to serialize just the feeds data to avoid circular reference issues\n const feedsData = window.__INITIAL_STATE__.feed.feeds._value;\n return JSON.stringify(feedsData);\n } catch (e) {\n logger.warn('Failed to serialize feeds data:', e.message);\n return null;\n }\n }\n return null;\n })()\n `));\n if (feedData) {\n logger/* logger */.v.info(`Feed results loaded after ${attempts} attempts`);\n break;\n }\n }\n if (!feedData) {\n throw new shared_errors/* FeedParsingError */.TG(`Could not extract feed data after ${maxAttempts} attempts. The page may not be fully loaded or the state structure has changed.`, {\n url: this.getConfig().xhs.homeUrl,\n suggestion: 'Try logging in first using xhs_auth_login tool',\n });\n }\n const feedsValue = JSON.parse(feedData);\n return {\n success: true,\n feeds: feedsValue,\n count: feedsValue.length,\n source: 'home_page',\n url: this.getConfig().xhs.homeUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* NotLoggedInError */.bG || error instanceof shared_errors/* FeedParsingError */.TG) {\n throw error;\n }\n logger/* logger */.v.error(`Failed to get feed list: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Failed to get feed list: ${error}`, 'GetFeedListError', {}, error);\n }\n }\n async searchFeeds(keyword, browserPath) {\n if (!keyword || !keyword.trim()) {\n throw new shared_errors/* FeedError */.lS('Search keyword cannot be empty');\n }\n const trimmedKeyword = keyword.trim();\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n const searchUrl = makeSearchUrl(trimmedKeyword);\n await this.getBrowserManager().navigateWithRetry(page, searchUrl);\n // Wait for search results to load with multiple attempts\n let searchData = null;\n let attempts = 0;\n const maxAttempts = 10;\n while (attempts < maxAttempts && !searchData) {\n await (0,utils/* sleep */.yy)(2000); // Wait 2 seconds between attempts\n attempts++;\n searchData = (await page.evaluate(`\n (() => {\n if (window.__INITIAL_STATE__ && window.__INITIAL_STATE__.search && window.__INITIAL_STATE__.search.feeds && window.__INITIAL_STATE__.search.feeds._value) {\n try {\n // Try to serialize just the feeds data to avoid circular reference issues\n const feedsData = window.__INITIAL_STATE__.search.feeds._value;\n return JSON.stringify(feedsData);\n } catch (e) {\n logger.warn('Failed to serialize feeds data:', e.message);\n return null;\n }\n }\n return null;\n })()\n `));\n if (searchData) {\n logger/* logger */.v.info(`Search results loaded after ${attempts} attempts`);\n break;\n }\n }\n if (!searchData) {\n throw new shared_errors/* FeedParsingError */.TG(`Could not extract search results for keyword: ${trimmedKeyword} after ${maxAttempts} attempts`, {\n keyword: trimmedKeyword,\n url: searchUrl,\n });\n }\n const feedsValue = JSON.parse(searchData);\n return {\n success: true,\n keyword: trimmedKeyword,\n feeds: feedsValue,\n count: feedsValue.length,\n searchUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* FeedError */.lS) {\n throw error;\n }\n logger/* logger */.v.error(`Feed search failed for keyword '${trimmedKeyword}': ${error}`);\n throw new shared_errors/* XHSError */.a_(`Feed search failed: ${error}`, 'SearchFeedsError', { keyword: trimmedKeyword }, error);\n }\n }\n async getFeedDetail(feedId, xsecToken, browserPath) {\n if (!feedId || !xsecToken) {\n throw new shared_errors/* FeedError */.lS('Both feed_id and xsec_token are required');\n }\n try {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n const detailUrl = makeFeedDetailUrl(feedId, xsecToken);\n await this.getBrowserManager().navigateWithRetry(page, detailUrl);\n await (0,utils/* sleep */.yy)(1000);\n const state = await extractInitialState(page);\n const noteData = state?.note;\n if (!state || !noteData || !noteData.noteDetailMap) {\n throw new shared_errors/* FeedParsingError */.TG(`Could not extract note details for feed: ${feedId}`, {\n feedId,\n url: detailUrl,\n });\n }\n const noteDetailMap = noteData.noteDetailMap;\n if (!(feedId in noteDetailMap)) {\n throw new shared_errors/* FeedNotFoundError */.aW(`Feed ${feedId} not found in note details`, {\n feedId,\n availableFeeds: Object.keys(noteDetailMap),\n });\n }\n const detail = noteDetailMap[feedId];\n return {\n success: true,\n feedId,\n detail,\n url: detailUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* FeedError */.lS ||\n error instanceof shared_errors/* FeedNotFoundError */.aW ||\n error instanceof shared_errors/* FeedParsingError */.TG) {\n throw error;\n }\n logger/* logger */.v.error(`Failed to get feed detail for ${feedId}: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Failed to get feed detail: ${error}`, 'GetFeedDetailError', { feedId }, error);\n }\n }\n async commentOnFeed(feedId, xsecToken, note, browserPath) {\n if (!feedId || !xsecToken || !note) {\n throw new shared_errors/* FeedError */.lS('feed_id, xsec_token, and note are all required');\n }\n if (note.trim().length === 0) {\n throw new shared_errors/* FeedError */.lS('Comment note cannot be empty');\n }\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n const detailUrl = makeFeedDetailUrl(feedId, xsecToken);\n await this.getBrowserManager().navigateWithRetry(page, detailUrl);\n await (0,utils/* sleep */.yy)(1000);\n // Check if logged in\n if (!(await isLoggedIn(page))) {\n throw new shared_errors/* NotLoggedInError */.bG('Must be logged in to comment on feeds', {\n operation: 'comment_on_feed',\n feedId,\n });\n }\n // Click on comment input\n const commentInputSelector = 'div.input-box div.content-edit span';\n if (!(await this.getBrowserManager().tryWaitForSelector(page, commentInputSelector))) {\n throw new shared_errors/* FeedError */.lS('Comment input not found on page', {\n feedId,\n selector: commentInputSelector,\n });\n }\n const commentInput = await page.$(commentInputSelector);\n if (commentInput) {\n await commentInput.click();\n }\n // Fill comment note\n const editorSelector = 'div.input-box div.content-edit p.content-input';\n const editor = await page.$(editorSelector);\n if (editor) {\n await editor.click();\n await editor.type(note, { delay: 30 });\n }\n await (0,utils/* sleep */.yy)(1000);\n // Submit comment\n const submitSelector = 'div.bottom button.submit';\n const submitButton = await page.$(submitSelector);\n if (submitButton) {\n await submitButton.click();\n }\n await (0,utils/* sleep */.yy)(2000); // Wait for submission\n return {\n success: true,\n message: 'Comment submitted successfully',\n feedId,\n note,\n url: detailUrl,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* FeedError */.lS || error instanceof shared_errors/* NotLoggedInError */.bG) {\n throw error;\n }\n logger/* logger */.v.error(`Failed to comment on feed ${feedId}: ${error}`);\n throw new shared_errors/* XHSError */.a_(`Failed to comment on feed: ${error}`, 'CommentOnFeedError', { feedId }, error);\n }\n }\n}\n\n// EXTERNAL MODULE: ./node_modules/string-width/index.js + 4 modules\nvar string_width = __webpack_require__(6904);\n;// ./src/shared/title-validator.ts\n/**\n * Title validation utility for XHS MCP Server\n * Validates title width according to XiaoHongShu's display width rules\n *\n * XHS Rules:\n * - Max width: 40 units\n * - CJK characters (Chinese/Japanese/Korean): 2 units each\n * - Other characters (English/Numbers): 1 unit each\n */\n\n\n/**\n * XiaoHongShu title constraints\n */\nconst XHS_TITLE_CONSTRAINTS = {\n MAX_WIDTH: 40, // Maximum display width in units\n MAX_LENGTH: 20, // Approximate max character count (for reference)\n};\n/**\n * Validate title width according to XHS display rules\n *\n * @param title - The title to validate\n * @returns Validation result with width information\n *\n * @example\n * ```typescript\n * const result = validateTitleWidth('Hello世界');\n * console.log(result.width); // 10 (5 + 2*2 + 1 = 10)\n * console.log(result.valid); // true\n * ```\n */\nfunction validateTitleWidth(title) {\n if (!title) {\n return {\n valid: false,\n width: 0,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n message: 'Title cannot be empty',\n suggestion: 'Please provide a valid title',\n };\n }\n // Calculate display width using string-width\n // This correctly handles CJK characters, emoji, and other Unicode\n const width = (0,string_width/* default */.A)(title);\n if (width > XHS_TITLE_CONSTRAINTS.MAX_WIDTH) {\n return {\n valid: false,\n width,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n message: `Title width exceeds limit: ${width} units (max: ${XHS_TITLE_CONSTRAINTS.MAX_WIDTH} units)`,\n suggestion: `Current title is too long. CJK characters count as 2 units, English/numbers as 1 unit. Please shorten your title.`,\n };\n }\n return {\n valid: true,\n width,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n };\n}\n/**\n * Validate and throw error if title width is invalid\n *\n * @param title - The title to validate\n * @throws PublishError if title width is invalid\n *\n * @example\n * ```typescript\n * try {\n * assertTitleWidthValid('很长很长的标题'.repeat(10));\n * } catch (error) {\n * console.error(error.message);\n * }\n * ```\n */\nfunction assertTitleWidthValid(title) {\n const result = validateTitleWidth(title);\n if (!result.valid) {\n throw new shared_errors/* PublishError */.S1(result.message, {\n title,\n width: result.width,\n maxWidth: result.maxWidth,\n suggestion: result.suggestion,\n details: {\n titleLength: title.length,\n displayWidth: result.width,\n maxDisplayWidth: result.maxWidth,\n exceeded: result.width - result.maxWidth,\n },\n });\n }\n}\n/**\n * Get the display width of a title\n *\n * @param title - The title to measure\n * @returns Display width in units\n *\n * @example\n * ```typescript\n * console.log(getTitleWidth('Hello')); // 5\n * console.log(getTitleWidth('你好')); // 4 (2*2)\n * console.log(getTitleWidth('Hello世界')); // 10 (5 + 2*2 + 1)\n * console.log(getTitleWidth('👋Hello')); // 7 (2 + 5)\n * ```\n */\nfunction getTitleWidth(title) {\n return (0,string_width/* default */.A)(title);\n}\n/**\n * Calculate how many characters can be added to the title\n *\n * @param title - Current title\n * @returns Remaining width units available\n *\n * @example\n * ```typescript\n * const remaining = getRemainingTitleWidth('Hello'); // 35\n * console.log(`You can add ${remaining} more units`);\n * ```\n */\nfunction calculateRemainingTitleWidth(title) {\n const currentWidth = getTitleWidth(title);\n return Math.max(0, XHS_TITLE_CONSTRAINTS.MAX_WIDTH - currentWidth);\n}\n/**\n * Truncate title to fit within width limit\n *\n * @param title - The title to truncate\n * @param maxWidth - Maximum width (default: XHS_TITLE_CONSTRAINTS.MAX_WIDTH)\n * @returns Truncated title that fits within width limit\n *\n * @example\n * ```typescript\n * const long = '这是一个很长很长的标题'.repeat(5);\n * const truncated = truncateTitleToWidth(long);\n * console.log(getTitleWidth(truncated)); // <= 40\n * ```\n */\nfunction truncateTitleToWidth(title, maxWidth = XHS_TITLE_CONSTRAINTS.MAX_WIDTH) {\n if (getTitleWidth(title) <= maxWidth) {\n return title;\n }\n let truncated = '';\n let currentWidth = 0;\n for (const char of title) {\n const charWidth = stringWidth(char);\n if (currentWidth + charWidth > maxWidth) {\n break;\n }\n truncated += char;\n currentWidth += charWidth;\n }\n return truncated;\n}\n/**\n * Get human-readable width breakdown\n * Useful for debugging and user feedback\n *\n * @param title - The title to analyze\n * @returns Width breakdown information\n */\nfunction getTitleWidthBreakdown(title) {\n const totalWidth = getTitleWidth(title);\n const breakdown = [];\n for (const char of title) {\n const charWidth = stringWidth(char);\n let type = 'Other';\n const code = char.charCodeAt(0);\n if (char.match(/[\\u4e00-\\u9fff\\u3400-\\u4dbf\\uf900-\\ufaff]/)) {\n type = 'CJK';\n }\n else if (code < 128) {\n type = 'ASCII';\n }\n else if (char.match(/[\\u{1F300}-\\u{1F9FF}]/u)) {\n type = 'Emoji';\n }\n breakdown.push({ char, width: charWidth, type });\n }\n return {\n title,\n totalWidth,\n totalChars: title.length,\n maxWidth: XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n remaining: calculateRemainingTitleWidth(title),\n valid: totalWidth <= XHS_TITLE_CONSTRAINTS.MAX_WIDTH,\n breakdown,\n };\n}\n\n// EXTERNAL MODULE: external \"fs\"\nvar external_fs_ = __webpack_require__(9896);\n// EXTERNAL MODULE: external \"path\"\nvar external_path_ = __webpack_require__(6928);\n;// external \"crypto\"\nconst external_crypto_namespaceObject = require(\"crypto\");\n;// external \"node-fetch\"\nconst external_node_fetch_namespaceObject = require(\"node-fetch\");\nvar external_node_fetch_default = /*#__PURE__*/__webpack_require__.n(external_node_fetch_namespaceObject);\n;// ./src/shared/image-downloader.ts\n/**\n * Image downloader utility for XHS MCP Server\n * Supports downloading images from HTTP/HTTPS URLs\n */\n\n\n\n\n\n\nclass ImageDownloader {\n saveDir;\n timeout;\n maxFileSize;\n constructor(saveDir = './temp_images', timeout = 30000, maxFileSize = 10 * 1024 * 1024 // 10MB default\n ) {\n this.saveDir = saveDir;\n this.timeout = timeout;\n this.maxFileSize = maxFileSize;\n // Ensure save directory exists\n if (!(0,external_fs_.existsSync)(this.saveDir)) {\n (0,external_fs_.mkdirSync)(this.saveDir, { recursive: true });\n }\n }\n /**\n * Check if a string is a valid HTTP/HTTPS URL\n */\n static isImageUrl(path) {\n if (!path)\n return false;\n const lowerPath = path.toLowerCase().trim();\n return lowerPath.startsWith('http://') || lowerPath.startsWith('https://');\n }\n /**\n * Generate a unique filename for an image URL\n * Uses only URL hash for consistent caching\n */\n generateFileName(imageUrl) {\n // Use SHA256 hash of URL for uniqueness\n const hash = (0,external_crypto_namespaceObject.createHash)('sha256').update(imageUrl).digest('hex');\n const shortHash = hash.substring(0, 16);\n // Try to extract extension from URL\n let extension = 'jpg'; // default\n try {\n const url = new URL(imageUrl);\n const pathname = url.pathname.toLowerCase();\n const match = pathname.match(/\\.(jpg|jpeg|png|gif|webp|bmp)$/i);\n if (match) {\n extension = match[1];\n }\n }\n catch {\n // Use default extension\n }\n // Fixed filename for proper caching (no timestamp)\n return `img_${shortHash}.${extension}`;\n }\n /**\n * Validate that downloaded data is actually an image\n */\n validateImageData(buffer) {\n // Check file signatures (magic numbers)\n if (buffer.length < 12) {\n return { isValid: false, extension: '' };\n }\n // JPEG\n if (buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff) {\n return { isValid: true, extension: 'jpg' };\n }\n // PNG\n if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47) {\n return { isValid: true, extension: 'png' };\n }\n // GIF\n if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46) {\n return { isValid: true, extension: 'gif' };\n }\n // WebP\n if (buffer[0] === 0x52 &&\n buffer[1] === 0x49 &&\n buffer[2] === 0x46 &&\n buffer[3] === 0x46 &&\n buffer[8] === 0x57 &&\n buffer[9] === 0x45 &&\n buffer[10] === 0x42 &&\n buffer[11] === 0x50) {\n return { isValid: true, extension: 'webp' };\n }\n // BMP\n if (buffer[0] === 0x42 && buffer[1] === 0x4d) {\n return { isValid: true, extension: 'bmp' };\n }\n return { isValid: false, extension: '' };\n }\n /**\n * Download a single image from URL\n */\n async downloadImage(imageUrl) {\n // Validate URL format\n if (!ImageDownloader.isImageUrl(imageUrl)) {\n throw new shared_errors/* InvalidImageError */.TD(`Invalid image URL format: ${imageUrl}`, {\n url: imageUrl,\n suggestion: 'URL must start with http:// or https://',\n });\n }\n // Generate filename and path\n const fileName = this.generateFileName(imageUrl);\n const localPath = (0,external_path_.join)(this.saveDir, fileName);\n // Check if file already exists (cache)\n if ((0,external_fs_.existsSync)(localPath)) {\n const stats = (0,external_fs_.statSync)(localPath);\n logger/* logger */.v.debug(`Using cached image: ${localPath}`);\n return {\n originalUrl: imageUrl,\n localPath,\n cached: true,\n fileSize: stats.size,\n };\n }\n logger/* logger */.v.debug(`Downloading image from: ${imageUrl}`);\n try {\n // Download image with timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n const response = await external_node_fetch_default()(imageUrl, {\n signal: controller.signal,\n headers: {\n 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',\n },\n });\n clearTimeout(timeoutId);\n if (!response.ok) {\n throw new shared_errors/* InvalidImageError */.TD(`Failed to download image: HTTP ${response.status} ${response.statusText}`, {\n url: imageUrl,\n statusCode: response.status,\n statusText: response.statusText,\n });\n }\n // Check Content-Length if available\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength) > this.maxFileSize) {\n throw new shared_errors/* InvalidImageError */.TD(`Image file too large: ${(parseInt(contentLength) / 1024 / 1024).toFixed(2)}MB (max: ${(this.maxFileSize / 1024 / 1024).toFixed(2)}MB)`, {\n url: imageUrl,\n fileSize: parseInt(contentLength),\n maxSize: this.maxFileSize,\n suggestion: 'Try using a smaller image or increase maxFileSize',\n });\n }\n // Get image data\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n // Verify actual size\n if (buffer.length > this.maxFileSize) {\n throw new shared_errors/* InvalidImageError */.TD(`Downloaded file too large: ${(buffer.length / 1024 / 1024).toFixed(2)}MB (max: ${(this.maxFileSize /\n 1024 /\n 1024).toFixed(2)}MB)`, {\n url: imageUrl,\n fileSize: buffer.length,\n maxSize: this.maxFileSize,\n });\n }\n // Validate it's actually an image\n const validation = this.validateImageData(buffer);\n if (!validation.isValid) {\n throw new shared_errors/* InvalidImageError */.TD(`Downloaded file is not a valid image: ${imageUrl}`, {\n url: imageUrl,\n suggestion: 'Make sure the URL points to an actual image file',\n });\n }\n // Save to file\n (0,external_fs_.writeFileSync)(localPath, buffer);\n logger/* logger */.v.debug(`Image downloaded successfully: ${localPath} (${buffer.length} bytes)`);\n return {\n originalUrl: imageUrl,\n localPath,\n cached: false,\n fileSize: buffer.length,\n };\n }\n catch (error) {\n if (error instanceof shared_errors/* InvalidImageError */.TD) {\n throw error;\n }\n // Handle abort error\n if (error instanceof Error && error.name === 'AbortError') {\n throw new shared_errors/* InvalidImageError */.TD(`Image download timeout after ${this.timeout}ms: ${imageUrl}`, {\n url: imageUrl,\n timeout: this.timeout,\n suggestion: 'The image may be too large or the network is slow',\n }, error);\n }\n throw new shared_errors/* InvalidImageError */.TD(`Failed to download image: ${imageUrl}`, {\n url: imageUrl,\n }, error);\n }\n }\n /**\n * Download multiple images from URLs (parallel download for better performance)\n */\n async downloadImages(imageUrls) {\n // Download all images in parallel\n const downloadPromises = imageUrls.map((url) => this.downloadImage(url).catch((error) => ({ error, url })));\n const results = await Promise.all(downloadPromises);\n const successResults = [];\n const errors = [];\n results.forEach((result) => {\n if ('error' in result) {\n errors.push({ url: result.url, error: result.error });\n }\n else {\n successResults.push(result);\n }\n });\n // If any downloads failed, throw an error with details\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => `${e.url}: ${e.error.message}`).join('\\n');\n throw new shared_errors/* InvalidImageError */.TD(`Failed to download ${errors.length} of ${imageUrls.length} images:\\n${errorMessages}`, {\n totalCount: imageUrls.length,\n failedCount: errors.length,\n successCount: successResults.length,\n failedUrls: errors.map((e) => e.url),\n });\n }\n return successResults;\n }\n /**\n * Process a list of image paths - download URLs and keep local paths as-is\n */\n async processImagePaths(imagePaths) {\n const localPaths = [];\n const urlsToDownload = [];\n // Separate URLs from local paths\n for (const path of imagePaths) {\n if (ImageDownloader.isImageUrl(path)) {\n urlsToDownload.push(path);\n }\n else {\n // Validate local path exists\n if (!(0,external_fs_.existsSync)(path)) {\n throw new shared_errors/* InvalidImageError */.TD(`Local image file not found: ${path}`, {\n path,\n suggestion: 'Make sure the file path is correct and the file exists',\n });\n }\n localPaths.push(path);\n }\n }\n // Download URLs if any\n if (urlsToDownload.length > 0) {\n logger/* logger */.v.debug(`Downloading ${urlsToDownload.length} images from URLs...`);\n const downloadResults = await this.downloadImages(urlsToDownload);\n const downloadedPaths = downloadResults.map((r) => r.localPath);\n localPaths.push(...downloadedPaths);\n // Log download summary\n const cachedCount = downloadResults.filter((r) => r.cached).length;\n const newCount = downloadResults.filter((r) => !r.cached).length;\n logger/* logger */.v.debug(`Downloaded ${newCount} new images, used ${cachedCount} cached images`);\n }\n if (localPaths.length === 0) {\n throw new shared_errors/* InvalidImageError */.TD('No valid images found', {\n providedPaths: imagePaths.length,\n suggestion: 'Provide at least one valid image URL or local file path',\n });\n }\n return localPaths;\n }\n /**\n * Get the save directory path\n */\n getSaveDir() {\n return this.saveDir;\n }\n}\n// Export a default instance\nlet defaultDownloader = null;\nfunction getImageDownloader(saveDir) {\n if (!defaultDownloader || (saveDir && defaultDownloader.getSaveDir() !== saveDir)) {\n defaultDownloader = new ImageDownloader(saveDir);\n }\n return defaultDownloader;\n}\n\n// EXTERNAL MODULE: ./src/shared/selectors.ts\nvar selectors = __webpack_require__(805);\n;// ./src/core/publishing/publish-base.service.ts\n/**\n * Publishing service for XHS MCP Server\n */\n\n\n\n\n\n\n// Constants for video publishing\nconst VIDEO_TIMEOUTS = {\n PAGE_LOAD: 3000,\n TAB_SWITCH: 2000,\n VIDEO_PROCESSING: 10000,\n CONTENT_WAIT: 1000,\n UPLOAD_READY: 1000,\n UPLOAD_START: 3000,\n PROCESSING_CHECK: 3000,\n COMPLETION_CHECK: 2000,\n PROCESSING_TIMEOUT: 120000, // 2 minutes\n COMPLETION_TIMEOUT: 300000, // 5 minutes\n};\nconst SELECTORS = {\n FILE_INPUT: selectors/* COMMON_FILE_SELECTORS */.mR.FILE_INPUT,\n SUCCESS_INDICATORS: selectors/* COMMON_STATUS_SELECTORS */.aB.SUCCESS,\n ERROR_INDICATORS: selectors/* COMMON_STATUS_SELECTORS */.aB.ERROR,\n PROCESSING_INDICATORS: selectors/* COMMON_STATUS_SELECTORS */.aB.PROCESSING,\n COMPLETION_INDICATORS: [\n '.upload-complete',\n '.processing-complete',\n '.video-ready',\n '[class*=\"complete\"]',\n '[class*=\"ready\"]',\n ],\n TOAST_SELECTORS: selectors/* COMMON_STATUS_SELECTORS */.aB.TOAST,\n PUBLISH_PAGE_INDICATORS: [\n 'div.upload-content',\n 'div.submit',\n '.creator-editor',\n '.video-upload-container',\n 'input[type=\"file\"]',\n ],\n};\nconst TEXT_PATTERNS = selectors/* COMMON_TEXT_PATTERNS */.mu;\nclass PublishBaseService extends base_service/* BaseService */.d {\n imageDownloader;\n constructor(config, browserManager) {\n super(config, browserManager);\n this.imageDownloader = new ImageDownloader('./temp_images');\n }\n // Helper methods for element detection and text matching\n async findElementBySelectors(page, selectors) {\n for (const selector of selectors) {\n const element = await page.$(selector);\n if (element) {\n logger/* logger */.v.debug(`Found element with selector: ${selector}`);\n return element;\n }\n }\n return null;\n }\n async getElementText(element) {\n try {\n return await element.page().evaluate((el) => el.textContent, element);\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to get element text: ${error}`);\n return null;\n }\n }\n async checkTextPatterns(text, patterns) {\n if (!text)\n return false;\n return patterns.some((pattern) => text.includes(pattern));\n }\n async checkElementForPatterns(page, selectors, patterns) {\n for (const selector of selectors) {\n const element = await page.$(selector);\n if (element) {\n const text = await this.getElementText(element);\n if (text && (await this.checkTextPatterns(text, patterns))) {\n return { found: true, text, element };\n }\n }\n }\n return { found: false };\n }\n async waitForCondition(condition, timeout, checkInterval = 1000, errorMessage) {\n const startTime = Date.now();\n while (Date.now() - startTime < timeout) {\n if (await condition()) {\n return;\n }\n await (0,utils/* sleep */.yy)(checkInterval);\n }\n throw new shared_errors/* PublishError */.S1(errorMessage);\n }\n async fillTitle(page, title) {\n // Wait for a likely title input to appear\n try {\n await page.waitForSelector('input.c-input_inner, input.c-input, input[placeholder*=\"标题\"], .title-input input, input[class*=\"title\"]', { timeout: 10000 });\n }\n catch (error) {\n // Continue without waiting if not found purely by selector\n }\n const titleSelectors = [\n 'input.c-input_inner', // specific for recent Xiaohongshu creator UI\n 'input.c-input',\n 'input[placeholder*=\"标题\"]',\n 'input[placeholder*=\"填写标题会有更多赞哦\"]',\n 'input[placeholder*=\"title\"]',\n 'input[data-placeholder*=\"标题\"]',\n '.title-input input',\n 'input[placeholder*=\"请输入标题\"]',\n 'input[name=\"title\"]',\n 'input[id*=\"title\"]',\n 'input[class*=\"title\"]',\n 'input[type=\"text\"]', // Fallbacks\n 'div[contenteditable=\"true\"]',\n 'textarea[placeholder*=\"标题\"]',\n 'textarea[placeholder*=\"title\"]',\n ];\n for (const selector of titleSelectors) {\n try {\n const titleInput = await page.$(selector);\n if (titleInput) {\n // Scroll into view just in case it's off screen\n await page.evaluate((el) => {\n if (el && typeof el.scrollIntoView === 'function') {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n }, titleInput);\n await (0,utils/* sleep */.yy)(500);\n const isVisible = await titleInput.isIntersectingViewport();\n if (isVisible) {\n await titleInput.click();\n await (0,utils/* sleep */.yy)(500); // Wait for focus\n // clear existing input if any\n await titleInput.click({ clickCount: 3 });\n await titleInput.press('Backspace');\n await titleInput.type(title);\n return;\n }\n }\n }\n catch (error) {\n // Continue to next selector\n }\n }\n // If no specific input found, try to find any visible input or textarea on the page\n try {\n const allInputs = await page.$$('input, textarea');\n for (let i = 0; i < allInputs.length; i++) {\n const input = allInputs[i];\n try {\n const type = await page.evaluate((el) => el.getAttribute('type'), input);\n // avoid file inputs or hidden inputs\n if (type !== 'file' && type !== 'hidden') {\n await page.evaluate((el) => {\n if (el && typeof el.scrollIntoView === 'function') {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n }, input);\n await (0,utils/* sleep */.yy)(500);\n const isVisible = await input.isIntersectingViewport();\n if (isVisible) {\n await input.click();\n await (0,utils/* sleep */.yy)(500);\n // clear existing input if any\n await input.click({ clickCount: 3 });\n await input.press('Backspace');\n await input.type(title);\n return;\n }\n }\n }\n catch (error) {\n // Continue to next input\n }\n }\n }\n catch (error) {\n // Fall through to error\n }\n throw new shared_errors/* PublishError */.S1('Could not find title input field');\n }\n async findContentElement(page) {\n try {\n // Strategy 1: Try div[contenteditable=\"true\"] (simple and direct)\n const contentEditable = await page.$('div[contenteditable=\"true\"]');\n if (contentEditable) {\n const isVisible = await contentEditable.isIntersectingViewport();\n if (isVisible) {\n return contentEditable;\n }\n }\n // Strategy 2: Try div.tiptap.ProseMirror (primary selector for creator platform)\n const tiptapEditor = await page.$('div.tiptap.ProseMirror');\n if (tiptapEditor) {\n const isVisible = await tiptapEditor.isIntersectingViewport();\n if (isVisible) {\n return tiptapEditor;\n }\n }\n // Strategy 3: Try div[role=\"textbox\"][contenteditable=\"true\"] (specific selector)\n const roleTextbox = await page.$('div[role=\"textbox\"][contenteditable=\"true\"]');\n if (roleTextbox) {\n const isVisible = await roleTextbox.isIntersectingViewport();\n if (isVisible) {\n return roleTextbox;\n }\n }\n // Strategy 4: Try div.ql-editor (legacy selector)\n const qlEditor = await page.$('div.ql-editor');\n if (qlEditor) {\n return qlEditor;\n }\n // Strategy 5: Try to find textarea or contenteditable\n const contentSelectors = [\n '.tiptap.ProseMirror',\n 'textarea[placeholder*=\"正文\"]',\n 'textarea[multiline]',\n 'div[data-placeholder*=\"正文\"]',\n '.content-editor',\n 'div[role=\"textbox\"]',\n 'textbox[role=\"textbox\"]',\n 'textbox[multiline]',\n ];\n for (const selector of contentSelectors) {\n const element = await page.$(selector);\n if (element) {\n return element;\n }\n }\n // Strategy 6: Try to find any multiline textbox (fallback)\n const multilineTextboxes = await page.$$('textbox[multiline]');\n for (const element of multilineTextboxes) {\n const isVisible = await element.isIntersectingViewport();\n if (isVisible) {\n return element;\n }\n }\n return null;\n }\n catch (error) {\n return null;\n }\n }\n async findTextboxByPlaceholder(page) {\n try {\n // Find all p elements\n const pElements = await page.$$('p');\n // Look for element with data-placeholder containing \"输入正文描述\"\n for (const p of pElements) {\n const placeholder = await page.evaluate((el) => el.getAttribute('data-placeholder'), p);\n if (placeholder?.includes('输入正文描述')) {\n return p;\n }\n }\n return null;\n }\n catch (error) {\n return null;\n }\n }\n async findTextboxParent(page, element) {\n try {\n return await page.evaluateHandle((el) => el.parentElement, element);\n }\n catch (error) {\n return null;\n }\n }\n async fillContent(page, content) {\n // Wait for content area to appear\n try {\n await page.waitForSelector('div[role=\"textbox\"][contenteditable=\"true\"], .tiptap.ProseMirror, div[contenteditable=\"true\"], textarea, [role=\"textbox\"], .ql-editor, textbox[multiline]', { timeout: 10000 });\n }\n catch (error) {\n // Continue without waiting\n }\n let contentElement = await this.findContentElement(page);\n if (!contentElement) {\n // Try alternative approach\n const textboxElement = await this.findTextboxByPlaceholder(page);\n if (textboxElement) {\n contentElement = await this.findTextboxParent(page, textboxElement);\n }\n }\n if (!contentElement) {\n // Try to find any contenteditable or textarea element\n try {\n const allContentElements = await page.$$('div[role=\"textbox\"][contenteditable=\"true\"], .tiptap.ProseMirror, div[contenteditable=\"true\"], textarea, [role=\"textbox\"], .ql-editor, p[contenteditable=\"true\"], textbox[multiline]');\n for (let i = 0; i < allContentElements.length; i++) {\n const element = allContentElements[i];\n try {\n const isVisible = await element.isIntersectingViewport();\n const tagName = await page.evaluate((el) => el.tagName, element);\n const contentEditable = await page.evaluate((el) => el.getAttribute('contenteditable'), element);\n const role = await page.evaluate((el) => el.getAttribute('role'), element);\n const className = await page.evaluate((el) => el.className, element);\n const multiline = await page.evaluate((el) => el.getAttribute('multiline'), element);\n if (isVisible &&\n (contentEditable === 'true' ||\n tagName === 'TEXTAREA' ||\n role === 'textbox' ||\n className.includes('ql-editor') ||\n className.includes('tiptap') ||\n multiline === '')) {\n contentElement = element;\n break;\n }\n }\n catch (error) {\n // Continue to next element\n }\n }\n }\n catch (error) {\n // Continue to next strategy\n }\n }\n if (!contentElement) {\n // Last resort: try to find any element that might be for content\n try {\n const allElements = await page.$$('*');\n for (let i = 0; i < Math.min(allElements.length, 50); i++) {\n // Limit to first 50 elements\n const element = allElements[i];\n try {\n const isVisible = await element.isIntersectingViewport();\n const tagName = await page.evaluate((el) => el.tagName, element);\n const contentEditable = await page.evaluate((el) => el.getAttribute('contenteditable'), element);\n const className = await page.evaluate((el) => el.className, element);\n const placeholder = await page.evaluate((el) => el.getAttribute('placeholder'), element);\n if (isVisible &&\n (contentEditable === 'true' ||\n tagName === 'TEXTAREA' ||\n className.includes('content') ||\n className.includes('editor') ||\n placeholder?.includes('内容') ||\n placeholder?.includes('正文'))) {\n contentElement = element;\n break;\n }\n }\n catch (error) {\n // Ignore errors for individual elements\n }\n }\n }\n catch (error) {\n // Fall through to error\n }\n }\n if (!contentElement) {\n throw new shared_errors/* PublishError */.S1('Could not find content input field');\n }\n try {\n await contentElement.click();\n await (0,utils/* sleep */.yy)(500); // Wait for focus\n await contentElement.type(content);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to fill content: ${error}`);\n }\n }\n async inputTags(page, contentElement, tags) {\n const tagList = tags\n .split(',')\n .map((tag) => tag.trim())\n .filter((tag) => tag.length > 0);\n for (const tag of tagList) {\n await this.inputTag(page, contentElement, tag);\n }\n }\n async inputTag(page, contentElement, tag) {\n try {\n // Type the tag\n await contentElement.type(`#${tag}`);\n await (0,utils/* sleep */.yy)(1000);\n // Try to find topic suggestion container\n const topicContainer = await page.$('#creator-editor-topic-container');\n if (topicContainer) {\n const firstItem = await topicContainer.$('.item');\n if (firstItem) {\n await firstItem.click();\n await (0,utils/* sleep */.yy)(500);\n }\n }\n else {\n // Press Enter to confirm the tag\n await contentElement.press('Enter');\n await (0,utils/* sleep */.yy)(500);\n // Press Space to separate tags\n await contentElement.press('Space');\n await (0,utils/* sleep */.yy)(200);\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to add tag ${tag}: ${error}`);\n }\n }\n async addTags(page, tags) {\n try {\n const contentElement = await this.findContentElement(page);\n if (contentElement) {\n await this.inputTags(page, contentElement, tags);\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to add tags: ${error}`);\n }\n }\n async submitPost(page) {\n try {\n // Strategy 1: Look for the <xhs-publish-btn> custom element (new XHS UI)\n let submitButton = null;\n const customBtn = await page.$('xhs-publish-btn');\n if (customBtn) {\n // Verify it has the right attributes (is-publish=\"true\", submit-text=\"发布\")\n const attrs = await customBtn.evaluate((el) => ({\n isPublish: el.getAttribute('is-publish'),\n submitText: el.getAttribute('submit-text'),\n submitDisabled: el.getAttribute('submit-disabled'),\n }));\n logger/* logger */.v.debug(`Found xhs-publish-btn custom element: ${JSON.stringify(attrs)}`);\n if (attrs.isPublish === 'true' || attrs.submitText === '发布') {\n submitButton = customBtn;\n }\n }\n // Strategy 2: Look for standard button elements containing \"发布\"\n if (!submitButton) {\n const buttons = await page.$$('button');\n for (const btn of buttons) {\n const text = await btn.evaluate(el => el.textContent?.trim());\n if (text?.includes('发布')) {\n submitButton = btn;\n break;\n }\n }\n }\n if (!submitButton) {\n // Strategy 3: search all visible div/span elements containing \"发布\" text\n const textCandidates = await page.$$('div, span');\n for (const el of textCandidates) {\n try {\n const text = await el.evaluate(el => el.textContent?.trim());\n if (text?.includes('发布') && text.length < 20) {\n const isVisible = await el.isIntersectingViewport().catch(() => false);\n if (isVisible) {\n submitButton = el;\n break;\n }\n }\n }\n catch {\n continue;\n }\n }\n }\n if (!submitButton) {\n const submitSelector = 'div.submit, .submit-btn, .publish-btn, [class*=\"publish\"], [class*=\"btn-\"], .btn-text';\n submitButton = await page.$(submitSelector);\n }\n // Strategy 5: XPath text match\n if (!submitButton) {\n const publishTexts = ['发布笔记', '发布', '发表'];\n for (const text of publishTexts) {\n const elements = await page.$x(`//*[contains(text(), '${text}')]`);\n for (const el of elements) {\n try {\n const rect = await el.evaluate((el) => {\n const r = el.getBoundingClientRect();\n return { w: r.width, h: r.height };\n });\n if (rect.w > 0 && rect.h > 0) {\n submitButton = el;\n break;\n }\n }\n catch {\n continue;\n }\n }\n if (submitButton)\n break;\n }\n }\n // Strategy 6: Find .btn-text span and click parent\n if (!submitButton) {\n const btnTextEl = await page.$('.btn-text');\n if (btnTextEl) {\n const text = await btnTextEl.evaluate(el => el.textContent?.trim());\n if (text?.includes('发布')) {\n const parent = await btnTextEl.evaluateHandle(el => el.closest('[class*=\"publish\"], [class*=\"btn-\"]') || el.parentElement);\n if (parent) {\n submitButton = parent;\n }\n }\n }\n }\n if (!submitButton) {\n // Debug: dump key info about the page state\n const debugInfo = await page.evaluate(() => {\n // Find all elements mentioning 发布\n const publishElements = [];\n document.querySelectorAll('*').forEach(el => {\n const text = el.textContent?.trim();\n if (text?.includes('发布')) {\n const rect = el.getBoundingClientRect();\n publishElements.push({\n tag: el.tagName,\n text: text.substring(0, 30),\n class: el.className?.substring(0, 80),\n visible: rect.width > 0 && rect.height > 0,\n rect: `${rect.width.toFixed(0)}x${rect.height.toFixed(0)} at ${rect.top.toFixed(0)},${rect.left.toFixed(0)}`,\n });\n }\n });\n return {\n url: window.location.href,\n bodyHeight: document.body.scrollHeight,\n viewportHeight: window.innerHeight,\n publishElements: publishElements.slice(0, 40),\n };\n });\n throw new shared_errors/* PublishError */.S1(`Could not find submit button. URL=${debugInfo.url}, body=${debugInfo.bodyHeight}, vp=${debugInfo.viewportHeight}, publishElems=${JSON.stringify(debugInfo.publishElements)}`);\n }\n // Pre-click checks: ensure button is enabled and clickable\n const buttonState = await page.evaluate((el) => {\n if (!el)\n return { exists: false };\n const htmlEl = el;\n const style = window.getComputedStyle(htmlEl);\n return {\n exists: true,\n disabled: htmlEl.hasAttribute('disabled') || htmlEl.getAttribute('aria-disabled') === 'true',\n pointerEvents: style.pointerEvents,\n opacity: style.opacity,\n visibility: style.visibility,\n display: style.display,\n tagName: htmlEl.tagName,\n className: htmlEl.className,\n text: htmlEl.textContent?.trim().substring(0, 20),\n };\n }, submitButton);\n logger/* logger */.v.debug(`Submit button state: ${JSON.stringify(buttonState)}`);\n if (buttonState.disabled) {\n logger/* logger */.v.warn('Submit button is disabled - publishing may fail');\n }\n // Scroll to button before clicking\n await page.evaluate((el) => {\n if (el && typeof el.scrollIntoView === 'function') {\n el.scrollIntoView({ behavior: 'instant', block: 'center' });\n }\n }, submitButton);\n await (0,utils/* sleep */.yy)(500);\n // Helper to check if publish was triggered (page navigating away or showing success)\n const isPublishTriggered = async () => {\n try {\n const currentUrl = page.url();\n const bodyText = await page.evaluate(() => document.body?.textContent || '');\n return !currentUrl.includes('/publish/publish') ||\n bodyText.includes('发布成功') ||\n bodyText.includes('审核中');\n }\n catch {\n return false;\n }\n };\n // Strategy A: For xhs-publish-btn custom element, dispatch a CustomEvent('publish')\n const isCustomElement = await submitButton.evaluate((el) => el.tagName === 'XHS-PUBLISH-BTN');\n if (isCustomElement) {\n try {\n await page.evaluate((el) => {\n if (!el)\n return;\n el.dispatchEvent(new CustomEvent('publish', { bubbles: true, composed: true }));\n }, submitButton);\n logger/* logger */.v.debug('Dispatched CustomEvent(\"publish\") on xhs-publish-btn');\n }\n catch (customEventError) {\n logger/* logger */.v.debug(`CustomEvent dispatch failed: ${customEventError}`);\n }\n await (0,utils/* sleep */.yy)(1500);\n if (await isPublishTriggered())\n return;\n }\n // Strategy B: Full React event chain via evaluate (fallback for standard elements)\n try {\n await page.evaluate((el) => {\n if (!el)\n return;\n const htmlEl = el;\n const rect = htmlEl.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n const eventInit = { bubbles: true, cancelable: true, composed: true, clientX: x, clientY: y, screenX: x, screenY: y };\n const events = [\n new MouseEvent('mouseenter', eventInit),\n new MouseEvent('mouseover', eventInit),\n new MouseEvent('mousemove', eventInit),\n new MouseEvent('mousedown', { ...eventInit, button: 0, buttons: 1 }),\n new FocusEvent('focus', { bubbles: true }),\n new MouseEvent('mouseup', { ...eventInit, button: 0, buttons: 0 }),\n new MouseEvent('click', { ...eventInit, button: 0, buttons: 0 }),\n ];\n events.forEach((ev) => htmlEl.dispatchEvent(ev));\n }, submitButton);\n logger/* logger */.v.debug('Dispatched full React event chain on submit button');\n }\n catch (chainError) {\n logger/* logger */.v.debug(`React event chain failed: ${chainError}`);\n }\n await (0,utils/* sleep */.yy)(1000);\n if (await isPublishTriggered())\n return;\n // Strategy C: Puppeteer native click as fallback\n try {\n await submitButton.click();\n logger/* logger */.v.debug('Clicked submit button via Puppeteer native click');\n }\n catch (clickError) {\n logger/* logger */.v.debug(`Puppeteer click failed: ${clickError}`);\n }\n await (0,utils/* sleep */.yy)(800);\n if (await isPublishTriggered())\n return;\n // Strategy D: JavaScript click via evaluate\n try {\n await page.evaluate((el) => { if (el)\n el.click(); }, submitButton);\n logger/* logger */.v.debug('Clicked submit button via JS evaluate click');\n }\n catch (jsClickError) {\n logger/* logger */.v.debug(`JS evaluate click failed: ${jsClickError}`);\n }\n await (0,utils/* sleep */.yy)(800);\n if (await isPublishTriggered())\n return;\n // Strategy E: Try clicking via page.mouse at element center coordinates\n try {\n const box = await submitButton.boundingBox();\n if (box) {\n await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);\n await page.mouse.down();\n await (0,utils/* sleep */.yy)(50);\n await page.mouse.up();\n logger/* logger */.v.debug('Clicked submit button via mouse coordinates');\n }\n }\n catch (mouseError) {\n logger/* logger */.v.debug(`Mouse click failed: ${mouseError}`);\n }\n await (0,utils/* sleep */.yy)(1500);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to click submit button: ${error}`);\n }\n }\n async isElementVisible(element) {\n try {\n return await element.isIntersectingViewport();\n }\n catch (error) {\n return false;\n }\n }\n async waitForPublishCompletion(page) {\n const maxWaitTime = 30000; // 30 seconds (reduced from 60s)\n const startTime = Date.now();\n const publishStartUrl = page.url();\n while (Date.now() - startTime < maxWaitTime) {\n const currentUrl = page.url();\n // Strategy 1: Check for success indicators via CSS selectors\n const successIndicators = [\n '.success-message',\n '.publish-success',\n '[data-testid=\"publish-success\"]',\n '.toast-success',\n ];\n for (const selector of successIndicators) {\n const element = await page.$(selector);\n if (element) {\n logger/* logger */.v.debug(`Found success indicator: ${selector}`);\n await (0,utils/* sleep */.yy)(2000);\n return await this.extractNoteIdFromPage(page);\n }\n }\n // Strategy 2: Check for error indicators\n const errorIndicators = [\n '.error-message',\n '.publish-error',\n '[data-testid=\"publish-error\"]',\n '.toast-error',\n '.error-toast',\n ];\n for (const selector of errorIndicators) {\n const element = await page.$(selector);\n if (element) {\n const errorText = await page.evaluate((el) => el.textContent, element);\n throw new shared_errors/* PublishError */.S1(`Publish failed with error: ${errorText}`);\n }\n }\n // Strategy 3: Check if we're still on the publish page\n const publishPageIndicators = ['div.upload-content', 'div.submit', '.creator-editor'];\n let stillOnPublishPage = false;\n for (const selector of publishPageIndicators) {\n const element = await page.$(selector);\n if (element) {\n stillOnPublishPage = true;\n break;\n }\n }\n if (!stillOnPublishPage) {\n logger/* logger */.v.debug('Left publish page, assuming success');\n return await this.extractNoteIdFromPage(page);\n }\n // Strategy 4: Check for toast/popup messages with text content\n const toastSelectors = ['.toast', '.message', '.notification', '[role=\"alert\"]'];\n for (const selector of toastSelectors) {\n const element = await page.$(selector);\n if (element) {\n const toastText = await page.evaluate((el) => el.textContent, element);\n if (toastText) {\n if (toastText.includes('成功') || toastText.includes('success')) {\n logger/* logger */.v.debug(`Found success toast: ${toastText}`);\n return await this.extractNoteIdFromPage(page);\n }\n else if (toastText.includes('失败') ||\n toastText.includes('error') ||\n toastText.includes('错误')) {\n throw new shared_errors/* PublishError */.S1(`Publish failed: ${toastText}`);\n }\n }\n }\n }\n // Strategy 5: Broad text-based success detection\n const textSuccessElements = await page.$$('div, span, p, h1, h2, h3, button');\n for (const el of textSuccessElements) {\n try {\n const text = await el.evaluate((e) => e.textContent?.trim());\n if (text && text.length < 50) {\n if (text.includes('发布成功') || text.includes('投稿成功') || text.includes('审核中')) {\n logger/* logger */.v.debug(`Found text success indicator: ${text}`);\n return await this.extractNoteIdFromPage(page);\n }\n if (text.includes('发布失败') || text.includes('投稿失败')) {\n throw new shared_errors/* PublishError */.S1(`Publish failed: ${text}`);\n }\n }\n }\n catch {\n continue;\n }\n }\n // Strategy 6: URL change detection (navigated away from publish page)\n if (currentUrl !== publishStartUrl) {\n const isPublishUrl = currentUrl.includes('/publish') || currentUrl.includes('/creator');\n if (!isPublishUrl) {\n logger/* logger */.v.debug(`URL changed from publish page to ${currentUrl}, assuming success`);\n return await this.extractNoteIdFromPage(page);\n }\n }\n // Strategy 7: Check for loading/success overlays\n const overlaySelectors = ['.modal', '.popup', '.dialog', '.overlay', '[class*=\"success\"]', '[class*=\"modal\"]'];\n for (const selector of overlaySelectors) {\n const element = await page.$(selector);\n if (element) {\n try {\n const isVisible = await element.isIntersectingViewport().catch(() => false);\n if (isVisible) {\n const text = await element.evaluate((e) => e.textContent?.trim());\n if (text && (text.includes('成功') || text.includes('发布'))) {\n logger/* logger */.v.debug(`Found overlay with success text: ${text.substring(0, 50)}`);\n return await this.extractNoteIdFromPage(page);\n }\n }\n }\n catch {\n continue;\n }\n }\n }\n await (0,utils/* sleep */.yy)(800); // Wait before next check\n }\n // Timeout: collect debug info\n const debugInfo = await page.evaluate(() => {\n const allTexts = [];\n document.querySelectorAll('div, span, p, h1, h2, h3, button').forEach((el) => {\n const text = el.textContent?.trim();\n if (text && text.length > 0 && text.length < 100) {\n allTexts.push(text);\n }\n });\n return {\n url: window.location.href,\n bodyText: document.body?.textContent?.substring(0, 500) || '',\n visibleTexts: allTexts.filter((t, i, arr) => arr.indexOf(t) === i).slice(0, 30),\n };\n });\n logger/* logger */.v.debug(`Publish timeout debug - URL: ${debugInfo.url}`);\n logger/* logger */.v.debug(`Visible texts: ${debugInfo.visibleTexts.join(' | ')}`);\n // Check if page left publish URL (even if not detected earlier) - assume success\n const isStillOnPublishUrl = debugInfo.url.includes('/publish');\n const hasErrorText = debugInfo.visibleTexts.some((t) => t.includes('失败') || t.includes('错误') || t.includes('error') || t.includes('无法'));\n if (!isStillOnPublishUrl || !hasErrorText) {\n logger/* logger */.v.warn(`Publish completion timed out but no error detected. Assuming success. URL=${debugInfo.url}`);\n return await this.extractNoteIdFromPage(page);\n }\n throw new shared_errors/* PublishError */.S1(`Publish completion timeout - could not determine result. URL=${debugInfo.url}, texts=${debugInfo.visibleTexts.join(', ').substring(0, 200)}`);\n }\n async extractNoteIdFromPage(page) {\n try {\n // Method 1: Try to extract from URL if redirected to note page\n const currentUrl = page.url();\n logger/* logger */.v.debug(`Current URL after publish: ${currentUrl}`);\n // Check if we're on a note page (URL contains /explore/ or /discovery/)\n const noteIdMatch = currentUrl.match(/\\/explore\\/([a-f0-9]+)/i) ||\n currentUrl.match(/\\/discovery\\/([a-f0-9]+)/i);\n if (noteIdMatch && noteIdMatch[1]) {\n const noteId = noteIdMatch[1];\n logger/* logger */.v.debug(`Extracted note ID from URL: ${noteId}`);\n return noteId;\n }\n // Method 2: Try to find note ID in page content or data attributes\n const noteIdFromPage = await page.evaluate(() => {\n // Look for data attributes that might contain note ID\n const elementsWithData = document.querySelectorAll('[data-note-id], [data-id], [data-impression]');\n for (let i = 0; i < elementsWithData.length; i++) {\n const element = elementsWithData[i];\n const noteId = element.getAttribute('data-note-id') ||\n element.getAttribute('data-id') ||\n element.getAttribute('data-impression');\n if (noteId && noteId.length > 10) { // Note IDs are typically long\n return noteId;\n }\n }\n // Look for links to note pages\n const noteLinks = document.querySelectorAll('a[href*=\"/explore/\"], a[href*=\"/discovery/\"]');\n for (let i = 0; i < noteLinks.length; i++) {\n const link = noteLinks[i];\n const href = link.getAttribute('href');\n if (href) {\n const match = href.match(/\\/explore\\/([a-f0-9]+)/i) ||\n href.match(/\\/discovery\\/([a-f0-9]+)/i);\n if (match && match[1]) {\n return match[1];\n }\n }\n }\n // Look for any text that looks like a note ID (long hex string)\n const textContent = document.body.textContent || '';\n const noteIdPattern = /[a-f0-9]{20,}/gi;\n const matches = textContent.match(noteIdPattern);\n if (matches && matches.length > 0) {\n // Return the first long hex string found\n return matches[0];\n }\n return null;\n });\n if (noteIdFromPage) {\n logger/* logger */.v.debug(`Extracted note ID from page content: ${noteIdFromPage}`);\n return noteIdFromPage;\n }\n // Method 3: Try to get the latest note ID using NoteService (fallback)\n logger/* logger */.v.debug('Could not extract note ID from page, trying fallback method');\n try {\n // Wait a bit for the note to be processed\n await (0,utils/* sleep */.yy)(5000);\n // Use NoteService to get the latest note ID\n const { NoteService } = await Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 9113));\n const noteService = new NoteService(this.getConfig());\n const userNotes = await noteService.getUserNotes(1); // Get only the latest note\n if (userNotes.success && userNotes.data && userNotes.data.length > 0) {\n const latestNoteId = userNotes.data[0].id;\n logger/* logger */.v.debug(`Extracted note ID from NoteService: ${latestNoteId}`);\n return latestNoteId;\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Fallback note ID extraction failed: ${error}`);\n }\n logger/* logger */.v.debug('Could not extract note ID from any method');\n return null;\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to extract note ID: ${error}`);\n return null;\n }\n }\n}\n\n;// ./src/core/publishing/publish-image.service.ts\n\n\n\n\n\n\n\nclass ImagePublishService extends PublishBaseService {\n async publishNote(title, content, imagePaths, tags = '', browserPath) {\n // Validate inputs\n if (!title?.trim()) {\n throw new shared_errors/* PublishError */.S1('Note title cannot be empty');\n }\n // Validate title width (CJK characters count as 2 units, ASCII as 1)\n assertTitleWidthValid(title);\n logger/* logger */.v.debug(`Title width validation passed: \"${title}\" (${getTitleWidth(title)} units)`);\n if (!content?.trim()) {\n throw new shared_errors/* PublishError */.S1('Note content cannot be empty');\n }\n if (!imagePaths || imagePaths.length === 0) {\n throw new shared_errors/* PublishError */.S1('At least one image is required');\n }\n // Process image paths - download URLs and validate local paths\n const resolvedPaths = await this.validateAndResolveImagePaths(imagePaths);\n // Wait for upload container selector\n const uploadSelector = 'div.upload-content';\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.creatorPublishUrl);\n // Wait for page to load\n await (0,utils/* sleep */.yy)(2000);\n // First, try to switch to the image/text upload tab\n await this.clickUploadTab(page);\n // Wait for tab switch to complete\n await (0,utils/* sleep */.yy)(2000);\n let hasUploadContainer = await this.getBrowserManager().tryWaitForSelector(page, uploadSelector, 30000);\n if (!hasUploadContainer) {\n // Try alternative selectors for upload container\n const alternativeSelectors = [\n 'div.upload-content',\n '.upload-content',\n 'div[class*=\"upload\"]',\n 'div[class*=\"image\"]',\n 'input[type=\"file\"]',\n ];\n for (const selector of alternativeSelectors) {\n hasUploadContainer = await this.getBrowserManager().tryWaitForSelector(page, selector, 10000);\n if (hasUploadContainer) {\n break;\n }\n }\n }\n if (!hasUploadContainer) {\n throw new shared_errors/* PublishError */.S1('Could not find upload container on publish page');\n }\n // Upload images\n await this.uploadImages(page, resolvedPaths);\n // Wait for images to be processed (large files need more time on XHS)\n logger/* logger */.v.debug('Waiting 10 seconds for images to be uploaded and processed...');\n await (0,utils/* sleep */.yy)(10000);\n // Wait for page to transition to edit mode (check for title or content input)\n try {\n await page.waitForSelector('input[placeholder*=\"标题\"], div[contenteditable=\"true\"], .tiptap.ProseMirror', { timeout: 15000 });\n }\n catch (error) {\n // Continue without waiting\n }\n // Wait a bit for the page to settle after image upload\n await (0,utils/* sleep */.yy)(1000);\n // Fill in title\n await this.fillTitle(page, title);\n // Wait a bit more for content area to appear\n await (0,utils/* sleep */.yy)(1000);\n // Fill in content\n await this.fillContent(page, content);\n // Add tags if provided\n if (tags) {\n await this.addTags(page, tags);\n }\n // Submit the note\n await this.submitPost(page);\n // Wait for completion and check result\n const noteId = await this.waitForPublishCompletion(page);\n // Save cookies\n await this.getBrowserManager().saveCookiesFromPage(page);\n return {\n success: true,\n message: 'Note published successfully',\n title,\n content,\n imageCount: resolvedPaths.length,\n tags,\n url: this.getConfig().xhs.creatorPublishUrl,\n noteId: noteId || undefined,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Publish error: ${error}`);\n throw error;\n }\n }\n /**\n * Process image paths - download URLs and validate local paths\n */\n async validateAndResolveImagePaths(imagePaths) {\n // Use ImageDownloader to process paths (downloads URLs, validates local paths)\n const resolvedPaths = await this.imageDownloader.processImagePaths(imagePaths);\n // Validate resolved paths\n for (const resolvedPath of resolvedPaths) {\n // For local paths that aren't absolute, resolve them\n const fullPath = resolvedPath.startsWith('/') || resolvedPath.match(/^[a-zA-Z]:/)\n ? resolvedPath\n : (0,external_path_.join)(process.cwd(), resolvedPath);\n if (!(0,external_fs_.existsSync)(fullPath)) {\n throw new shared_errors/* InvalidImageError */.TD(`Image file not found: ${resolvedPath}`);\n }\n const stats = (0,external_fs_.statSync)(fullPath);\n if (!stats.isFile()) {\n throw new shared_errors/* InvalidImageError */.TD(`Path is not a file: ${resolvedPath}`);\n }\n // Check file extension\n const ext = resolvedPath.toLowerCase().split('.').pop();\n const allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'];\n if (!ext || !allowedExtensions.includes(ext)) {\n throw new shared_errors/* InvalidImageError */.TD(`Unsupported image format: ${resolvedPath}. Supported: ${allowedExtensions.join(', ')}`);\n }\n }\n if (resolvedPaths.length > 18) {\n throw new shared_errors/* PublishError */.S1('Maximum 18 images allowed');\n }\n return resolvedPaths;\n }\n async clickUploadTab(page) {\n try {\n logger/* logger */.v.debug('Attempting to switch to \"上传图文\" tab');\n // Strategy 1: Navigate directly to image publish URL\n const imagePublishUrl = 'https://creator.xiaohongshu.com/publish/publish?source=official&from=menu&target=image';\n await page.goto(imagePublishUrl, { waitUntil: 'networkidle2', timeout: 30000 });\n logger/* logger */.v.debug(`Navigated directly to image publish URL: ${imagePublishUrl}`);\n await (0,utils/* sleep */.yy)(2000);\n // Verify we're on the image tab by checking page content\n const pageState = await page.evaluate(() => {\n const bodyText = document.body?.textContent || '';\n return {\n hasImageUpload: bodyText.includes('上传图文') || bodyText.includes('拖拽图片'),\n hasVideoUpload: bodyText.includes('上传视频') || bodyText.includes('拖拽视频'),\n url: window.location.href,\n };\n });\n logger/* logger */.v.debug(`Page state after navigation: ${JSON.stringify(pageState)}`);\n if (!pageState.hasImageUpload && pageState.hasVideoUpload) {\n logger/* logger */.v.warn('Still on video upload page after navigation. Trying tab click...');\n // Strategy 2: Click the image tab explicitly\n const tabs = await page.$$('div[class*=\"tab\"], .creator-tab, [role=\"tab\"]');\n for (const tab of tabs) {\n const text = await tab.evaluate(el => el.textContent?.trim());\n if (text && (text.includes('上传图文') || text.includes('图文'))) {\n const isVisible = await tab.isIntersectingViewport().catch(() => false);\n if (!isVisible)\n continue;\n // Full event chain for React\n await tab.evaluate((el) => {\n const htmlEl = el;\n const events = ['mouseenter', 'mouseover', 'mousedown', 'mouseup', 'click'];\n events.forEach(ev => {\n htmlEl.dispatchEvent(new MouseEvent(ev, { bubbles: true, cancelable: true }));\n });\n });\n await (0,utils/* sleep */.yy)(500);\n await tab.click();\n logger/* logger */.v.debug('Clicked image tab via Puppeteer');\n await (0,utils/* sleep */.yy)(1000);\n break;\n }\n }\n }\n await (0,utils/* sleep */.yy)(1000);\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to switch to image tab: ${error}`);\n }\n }\n async uploadImages(page, imagePaths) {\n try {\n logger/* logger */.v.debug('Uploading images using direct input element targeting');\n const fileInput = await page.$('input[type=\"file\"]');\n if (!fileInput) {\n throw new shared_errors/* PublishError */.S1('Could not find file upload input on page');\n }\n // Ensure the input accepts multiple files and any type to avoid frontend blocks\n await page.evaluate((el) => {\n if (el) {\n el.setAttribute('multiple', 'multiple');\n el.removeAttribute('accept');\n }\n }, fileInput);\n logger/* logger */.v.debug(`Submitting ${imagePaths.length} image paths to file input element`);\n await fileInput.uploadFile(...imagePaths);\n // Dispatch a change event manually in case the framework missed it\n await page.evaluate((el) => {\n if (el) {\n el.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }, fileInput);\n await (0,utils/* sleep */.yy)(8000);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to upload images: ${error}`);\n }\n }\n}\n\n;// ./src/core/publishing/publish-video.service.ts\n\n\n\n\n\n\n\n\nclass VideoPublishService extends PublishBaseService {\n async waitForVideoPublishCompletion(page) {\n logger/* logger */.v.debug('Waiting for video publish completion...');\n let isProcessing = false;\n await this.waitForCondition(async () => {\n // Check for success indicators\n const successResult = await this.checkElementForPatterns(page, SELECTORS.SUCCESS_INDICATORS, TEXT_PATTERNS.SUCCESS);\n if (successResult.found) {\n logger/* logger */.v.debug(`Found success indicator: ${successResult.text}`);\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.COMPLETION_CHECK);\n return true;\n }\n // Check for error indicators\n const errorResult = await this.checkElementForPatterns(page, SELECTORS.ERROR_INDICATORS, TEXT_PATTERNS.ERROR);\n if (errorResult.found) {\n throw new shared_errors/* PublishError */.S1(`Video publish failed with error: ${errorResult.text}`);\n }\n // Check if we've left the publish page (likely success)\n const stillOnPage = await this.findElementBySelectors(page, SELECTORS.PUBLISH_PAGE_INDICATORS);\n if (!stillOnPage) {\n logger/* logger */.v.debug('Left publish page, assuming video publish success');\n return true;\n }\n // Check for processing status\n const processingResult = await this.checkElementForPatterns(page, SELECTORS.PROCESSING_INDICATORS, TEXT_PATTERNS.PROCESSING);\n isProcessing = processingResult.found;\n if (isProcessing) {\n logger/* logger */.v.debug(`Video still processing: ${processingResult.text}`);\n }\n // Check for toast messages\n const toastResult = await this.checkElementForPatterns(page, SELECTORS.TOAST_SELECTORS, TEXT_PATTERNS.SUCCESS);\n if (toastResult.found) {\n logger/* logger */.v.debug(`Found success toast: ${toastResult.text}`);\n return true;\n }\n const errorToastResult = await this.checkElementForPatterns(page, SELECTORS.TOAST_SELECTORS, TEXT_PATTERNS.ERROR);\n if (errorToastResult.found) {\n throw new shared_errors/* PublishError */.S1(`Video publish failed: ${errorToastResult.text}`);\n }\n return false;\n }, VIDEO_TIMEOUTS.COMPLETION_TIMEOUT, isProcessing ? 5000 : VIDEO_TIMEOUTS.COMPLETION_CHECK, 'Video publish completion timeout - could not determine result after 5 minutes');\n // Extract note ID after successful completion\n return await this.extractNoteIdFromPage(page);\n }\n async publishVideo(title, content, videoPath, tags = '', browserPath) {\n // Validate inputs\n this.validateVideoInputs(title, content, videoPath);\n // Validate and resolve video path\n const resolvedVideoPath = this.validateAndResolveVideoPath(videoPath);\n try {\n const page = await this.getBrowserManager().createPage(false, browserPath, true);\n try {\n const noteId = await this.executeVideoPublishWorkflow(page, title, content, resolvedVideoPath, tags);\n // Save cookies\n await this.getBrowserManager().saveCookiesFromPage(page);\n return {\n success: true,\n message: 'Video published successfully',\n title,\n content,\n imageCount: 0, // Videos don't have image count\n tags,\n url: this.getConfig().xhs.creatorVideoPublishUrl,\n noteId: noteId || undefined,\n };\n }\n finally {\n await page.close();\n }\n }\n catch (error) {\n logger/* logger */.v.error(`Video publish error: ${error}`);\n throw error;\n }\n }\n validateVideoInputs(title, content, videoPath) {\n if (!title?.trim()) {\n throw new shared_errors/* PublishError */.S1('Video title cannot be empty');\n }\n // Validate title width for video posts too\n assertTitleWidthValid(title);\n logger/* logger */.v.debug(`Video title width validation passed: \"${title}\" (${getTitleWidth(title)} units)`);\n if (!content?.trim()) {\n throw new shared_errors/* PublishError */.S1('Video content cannot be empty');\n }\n if (!videoPath?.trim()) {\n throw new shared_errors/* PublishError */.S1('Video path is required');\n }\n }\n async executeVideoPublishWorkflow(page, title, content, videoPath, tags) {\n // Navigate to video upload page\n await this.getBrowserManager().navigateWithRetry(page, this.getConfig().xhs.creatorVideoPublishUrl);\n // Wait for page to load\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.PAGE_LOAD);\n // Switch to video upload tab if needed\n await this.clickVideoUploadTab(page);\n // Wait for tab switch to complete\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.TAB_SWITCH);\n // Upload video\n await this.uploadVideo(page, videoPath);\n // Wait for video to be processed (videos take longer than images)\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.VIDEO_PROCESSING);\n // Fill in title\n await this.fillTitle(page, title);\n // Wait a bit for content area to appear\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.CONTENT_WAIT);\n // Fill in content\n await this.fillContent(page, content);\n // Add tags if provided\n if (tags) {\n await this.addTags(page, tags);\n }\n // Submit the video\n await this.submitPost(page);\n // Wait for completion and check result (videos need longer timeout)\n return await this.waitForVideoPublishCompletion(page);\n }\n validateAndResolveVideoPath(videoPath) {\n const resolvedPath = videoPath.startsWith('/') || videoPath.match(/^[a-zA-Z]:/)\n ? videoPath\n : (0,external_path_.join)(process.cwd(), videoPath);\n if (!(0,external_fs_.existsSync)(resolvedPath)) {\n throw new shared_errors/* PublishError */.S1(`Video file not found: ${videoPath}`);\n }\n const stats = (0,external_fs_.statSync)(resolvedPath);\n if (!stats.isFile()) {\n throw new shared_errors/* PublishError */.S1(`Path is not a file: ${videoPath}`);\n }\n // Check file extension\n const ext = videoPath.toLowerCase().split('.').pop();\n const allowedExtensions = ['mp4', 'mov', 'avi', 'mkv', 'webm', 'flv', 'wmv'];\n if (!ext || !allowedExtensions.includes(ext)) {\n throw new shared_errors/* PublishError */.S1(`Unsupported video format: ${videoPath}. Supported: ${allowedExtensions.join(', ')}`);\n }\n // Check file size (XHS typically has limits)\n const maxSizeInMB = 500; // 500MB limit\n const fileSizeInMB = stats.size / (1024 * 1024);\n if (fileSizeInMB > maxSizeInMB) {\n throw new shared_errors/* PublishError */.S1(`Video file too large: ${fileSizeInMB.toFixed(2)}MB. Maximum allowed: ${maxSizeInMB}MB`);\n }\n return resolvedPath;\n }\n async clickVideoUploadTab(page) {\n try {\n // Try multiple selectors for video tab\n const videoTabSelectors = [\n 'div.creator-tab',\n '.creator-tab',\n '[role=\"tab\"]',\n '.tab',\n 'div[class*=\"tab\"]',\n ];\n let tabs = [];\n for (const selector of videoTabSelectors) {\n const foundTabs = await page.$$(selector);\n if (foundTabs.length > 0) {\n tabs = foundTabs;\n break;\n }\n }\n if (tabs.length === 0) {\n logger/* logger */.v.warn('No tabs found for video upload');\n return;\n }\n // Look for the video upload tab specifically\n let videoTab = null;\n for (let i = 0; i < tabs.length; i++) {\n const tab = tabs[i];\n try {\n const isVisible = await tab.isIntersectingViewport();\n if (!isVisible)\n continue;\n const text = await page.evaluate((el) => el.textContent, tab);\n // Check if this is the video upload tab\n if (text &&\n (text.includes('上传视频') || text.includes('视频') || text.includes('video'))) {\n videoTab = tab;\n break;\n }\n }\n catch (error) {\n // Ignore individual tab errors\n }\n }\n if (videoTab) {\n await videoTab.click();\n await (0,utils/* sleep */.yy)(2000); // Wait for tab switch\n }\n else {\n // Fallback: click the first tab (usually video upload)\n const visibleTabs = [];\n for (const tab of tabs) {\n const isVisible = await tab.isIntersectingViewport();\n if (isVisible) {\n visibleTabs.push(tab);\n }\n }\n if (visibleTabs.length > 0) {\n await visibleTabs[0].click(); // Usually the first tab is video upload\n await (0,utils/* sleep */.yy)(2000);\n }\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to click video upload tab: ${error}`);\n }\n }\n async uploadVideo(page, videoPath) {\n logger/* logger */.v.debug(`Uploading video: ${videoPath}`);\n // Find file input element\n const fileInput = await this.findElementBySelectors(page, SELECTORS.FILE_INPUT);\n if (!fileInput) {\n throw new shared_errors/* PublishError */.S1('Could not find file upload input on video upload page');\n }\n try {\n // Wait for the input to be ready\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.UPLOAD_READY);\n // Upload the video file\n await fileInput.uploadFile(videoPath);\n logger/* logger */.v.debug('Video file uploaded, waiting for processing...');\n // Wait for upload to start and show progress\n await (0,utils/* sleep */.yy)(VIDEO_TIMEOUTS.UPLOAD_START);\n // Wait for video processing to complete (this can take a while)\n await this.waitForVideoProcessing(page);\n }\n catch (error) {\n throw new shared_errors/* PublishError */.S1(`Failed to upload video ${videoPath}: ${error}`);\n }\n }\n async waitForVideoProcessing(page) {\n logger/* logger */.v.debug('Waiting for video processing to complete...');\n try {\n await this.waitForCondition(async () => {\n // Check if processing is complete\n const completeResult = await this.checkElementForPatterns(page, SELECTORS.COMPLETION_INDICATORS, TEXT_PATTERNS.SUCCESS);\n if (completeResult.found) {\n logger/* logger */.v.debug(`Video processing complete: ${completeResult.text}`);\n return true;\n }\n // Check if still processing\n const processingResult = await this.checkElementForPatterns(page, SELECTORS.PROCESSING_INDICATORS, TEXT_PATTERNS.PROCESSING);\n if (processingResult.found) {\n logger/* logger */.v.debug(`Video processing: ${processingResult.text}`);\n return false; // Still processing, continue waiting\n }\n // If not processing and no completion indicator, assume it's done\n logger/* logger */.v.debug('No processing indicators found, assuming video processing complete');\n return true;\n }, VIDEO_TIMEOUTS.PROCESSING_TIMEOUT, VIDEO_TIMEOUTS.PROCESSING_CHECK, 'Video processing timeout');\n }\n catch (error) {\n logger/* logger */.v.warn('Video processing timeout, continuing anyway...');\n }\n }\n}\n\n;// ./src/core/publishing/publish.service.ts\n\n\n\nclass PublishService extends base_service/* BaseService */.d {\n imageService;\n videoService;\n constructor(config, browserManager) {\n super(config, browserManager);\n this.imageService = new ImagePublishService(config, this.browserManager);\n this.videoService = new VideoPublishService(config, this.browserManager);\n }\n async publishNote(title, content, imagePaths, tags = '', browserPath) {\n return this.imageService.publishNote(title, content, imagePaths, tags, browserPath);\n }\n async publishVideo(title, content, videoPath, tags = '', browserPath) {\n return this.videoService.publishVideo(title, content, videoPath, tags, browserPath);\n }\n async publishContent(type, title, content, mediaPaths, tags = '', browserPath) {\n if (type === 'image') {\n return this.publishNote(title, content, mediaPaths, tags, browserPath);\n }\n else {\n return this.publishVideo(title, content, mediaPaths[0], tags, browserPath);\n }\n }\n}\n\n// EXTERNAL MODULE: ./src/core/notes/note.service.ts + 2 modules\nvar note_service = __webpack_require__(9113);\n// EXTERNAL MODULE: ./src/core/browser/browser.manager.ts + 1 modules\nvar browser_manager = __webpack_require__(3977);\n;// ./src/server/handlers/tool.handlers.ts\n/**\n * Tool request handlers for XHS MCP Server\n */\n\n\n\n\n\n\n\n\n\n\nclass ToolHandlers {\n authService;\n feedService;\n publishService;\n noteService;\n browserManager;\n constructor() {\n const config = (0,shared_config/* getConfig */.zj)();\n this.browserManager = new browser_manager/* BrowserManager */.Gd(config);\n this.authService = new AuthService(config, this.browserManager);\n this.feedService = new FeedService(config, this.browserManager);\n this.publishService = new PublishService(config, this.browserManager);\n this.noteService = new note_service.NoteService(config, this.browserManager);\n }\n async handleAuthLogin(browserPath) {\n // Start login process in background and return immediately\n // This follows the \"instant response\" pattern described in README\n this.authService.login(browserPath).catch((error) => {\n (0,utils/* safeErrorHandler */.ah)(error, 'Background login error', logger/* logger */.v);\n });\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n success: true,\n message: 'Login process started. A browser window will open for you to complete the login.',\n status: 'login_started',\n action: 'browser_opened',\n instructions: [\n '1. Complete the login process in the opened browser window',\n '2. Scan QR code or enter your credentials',\n '3. Login will be automatically verified and cookies saved',\n '4. Use xhs_auth_status to check if login completed',\n ],\n note: 'The login process runs in the background. You can continue using other tools while login completes.',\n }, null, 2),\n },\n ],\n };\n }\n async handleAuthLogout() {\n const result = await this.authService.logout();\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleAuthStatus(browserPath) {\n const result = await this.authService.checkStatus(browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleDiscoverFeeds(browserPath) {\n const result = await this.feedService.getFeedList(browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleSearchNote(keyword, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ keyword }, ['keyword']);\n const result = await this.feedService.searchFeeds(keyword, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleGetNoteDetail(feedId, xsecToken, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ feedId, xsecToken }, ['feedId', 'xsecToken']);\n const result = await this.feedService.getFeedDetail(feedId, xsecToken, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleCommentOnNote(feedId, xsecToken, note, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ feedId, xsecToken, note }, ['feedId', 'xsecToken', 'note']);\n const result = await this.feedService.commentOnFeed(feedId, xsecToken, note, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handlePublishContent(type, title, content, mediaPaths, tags, browserPath) {\n (0,utils/* validateRequiredParams */.IB)({ type, title, content, mediaPaths }, [\n 'type',\n 'title',\n 'content',\n 'mediaPaths',\n ]);\n // Validate content type\n if (type !== 'image' && type !== 'video') {\n throw new Error('Content type must be \"image\" or \"video\"');\n }\n // Validate parameter constraints using width-aware title validation\n assertTitleWidthValid(title);\n if (content.length > 1000) {\n throw new Error('Content must be 1000 characters or less');\n }\n // Execute unified publishing process\n const result = await this.publishService.publishContent(type, title, content, mediaPaths, tags, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleGetUserNotes(limit, cursor, browserPath) {\n const result = await this.noteService.getUserNotes(limit, cursor, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n async handleDeleteNote(noteId, lastPublished, browserPath) {\n if (lastPublished) {\n const result = await this.noteService.deleteLastPublishedNote(browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n else if (noteId) {\n const result = await this.noteService.deleteNote(noteId, browserPath);\n return (0,utils/* createMcpToolResponse */.q$)(result);\n }\n else {\n throw new Error('Either note_id or last_published must be specified');\n }\n }\n async handleToolRequest(name, args = {}) {\n try {\n switch (name) {\n case 'xhs_auth_login':\n return await this.handleAuthLogin(args?.browser_path);\n case 'xhs_auth_logout':\n return await this.handleAuthLogout();\n case 'xhs_auth_status':\n return await this.handleAuthStatus(args?.browser_path);\n case 'xhs_discover_feeds':\n return await this.handleDiscoverFeeds(args?.browser_path);\n case 'xhs_search_note':\n return await this.handleSearchNote(args?.keyword, args?.browser_path);\n case 'xhs_get_note_detail':\n return await this.handleGetNoteDetail(args?.feed_id, args?.xsec_token, args?.browser_path);\n case 'xhs_comment_on_note':\n return await this.handleCommentOnNote(args?.feed_id, args?.xsec_token, args?.note, args?.browser_path);\n case 'xhs_publish_content':\n return await this.handlePublishContent(args?.type, args?.title, args?.content, args?.media_paths, args?.tags, args?.browser_path);\n case 'xhs_get_user_notes':\n return await this.handleGetUserNotes(args?.limit, args?.cursor, args?.browser_path);\n case 'xhs_delete_note':\n return await this.handleDeleteNote(args?.note_id, args?.last_published, args?.browser_path);\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n }\n catch (error) {\n if (error instanceof shared_errors/* XHSError */.a_) {\n return (0,utils/* createMcpToolResponse */.q$)(error.toJSON());\n }\n return (0,utils/* createMcpErrorResponse */.mo)(error);\n }\n }\n}\n\n;// ./src/shared/index.ts\n/**\n * Shared utilities, types, and services for XHS MCP Server\n */\n// Configuration and types\n\n\n// Utilities\n\n\n\n\n\n// Error handling and logging\n\n\n// Base service\n\n\n;// ./src/server/handlers/resource.handlers.ts\n/**\n * Resource request handlers for XHS MCP Server\n */\n\n\nclass ResourceHandlers {\n authService;\n constructor() {\n const config = (0,shared_config/* getConfig */.zj)();\n this.authService = new AuthService(config);\n }\n async getCookiesResource() {\n try {\n const cookiesInfo = (0,cookies/* getCookiesInfo */.mL)();\n return JSON.stringify(cookiesInfo, null, 2);\n }\n catch (error) {\n return JSON.stringify({ error: String(error) }, null, 2);\n }\n }\n async getConfigResource() {\n try {\n const configDict = (0,shared_config/* getConfig */.zj)();\n const configWithFramework = {\n ...configDict,\n framework: 'MCP TypeScript',\n version: configDict.server.version,\n };\n return JSON.stringify(configWithFramework, null, 2);\n }\n catch (error) {\n return JSON.stringify({ error: String(error) }, null, 2);\n }\n }\n async getStatusResource() {\n try {\n // Quick status check (but don't fail if it errors)\n let authStatus = { status: 'unknown', error: 'Status check not performed' };\n try {\n authStatus = await this.authService.checkStatus();\n }\n catch (error) {\n authStatus = { status: 'error', error: String(error) };\n }\n const cookiesInfo = (0,cookies/* getCookiesInfo */.mL)();\n const config = (0,shared_config/* getConfig */.zj)();\n const statusData = {\n server: {\n status: 'running',\n name: config.server.name,\n version: config.server.version,\n framework: 'MCP TypeScript',\n },\n authentication: authStatus,\n cookies: {\n fileExists: cookiesInfo.fileExists,\n cookieCount: cookiesInfo.cookieCount,\n },\n capabilities: {\n toolsAvailable: 8,\n promptsAvailable: 0,\n resourcesAvailable: 3,\n },\n };\n return JSON.stringify(statusData, null, 2);\n }\n catch (error) {\n return JSON.stringify({\n server: { status: 'error', error: String(error) },\n framework: 'MCP TypeScript',\n }, null, 2);\n }\n }\n async handleResourceRequest(uri) {\n try {\n let content;\n switch (uri) {\n case 'xhs://cookies':\n content = await this.getCookiesResource();\n break;\n case 'xhs://config':\n content = await this.getConfigResource();\n break;\n case 'xhs://status':\n content = await this.getStatusResource();\n break;\n default:\n throw new Error(`Unknown resource: ${uri}`);\n }\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: content,\n },\n ],\n };\n }\n catch (error) {\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify({ error: String(error) }, null, 2),\n },\n ],\n };\n }\n }\n}\n\n;// ./src/server/schemas/tool.schemas.ts\n/**\n * Tool schemas for XHS MCP Server\n */\nconst XHS_TOOL_SCHEMAS = [\n {\n name: 'xhs_auth_login',\n description: 'Start XiaoHongShu login process.',\n inputSchema: {\n type: 'object',\n properties: {\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_auth_logout',\n description: 'Logout from XiaoHongShu (clears saved cookies).',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n },\n {\n name: 'xhs_auth_status',\n description: 'Check XiaoHongShu login status (fast check with browser).',\n inputSchema: {\n type: 'object',\n properties: {\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_discover_feeds',\n description: 'Get home page feed list.',\n inputSchema: {\n type: 'object',\n properties: {\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_search_note',\n description: 'Search for notes by keyword.',\n inputSchema: {\n type: 'object',\n properties: {\n keyword: {\n type: 'string',\n description: 'Search keyword (required)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['keyword'],\n },\n },\n {\n name: 'xhs_get_note_detail',\n description: 'Get detailed information about a specific note.',\n inputSchema: {\n type: 'object',\n properties: {\n feed_id: {\n type: 'string',\n description: 'Feed ID (required)',\n },\n xsec_token: {\n type: 'string',\n description: 'Security token for the feed (required)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['feed_id', 'xsec_token'],\n },\n },\n {\n name: 'xhs_comment_on_note',\n description: 'Comment on a note.',\n inputSchema: {\n type: 'object',\n properties: {\n feed_id: {\n type: 'string',\n description: 'Feed ID (required)',\n },\n xsec_token: {\n type: 'string',\n description: 'Security token for the feed (required)',\n },\n note: {\n type: 'string',\n description: 'Comment note (required)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['feed_id', 'xsec_token', 'note'],\n },\n },\n {\n name: 'xhs_publish_content',\n description: 'Publish content to XiaoHongShu (supports both images and videos).',\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['image', 'video'],\n description: 'Content type: \"image\" for images, \"video\" for videos (required)',\n },\n title: {\n type: 'string',\n description: 'Content title (required, max 20 characters)',\n maxLength: 20,\n },\n content: {\n type: 'string',\n description: 'Content description (required, max 1000 characters)',\n maxLength: 1000,\n },\n media_paths: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of media file paths (required, non-empty). For images: 1-18 image files. For videos: exactly 1 video file.',\n maxItems: 18,\n },\n tags: {\n type: 'string',\n description: 'Comma-separated tags (optional)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n required: ['type', 'title', 'content', 'media_paths'],\n },\n },\n {\n name: 'xhs_get_user_notes',\n description: 'Get current user notes list.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Number of notes to fetch (default: 20)',\n },\n cursor: {\n type: 'string',\n description: 'Pagination cursor for next page',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n {\n name: 'xhs_delete_note',\n description: 'Delete a user note by ID or delete the last published note.',\n inputSchema: {\n type: 'object',\n properties: {\n note_id: {\n type: 'string',\n description: 'Specific note ID to delete (optional if last_published is true)',\n },\n last_published: {\n type: 'boolean',\n description: 'Delete the last published note (optional if note_id is provided)',\n },\n browser_path: {\n type: 'string',\n description: 'Optional custom browser binary path',\n },\n },\n },\n },\n];\nconst XHS_RESOURCE_SCHEMAS = [\n {\n uri: 'xhs://cookies',\n name: 'XHS Authentication Cookies',\n description: 'Current XiaoHongShu authentication cookies and info',\n mimeType: 'application/json',\n },\n {\n uri: 'xhs://config',\n name: 'XHS Server Configuration',\n description: 'XHS MCP server configuration',\n mimeType: 'application/json',\n },\n {\n uri: 'xhs://status',\n name: 'XHS Server Status',\n description: 'Current server and authentication status',\n mimeType: 'application/json',\n },\n];\n\n;// ./src/server/mcp.server.ts\n/**\n * MCP Server for XiaoHongShu Operations\n */\n\n\n\n\n\n\n\nclass XHSMCPServer {\n server;\n toolHandlers;\n resourceHandlers;\n config;\n constructor() {\n this.config = (0,shared_config/* getConfig */.zj)();\n this.toolHandlers = new ToolHandlers();\n this.resourceHandlers = new ResourceHandlers();\n this.server = new esm_server/* Server */.g({\n name: this.config.server.name,\n version: this.config.server.version,\n }, {\n capabilities: {\n tools: {},\n resources: {},\n },\n });\n this.setupToolHandlers();\n this.setupResourceHandlers();\n }\n setupToolHandlers() {\n this.server.setRequestHandler(types/* CallToolRequestSchema */.FT, async (request) => {\n const { name, arguments: args } = request.params;\n return await this.toolHandlers.handleToolRequest(name, args);\n });\n this.server.setRequestHandler(types/* ListToolsRequestSchema */.gW, async () => {\n return {\n tools: XHS_TOOL_SCHEMAS,\n };\n });\n }\n setupResourceHandlers() {\n this.server.setRequestHandler(types/* ListResourcesRequestSchema */.OI, async () => {\n return {\n resources: XHS_RESOURCE_SCHEMAS,\n };\n });\n this.server.setRequestHandler(types/* ReadResourceRequestSchema */.R6, async (request) => {\n const { uri } = request.params;\n return await this.resourceHandlers.handleResourceRequest(uri);\n });\n }\n async start() {\n const transport = new stdio/* StdioServerTransport */.S();\n await this.server.connect(transport);\n // Don't log to stderr in stdio mode to avoid interfering with MCP protocol\n }\n}\n\n;// external \"express\"\nconst external_express_namespaceObject = require(\"express\");\nvar external_express_default = /*#__PURE__*/__webpack_require__.n(external_express_namespaceObject);\n;// external \"cors\"\nconst external_cors_namespaceObject = require(\"cors\");\nvar external_cors_default = /*#__PURE__*/__webpack_require__.n(external_cors_namespaceObject);\n// EXTERNAL MODULE: external \"node:crypto\"\nvar external_node_crypto_ = __webpack_require__(7598);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/sse.js\nvar sse = __webpack_require__(4375);\n// EXTERNAL MODULE: ./node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js\nvar streamableHttp = __webpack_require__(8144);\n;// ./src/server/http.server.ts\n/**\n * HTTP Server with SSE and Streamable HTTP Transport Support\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\nclass XHSHTTPMCPServer {\n app;\n config;\n toolHandlers;\n resourceHandlers;\n transports = new Map();\n port;\n constructor(port = 3000) {\n this.port = port;\n this.config = (0,shared_config/* getConfig */.zj)();\n this.toolHandlers = new ToolHandlers();\n this.resourceHandlers = new ResourceHandlers();\n this.app = external_express_default()();\n this.setupMiddleware();\n this.setupRoutes();\n }\n setupMiddleware() {\n // Parse JSON bodies\n this.app.use(external_express_default().json());\n // Configure CORS to expose Mcp-Session-Id header for browser-based clients\n this.app.use(external_cors_default()({\n origin: '*', // Allow all origins - adjust as needed for production\n exposedHeaders: ['Mcp-Session-Id'],\n }));\n }\n setupRoutes() {\n // Streamable HTTP Transport (Protocol version 2025-03-26)\n this.app.all('/mcp', this.handleStreamableHTTP.bind(this));\n // Deprecated HTTP+SSE Transport (Protocol version 2024-11-05)\n this.app.get('/sse', this.handleSSEConnection.bind(this));\n this.app.post('/messages', this.handleSSEMessage.bind(this));\n // Health check endpoint\n this.app.get('/health', (req, res) => {\n res.json({\n status: 'healthy',\n server: this.config.server.name,\n version: this.config.server.version,\n transports: ['streamable-http', 'sse'],\n });\n });\n }\n async handleStreamableHTTP(req, res) {\n logger/* logger */.v.info(`Received ${req.method} request to /mcp`);\n try {\n // Check for existing session ID\n const sessionId = req.headers['mcp-session-id'];\n let transport;\n if (sessionId && this.transports.has(sessionId)) {\n const existingTransport = this.transports.get(sessionId);\n if (existingTransport instanceof streamableHttp/* StreamableHTTPServerTransport */.D) {\n transport = existingTransport;\n }\n else {\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: Session exists but uses a different transport protocol',\n },\n id: null,\n });\n return;\n }\n }\n else if (!sessionId && req.method === 'POST' && (0,types/* isInitializeRequest */.eK)(req.body)) {\n // Create new Streamable HTTP transport\n transport = new streamableHttp/* StreamableHTTPServerTransport */.D({\n sessionIdGenerator: () => (0,external_node_crypto_.randomUUID)(),\n onsessioninitialized: (sessionId) => {\n logger/* logger */.v.info(`StreamableHTTP session initialized with ID: ${sessionId}`);\n this.transports.set(sessionId, transport);\n },\n onsessionclosed: (sessionId) => {\n logger/* logger */.v.info(`StreamableHTTP session closed: ${sessionId}`);\n this.transports.delete(sessionId);\n },\n });\n // Set up onclose handler to clean up transport when closed\n transport.onclose = () => {\n const sid = transport.sessionId;\n if (sid && this.transports.has(sid)) {\n logger/* logger */.v.info(`Transport closed for session ${sid}, removing from transports map`);\n this.transports.delete(sid);\n }\n };\n // Connect the transport to the MCP server\n const server = this.createMCPServer();\n await server.connect(transport);\n }\n else {\n // Invalid request - no session ID or not initialization request\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: No valid session ID provided',\n },\n id: null,\n });\n return;\n }\n // Handle the request with the transport\n await transport.handleRequest(req, res, req.body);\n }\n catch (error) {\n logger/* logger */.v.error('Error handling Streamable HTTP request:', error);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n async handleSSEConnection(req, res) {\n logger/* logger */.v.info('Received GET request to /sse (deprecated SSE transport)');\n try {\n const transport = new sse/* SSEServerTransport */.K('/messages', res);\n this.transports.set(transport.sessionId, transport);\n res.on('close', () => {\n this.transports.delete(transport.sessionId);\n });\n const server = this.createMCPServer();\n await server.connect(transport);\n }\n catch (error) {\n logger/* logger */.v.error('Error handling SSE connection:', error);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n async handleSSEMessage(req, res) {\n const sessionId = req.query.sessionId;\n try {\n const transport = this.transports.get(sessionId);\n if (!transport || !(transport instanceof sse/* SSEServerTransport */.K)) {\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: Session exists but uses a different transport protocol',\n },\n id: null,\n });\n return;\n }\n await transport.handlePostMessage(req, res, req.body);\n }\n catch (error) {\n logger/* logger */.v.error('Error handling SSE message:', error);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n createMCPServer() {\n const server = new esm_server/* Server */.g({\n name: this.config.server.name,\n version: this.config.server.version,\n }, {\n capabilities: {\n tools: {},\n resources: {},\n },\n });\n // Setup tool handlers\n server.setRequestHandler(types/* CallToolRequestSchema */.FT, async (request) => {\n const { name, arguments: args } = request.params;\n return await this.toolHandlers.handleToolRequest(name, args);\n });\n server.setRequestHandler(types/* ListToolsRequestSchema */.gW, async () => {\n return {\n tools: XHS_TOOL_SCHEMAS,\n };\n });\n // Setup resource handlers\n server.setRequestHandler(types/* ListResourcesRequestSchema */.OI, async () => {\n return {\n resources: XHS_RESOURCE_SCHEMAS,\n };\n });\n server.setRequestHandler(types/* ReadResourceRequestSchema */.R6, async (request) => {\n const { uri } = request.params;\n return await this.resourceHandlers.handleResourceRequest(uri);\n });\n return server;\n }\n async start() {\n return new Promise((resolve, reject) => {\n const server = this.app.listen(this.port, (error) => {\n if (error) {\n logger/* logger */.v.error('Failed to start HTTP server:', error);\n reject(error);\n return;\n }\n console.log(`XHS MCP HTTP Server listening on port ${this.port}`);\n console.log(`\n==============================================\nSUPPORTED TRANSPORT OPTIONS:\n\n1. Streamable HTTP (Protocol version: 2025-03-26)\n Endpoint: /mcp\n Methods: GET, POST, DELETE\n Usage:\n - Initialize with POST to /mcp\n - Establish SSE stream with GET to /mcp\n - Send requests with POST to /mcp\n - Terminate session with DELETE to /mcp\n\n2. HTTP + SSE (Protocol version: 2024-11-05)\n Endpoints: /sse (GET) and /messages (POST)\n Usage:\n - Establish SSE stream with GET to /sse\n - Send requests with POST to /messages?sessionId=<id>\n\n3. Health Check\n Endpoint: /health\n Method: GET\n Usage: Check server status and supported transports\n==============================================\n`);\n resolve();\n });\n // Handle server shutdown\n process.on('SIGINT', async () => {\n logger/* logger */.v.info('Shutting down HTTP server...');\n for (const [sessionId, transport] of this.transports) {\n try {\n logger/* logger */.v.info(`Closing transport for session ${sessionId}`);\n await transport.close();\n }\n catch (error) {\n logger/* logger */.v.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n server.close(() => {\n logger/* logger */.v.info('HTTP server shutdown complete');\n process.exit(0);\n });\n });\n process.on('SIGTERM', async () => {\n logger/* logger */.v.info('Shutting down HTTP server...');\n for (const [sessionId, transport] of this.transports) {\n try {\n logger/* logger */.v.info(`Closing transport for session ${sessionId}`);\n await transport.close();\n }\n catch (error) {\n logger/* logger */.v.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n server.close(() => {\n logger/* logger */.v.info('HTTP server shutdown complete');\n process.exit(0);\n });\n });\n });\n }\n async stop() {\n // Close all active transports\n for (const [sessionId, transport] of this.transports) {\n try {\n await transport.close();\n }\n catch (error) {\n logger/* logger */.v.error(`Error closing transport for session ${sessionId}:`, error);\n }\n }\n this.transports.clear();\n }\n}\n\n;// ./src/server/handlers/index.ts\n/**\n * Request handlers for XHS MCP Server\n */\n\n\n\n;// ./src/server/index.ts\n/**\n * Server implementation for XHS MCP Server\n */\n\n\n\n\n;// ./src/cli/cli.ts\n//#!/usr/bin/env node\n/**\n * Unified CLI for XiaoHongShu operations\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * CLI utility functions\n */\nclass CLIUtils {\n program;\n constructor(program) {\n this.program = program;\n }\n formatErrorMessage(error) {\n const raw = error instanceof Error ? (error.stack ?? error.message) : String(error);\n // Handle specific error patterns\n if (/Executable doesn't exist|puppeteer browsers install/i.test(raw)) {\n return 'Chromium is not installed. Run: npx puppeteer browsers install chrome or xhs-mcp browser';\n }\n // For user-facing errors, just return the message without stack trace\n if (error instanceof Error) {\n // Check if it's a known error type that should show just the message\n if (error.message.includes('Either --note-id or --last-published must be specified') ||\n error.message.includes('Please specify either') ||\n error.message.includes('User not logged in') ||\n error.message.includes('Note not found') ||\n error.message.includes('Delete button not found')) {\n return error.message;\n }\n // For other errors, show a cleaner version\n const condensed = raw\n .replace(/[\\s\\S]*?Looks like Puppeteer[\\s\\S]*?Please run the following command to download new browsers:[\\s\\S]*?npx puppeteer browsers install[\\s\\S]*?(Puppeteer Team[\\s\\S]*?)*?/m, '')\n .replace(/[\\u2500-\\u257F]+/g, '') // box-drawing characters\n .replace(/\\s+at\\s+.*$/gm, '') // Remove stack trace lines\n .trim();\n return condensed || error.message;\n }\n return String(error);\n }\n writeJson(output, exitCode = 0) {\n const compact = this.program.getOptionValue?.('compact') === true;\n const json = compact ? JSON.stringify(output) : JSON.stringify(output, null, 2);\n process.stdout.write(`${json}\\n`);\n // Flush stdout before exiting to ensure output is visible\n if (process.stdout.writable) {\n process.stdout.end();\n }\n process.exit(exitCode);\n }\n printSuccess(result, message) {\n // If result already has success field, print it directly\n if (result && typeof result === 'object' && 'success' in result) {\n this.writeJson(result, 0);\n }\n else {\n // Otherwise, wrap it\n const payload = {\n success: true,\n message: message ?? result?.message ?? undefined,\n data: result,\n };\n this.writeJson(payload, 0);\n }\n }\n printError(error, code) {\n const message = this.formatErrorMessage(error);\n const payload = { success: false, message, code: code ?? undefined, status: 'error' };\n this.writeJson(payload, 1);\n }\n printUsageError(command, message) {\n const payload = {\n success: false,\n message,\n status: 'error',\n usage: `Use 'xhs-mcp ${command} --help' for more information`,\n };\n this.writeJson(payload, 1);\n }\n}\nasync function main() {\n const config = (0,shared_config/* getConfig */.zj)();\n const program = new external_commander_namespaceObject.Command();\n const utils = new CLIUtils(program);\n program\n .name('xhs-mcp')\n .description('XiaoHongShu CLI with subcommands')\n .option('--compact', 'Output compact one-line JSON (no pretty print)')\n .showHelpAfterError();\n program\n .command('login')\n .description('Start XiaoHongShu login flow (opens browser, saves cookies)')\n .option('-t, --timeout <seconds>', 'Login timeout in seconds', `${config.browser.loginTimeout}`)\n .action(async (opts) => {\n const browserPath = undefined;\n const timeoutSec = opts.timeout ? parseInt(opts.timeout, 10) : config.browser.loginTimeout;\n const authService = new AuthService(config);\n try {\n const result = await authService.login(browserPath, timeoutSec);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('logout')\n .description('Logout from XiaoHongShu and clear saved cookies')\n .action(async () => {\n const authService = new AuthService(config);\n try {\n const result = await authService.logout();\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('status')\n .description('Check current XiaoHongShu login status')\n .action(async () => {\n const browserPath = undefined;\n const authService = new AuthService(config);\n try {\n const result = await authService.checkStatus(browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('browser')\n .description('Ensure Puppeteer Chromium is installed and launchable; installs if missing')\n .option('--with-deps', 'Install OS-level dependencies as well (may require sudo)')\n .action(async (opts) => {\n async function canLaunchChromium() {\n try {\n // Get the executable path before launching\n const executablePath = external_puppeteer_default().executablePath();\n const browser = await external_puppeteer_default().launch({ headless: true });\n await browser.close();\n return { canLaunch: true, executablePath };\n }\n catch {\n return { canLaunch: false };\n }\n }\n const browserInfo = await canLaunchChromium();\n if (browserInfo.canLaunch) {\n utils.printSuccess({\n installed: true,\n executablePath: browserInfo.executablePath,\n }, 'Chromium is ready');\n return;\n }\n const args = ['puppeteer', 'browsers', 'install', 'chrome'];\n if (opts.withDeps)\n args.push('--with-deps');\n const result = (0,external_node_child_process_namespaceObject.spawnSync)('npx', args, { stdio: 'inherit', env: process.env });\n const afterInstallInfo = await canLaunchChromium();\n if (afterInstallInfo.canLaunch) {\n utils.printSuccess({\n installed: true,\n executablePath: afterInstallInfo.executablePath,\n exitCode: result.status ?? null,\n }, 'Chromium installed and ready');\n }\n else {\n utils.printError(new Error('Failed to install or launch Chromium'));\n }\n });\n // Feeds: discover\n program\n .command('feeds')\n .description('Discover home page feeds')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const feedService = new FeedService(config);\n try {\n const result = await feedService.getFeedList(opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // Feeds: search note\n program\n .command('search')\n .description('Search notes by keyword')\n .requiredOption('-k, --keyword <keyword>', 'Search keyword')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const feedService = new FeedService(config);\n try {\n const result = await feedService.searchFeeds(opts.keyword, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // User Notes: unified command with subcommands\n const userNoteCommand = program\n .command('usernote')\n .description(\"Current user's note management operations\");\n // User Note list subcommand\n userNoteCommand\n .command('list')\n .description(\"List current user's published notes\")\n .option('-l, --limit <number>', 'Maximum number of notes to retrieve', '20')\n .option('-c, --cursor <cursor>', 'Pagination cursor for next page')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const noteService = new note_service.NoteService(config);\n try {\n const limit = parseInt(opts.limit) || 20;\n const result = await noteService.getUserNotes(limit, opts.cursor, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // User Note delete subcommand\n userNoteCommand\n .command('delete')\n .description('Delete user notes')\n .option('--note-id <id>', 'Specific note ID to delete')\n .option('--last-published', 'Delete the last published note')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const noteService = new note_service.NoteService(config);\n try {\n if (opts.lastPublished) {\n const result = await noteService.deleteLastPublishedNote(opts.browserPath);\n utils.printSuccess(result);\n }\n else if (opts.noteId) {\n const result = await noteService.deleteNote(opts.noteId, opts.browserPath);\n utils.printSuccess(result);\n }\n else {\n // Show help instead of JSON error when no arguments provided\n console.log('Usage: xhs-mcp usernote delete [options]\\n');\n console.log('Delete user notes\\n');\n console.log('Options:');\n console.log(' --note-id <id> Specific note ID to delete');\n console.log(' --last-published Delete the last published note');\n console.log(' -b, --browser-path <path> Custom browser binary path');\n console.log(' -h, --help display help for command');\n process.exit(0);\n }\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // Feeds: comment on note\n program\n .command('comment')\n .description('Comment on a note')\n .requiredOption('--feed-id <id>', 'Feed ID')\n .requiredOption('--xsec-token <token>', 'Security token for the feed')\n .requiredOption('-n, --note <text>', 'Comment content')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const feedService = new FeedService(config);\n try {\n const result = await feedService.commentOnFeed(opts.feedId, opts.xsecToken, opts.note, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n // Publishing: unified publish command\n program\n .command('publish')\n .description('Publish content to XiaoHongShu (supports both images and videos)')\n .requiredOption('-t, --type <type>', 'Content type: \"image\" for images, \"video\" for videos')\n .requiredOption('--title <title>', 'Content title (<= 20 chars)')\n .requiredOption('--content <content>', 'Content description (<= 1000 chars)')\n .requiredOption('-m, --media <paths>', 'Comma-separated media file paths (1-18 images for image posts, exactly 1 video for videos)')\n .option('--tags <tags>', 'Comma-separated tags')\n .option('-b, --browser-path <path>', 'Custom browser binary path')\n .action(async (opts) => {\n const publishService = new PublishService(config);\n try {\n if (opts.type !== 'image' && opts.type !== 'video') {\n utils.printError(new Error('Type must be \"image\" or \"video\"'));\n return;\n }\n const mediaPaths = opts.media\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const result = await publishService.publishContent(opts.type, opts.title, opts.content, mediaPaths, opts.tags, opts.browserPath);\n utils.printSuccess(result);\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program\n .command('mcp')\n .description('Start XHS MCP server (stdio or http mode)')\n .option('-m, --mode <mode>', 'Server mode: stdio or http', 'stdio')\n .option('-p, --port <port>', 'HTTP server port (only for http mode)', '3000')\n .action(async (opts) => {\n try {\n if (opts.mode === 'http') {\n const port = opts.port ? parseInt(opts.port, 10) : 3000;\n const httpServer = new XHSHTTPMCPServer(port);\n await httpServer.start();\n }\n else {\n // In stdio mode, we must not output anything to stdout/stderr except MCP protocol messages\n // This prevents interference with MCP communication\n const server = new XHSMCPServer();\n await server.start();\n }\n }\n catch (error) {\n // Only log to stderr if logging is explicitly enabled\n if (process.env.XHS_ENABLE_LOGGING === 'true') {\n process.stderr.write(`Server failed to start: ${error}\\n`);\n }\n process.exit(1);\n }\n });\n // List MCP tools\n program\n .command('tools')\n .description('List available MCP tools')\n .option('-j, --json', 'Output in JSON format')\n .option('-d, --detailed', 'Show detailed tool information')\n .action(async (opts) => {\n try {\n const toolSchemas = XHS_TOOL_SCHEMAS;\n if (opts.json) {\n if (opts.detailed) {\n console.log(JSON.stringify(toolSchemas, null, 2));\n }\n else {\n const toolNames = toolSchemas.map((tool) => ({\n name: tool.name,\n description: tool.description,\n }));\n console.log(JSON.stringify(toolNames, null, 2));\n }\n }\n else {\n console.log('\\n📋 Available MCP Tools:\\n');\n toolSchemas.forEach((tool, index) => {\n console.log(`${index + 1}. ${tool.name}`);\n console.log(` ${tool.description}`);\n if (opts.detailed) {\n const required = tool.inputSchema.required ?? [];\n const properties = tool.inputSchema.properties ?? {};\n if (Object.keys(properties).length > 0) {\n console.log(' Parameters:');\n Object.entries(properties).forEach(([key, prop]) => {\n const requiredMark = required.includes(key) ? ' (required)' : ' (optional)';\n const propDesc = prop.description;\n console.log(` - ${key}: ${propDesc ?? 'No description'}${requiredMark}`);\n });\n }\n }\n console.log('');\n });\n console.log(`Total: ${toolSchemas.length} tools available`);\n console.log('\\nUse --detailed for parameter information');\n console.log('Use --json for machine-readable output');\n }\n }\n catch (error) {\n utils.printError(error);\n }\n });\n program.parseAsync(process.argv);\n}\n// Handle graceful shutdown for MCP server mode\nprocess.on('SIGINT', () => {\n // Don't log to stderr in stdio mode to avoid interfering with MCP protocol\n process.exit(0);\n});\nprocess.on('SIGTERM', () => {\n // Don't log to stderr in stdio mode to avoid interfering with MCP protocol\n process.exit(0);\n});\n// Start the CLI\nmain().catch((error) => {\n // Only log to stderr if logging is explicitly enabled\n if (process.env.XHS_ENABLE_LOGGING === 'true') {\n process.stderr.write(`Fatal error: ${error}\\n`);\n }\n process.exit(1);\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LEVBQUUsRUFBRSxDQUFDO1FBQzNDLENBQUM7UUFFRCxPQUFPO1FBQ1AsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ25FLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUM3QyxDQUFDO1FBRUQsTUFBTTtRQUNOLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3pGLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUM3QyxDQUFDO1FBRUQsTUFBTTtRQUNOLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNuRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDN0MsQ0FBQztRQUVELE9BQU87UUFDUCxJQUNFLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQ2xCLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJO1lBQ25CLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJLEVBQ25CLENBQUM7WUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDOUMsQ0FBQztRQUVELE1BQU07UUFDTixJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUM3QyxDQUFDO1FBRUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxhQUFhLENBQUMsUUFBZ0I7UUFDbEMsc0JBQXNCO1FBQ3RCLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDMUMsTUFBTSxJQUFJLHVDQUFpQixDQUFDLDZCQUE2QixRQUFRLEVBQUUsRUFBRTtnQkFDbkUsR0FBRyxFQUFFLFFBQVE7Z0JBQ2IsVUFBVSxFQUFFLHlDQUF5QzthQUN0RCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsNkJBQTZCO1FBQzdCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqRCxNQUFNLFNBQVMsR0FBRyx1QkFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFL0MsdUNBQXVDO1FBQ3ZDLElBQUksMkJBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzFCLE1BQU0sS0FBSyxHQUFHLHlCQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbEMsb0JBQU0sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLFNBQVMsRUFBRSxDQUFDLENBQUM7WUFDakQsT0FBTztnQkFDTCxXQUFXLEVBQUUsUUFBUTtnQkFDckIsU0FBUztnQkFDVCxNQUFNLEVBQUUsSUFBSTtnQkFDWixRQUFRLEVBQUUsS0FBSyxDQUFDLElBQUk7YUFDckIsQ0FBQztRQUNKLENBQUM7UUFFRCxvQkFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUVwRCxJQUFJLENBQUM7WUFDSCw4QkFBOEI7WUFDOUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUN6QyxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUVyRSxNQUFNLFFBQVEsR0FBRyxNQUFNLDZCQUFLLENBQUMsUUFBUSxFQUFFO2dCQUNyQyxNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07Z0JBQ3pCLE9BQU8sRUFBRTtvQkFDUCxZQUFZLEVBQUUsb0VBQW9FO2lCQUNuRjthQUNGLENBQUMsQ0FBQztZQUVILFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUV4QixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUNqQixNQUFNLElBQUksdUNBQWlCLENBQ3pCLGtDQUFrQyxRQUFRLENBQUMsTUFBTSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUUsRUFDMUU7b0JBQ0UsR0FBRyxFQUFFLFFBQVE7b0JBQ2IsVUFBVSxFQUFFLFFBQVEsQ0FBQyxNQUFNO29CQUMzQixVQUFVLEVBQUUsUUFBUSxDQUFDLFVBQVU7aUJBQ2hDLENBQ0YsQ0FBQztZQUNKLENBQUM7WUFFRCxvQ0FBb0M7WUFDcEMsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUM3RCxJQUFJLGFBQWEsSUFBSSxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNoRSxNQUFNLElBQUksdUNBQWlCLENBQ3pCLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUN0RSxDQUFDLENBQ0YsWUFBWSxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUM3RDtvQkFDRSxHQUFHLEVBQUUsUUFBUTtvQkFDYixRQUFRLEVBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQztvQkFDakMsT0FBTyxFQUFFLElBQUksQ0FBQyxXQUFXO29CQUN6QixVQUFVLEVBQUUsbURBQW1EO2lCQUNoRSxDQUNGLENBQUM7WUFDSixDQUFDO1lBRUQsaUJBQWlCO1lBQ2pCLE1BQU0sV0FBVyxHQUFHLE1BQU0sUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFFeEMscUJBQXFCO1lBQ3JCLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3JDLE1BQU0sSUFBSSx1Q0FBaUIsQ0FDekIsOEJBQThCLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQ2hGLElBQUksQ0FBQyxXQUFXO29CQUNoQixJQUFJO29CQUNKLElBQUksQ0FDTCxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUNqQjtvQkFDRSxHQUFHLEVBQUUsUUFBUTtvQkFDYixRQUFRLEVBQUUsTUFBTSxDQUFDLE1BQU07b0JBQ3ZCLE9BQU8sRUFBRSxJQUFJLENBQUMsV0FBVztpQkFDMUIsQ0FDRixDQUFDO1lBQ0osQ0FBQztZQUVELGtDQUFrQztZQUNsQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDeEIsTUFBTSxJQUFJLHVDQUFpQixDQUFDLHlDQUF5QyxRQUFRLEVBQUUsRUFBRTtvQkFDL0UsR0FBRyxFQUFFLFFBQVE7b0JBQ2IsVUFBVSxFQUFFLGtEQUFrRDtpQkFDL0QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELGVBQWU7WUFDZiw4QkFBYSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUVqQyxvQkFBTSxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsU0FBUyxLQUFLLE1BQU0sQ0FBQyxNQUFNLFNBQVMsQ0FBQyxDQUFDO1lBRXJGLE9BQU87Z0JBQ0wsV0FBVyxFQUFFLFFBQVE7Z0JBQ3JCLFNBQVM7Z0JBQ1QsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsUUFBUSxFQUFFLE1BQU0sQ0FBQyxNQUFNO2FBQ3hCLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLHVDQUFpQixFQUFFLENBQUM7Z0JBQ3ZDLE1BQU0sS0FBSyxDQUFDO1lBQ2QsQ0FBQztZQUVELHFCQUFxQjtZQUNyQixJQUFJLEtBQUssWUFBWSxLQUFLLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUUsQ0FBQztnQkFDMUQsTUFBTSxJQUFJLHVDQUFpQixDQUN6QixnQ0FBZ0MsSUFBSSxDQUFDLE9BQU8sT0FBTyxRQUFRLEVBQUUsRUFDN0Q7b0JBQ0UsR0FBRyxFQUFFLFFBQVE7b0JBQ2IsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO29CQUNyQixVQUFVLEVBQUUsbURBQW1EO2lCQUNoRSxFQUNELEtBQUssQ0FDTixDQUFDO1lBQ0osQ0FBQztZQUVELE1BQU0sSUFBSSx1Q0FBaUIsQ0FDekIsNkJBQTZCLFFBQVEsRUFBRSxFQUN2QztnQkFDRSxHQUFHLEVBQUUsUUFBUTthQUNkLEVBQ0QsS0FBYyxDQUNmLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxTQUFtQjtRQUN0QyxrQ0FBa0M7UUFDbEMsTUFBTSxnQkFBZ0IsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDN0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUMzRCxDQUFDO1FBRUYsTUFBTSxPQUFPLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFcEQsTUFBTSxjQUFjLEdBQXFCLEVBQUUsQ0FBQztRQUM1QyxNQUFNLE1BQU0sR0FBeUMsRUFBRSxDQUFDO1FBRXhELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUN6QixJQUFJLE9BQU8sSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBYyxFQUFFLENBQUMsQ0FBQztZQUNqRSxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM5QixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCx1REFBdUQ7UUFDdkQsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25GLE1BQU0sSUFBSSx1Q0FBaUIsQ0FDekIsc0JBQXNCLE1BQU0sQ0FBQyxNQUFNLE9BQU8sU0FBUyxDQUFDLE1BQU0sYUFBYSxhQUFhLEVBQUUsRUFDdEY7Z0JBQ0UsVUFBVSxFQUFFLFNBQVMsQ0FBQyxNQUFNO2dCQUM1QixXQUFXLEVBQUUsTUFBTSxDQUFDLE1BQU07Z0JBQzFCLFlBQVksRUFBRSxjQUFjLENBQUMsTUFBTTtnQkFDbkMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7YUFDckMsQ0FDRixDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxVQUFvQjtRQUMxQyxNQUFNLFVBQVUsR0FBYSxFQUFFLENBQUM7UUFDaEMsTUFBTSxjQUFjLEdBQWEsRUFBRSxDQUFDO1FBRXBDLGlDQUFpQztRQUNqQyxLQUFLLE1BQU0sSUFBSSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzlCLElBQUksZUFBZSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNyQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzVCLENBQUM7aUJBQU0sQ0FBQztnQkFDTiw2QkFBNkI7Z0JBQzdCLElBQUksQ0FBQywyQkFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ3RCLE1BQU0sSUFBSSx1Q0FBaUIsQ0FBQywrQkFBK0IsSUFBSSxFQUFFLEVBQUU7d0JBQ2pFLElBQUk7d0JBQ0osVUFBVSxFQUFFLHdEQUF3RDtxQkFDckUsQ0FBQyxDQUFDO2dCQUNMLENBQUM7Z0JBQ0QsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QixDQUFDO1FBQ0gsQ0FBQztRQUVELHVCQUF1QjtRQUN2QixJQUFJLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDOUIsb0JBQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxjQUFjLENBQUMsTUFBTSxzQkFBc0IsQ0FBQyxDQUFDO1lBQ3pFLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNsRSxNQUFNLGVBQWUsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDaEUsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLGVBQWUsQ0FBQyxDQUFDO1lBRXBDLHVCQUF1QjtZQUN2QixNQUFNLFdBQVcsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDO1lBQ25FLE1BQU0sUUFBUSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUNqRSxvQkFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLFFBQVEscUJBQXFCLFdBQVcsZ0JBQWdCLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBRUQsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVCLE1BQU0sSUFBSSx1Q0FBaUIsQ0FBQyx1QkFBdUIsRUFBRTtnQkFDbkQsYUFBYSxFQUFFLFVBQVUsQ0FBQyxNQUFNO2dCQUNoQyxVQUFVLEVBQUUseURBQXlEO2FBQ3RFLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxVQUFVO1FBQ1IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RCLENBQUM7Q0FDRjtBQUVELDRCQUE0QjtBQUM1QixJQUFJLGlCQUFpQixHQUEyQixJQUFJLENBQUM7QUFFOUMsU0FBUyxrQkFBa0IsQ0FBQyxPQUFnQjtJQUNqRCxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxPQUFPLElBQUksaUJBQWlCLENBQUMsVUFBVSxFQUFFLEtBQUssT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNsRixpQkFBaUIsR0FBRyxJQUFJLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBQ0QsT0FBTyxpQkFBaUIsQ0FBQztBQUMzQixDQUFDOzs7OztBQ3hXRDs7R0FFRztBQUlnRDtBQUNLO0FBRVg7QUFDRjtBQUNxQjtBQUM4QztBQUU5RyxpQ0FBaUM7QUFDMUIsTUFBTSxjQUFjLEdBQUc7SUFDNUIsU0FBUyxFQUFFLElBQUk7SUFDZixVQUFVLEVBQUUsSUFBSTtJQUNoQixnQkFBZ0IsRUFBRSxLQUFLO0lBQ3ZCLFlBQVksRUFBRSxJQUFJO0lBQ2xCLFlBQVksRUFBRSxJQUFJO0lBQ2xCLFlBQVksRUFBRSxJQUFJO0lBQ2xCLGdCQUFnQixFQUFFLElBQUk7SUFDdEIsZ0JBQWdCLEVBQUUsSUFBSTtJQUN0QixrQkFBa0IsRUFBRSxNQUFNLEVBQUUsWUFBWTtJQUN4QyxrQkFBa0IsRUFBRSxNQUFNLEVBQUUsWUFBWTtDQUNoQyxDQUFDO0FBRUosTUFBTSxTQUFTLEdBQUc7SUFDdkIsVUFBVSxFQUFFLHVDQUFxQixDQUFDLFVBQVU7SUFDNUMsa0JBQWtCLEVBQUUseUNBQXVCLENBQUMsT0FBTztJQUNuRCxnQkFBZ0IsRUFBRSx5Q0FBdUIsQ0FBQyxLQUFLO0lBQy9DLHFCQUFxQixFQUFFLHlDQUF1QixDQUFDLFVBQVU7SUFDekQscUJBQXFCLEVBQUU7UUFDckIsa0JBQWtCO1FBQ2xCLHNCQUFzQjtRQUN0QixjQUFjO1FBQ2QscUJBQXFCO1FBQ3JCLGtCQUFrQjtLQUNuQjtJQUNELGVBQWUsRUFBRSx5Q0FBdUIsQ0FBQyxLQUFLO0lBQzlDLHVCQUF1QixFQUFFO1FBQ3ZCLG9CQUFvQjtRQUNwQixZQUFZO1FBQ1osaUJBQWlCO1FBQ2pCLHlCQUF5QjtRQUN6QixvQkFBb0I7S0FDckI7Q0FDTyxDQUFDO0FBRUosTUFBTSxhQUFhLEdBQUcsc0NBQW9CLENBQUM7QUFHM0MsTUFBZSxrQkFBbUIsU0FBUSwrQkFBVztJQUNoRCxlQUFlLENBQWtCO0lBRTNDLFlBQVksTUFBYyxFQUFFLGNBQStCO1FBQ3pELEtBQUssQ0FBQyxNQUFNLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQseURBQXlEO0lBQy9DLEtBQUssQ0FBQyxzQkFBc0IsQ0FDcEMsSUFBVSxFQUNWLFNBQTRCO1FBRTVCLEtBQUssTUFBTSxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7WUFDakMsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQ1osb0JBQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQ3pELE9BQU8sT0FBTyxDQUFDO1lBQ2pCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRVMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUFnQjtRQUM3QyxJQUFJLENBQUM7WUFDSCxPQUFPLE1BQU8sT0FBZSxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQVcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUMxRixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsSUFBSSxDQUFDLCtCQUErQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3BELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFUyxLQUFLLENBQUMsaUJBQWlCLENBQy9CLElBQW1CLEVBQ25CLFFBQTJCO1FBRTNCLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDeEIsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVTLEtBQUssQ0FBQyx1QkFBdUIsQ0FDckMsSUFBVSxFQUNWLFNBQTRCLEVBQzVCLFFBQTJCO1FBRTNCLEtBQUssTUFBTSxRQUFRLElBQUksU0FBUyxFQUFFLENBQUM7WUFDakMsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQ1osTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQTZCLENBQUMsQ0FBQztnQkFDdEUsSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUMzRCxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7Z0JBQ3hDLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVTLEtBQUssQ0FBQyxnQkFBZ0IsQ0FDOUIsU0FBaUMsRUFDakMsT0FBZSxFQUNmLGdCQUF3QixJQUFJLEVBQzVCLFlBQW9CO1FBRXBCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUU3QixPQUFPLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLEdBQUcsT0FBTyxFQUFFLENBQUM7WUFDeEMsSUFBSSxNQUFNLFNBQVMsRUFBRSxFQUFFLENBQUM7Z0JBQ3RCLE9BQU87WUFDVCxDQUFDO1lBQ0QsTUFBTSx1QkFBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFFRCxNQUFNLElBQUksa0NBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRVMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFVLEVBQUUsS0FBYTtRQUNqRCwwQ0FBMEM7UUFDMUMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUN4Qix5R0FBeUcsRUFDekcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQ25CLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLDJEQUEyRDtRQUM3RCxDQUFDO1FBRUQsTUFBTSxjQUFjLEdBQUc7WUFDckIscUJBQXFCLEVBQUUsNkNBQTZDO1lBQ3BFLGVBQWU7WUFDZiwwQkFBMEI7WUFDMUIsa0NBQWtDO1lBQ2xDLDZCQUE2QjtZQUM3QiwrQkFBK0I7WUFDL0Isb0JBQW9CO1lBQ3BCLDZCQUE2QjtZQUM3QixxQkFBcUI7WUFDckIsb0JBQW9CO1lBQ3BCLHVCQUF1QjtZQUN2QixvQkFBb0IsRUFBRSxZQUFZO1lBQ2xDLDZCQUE2QjtZQUM3Qiw2QkFBNkI7WUFDN0IsZ0NBQWdDO1NBQ2pDLENBQUM7UUFFRixLQUFLLE1BQU0sUUFBUSxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQztnQkFDSCxNQUFNLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzFDLElBQUksVUFBVSxFQUFFLENBQUM7b0JBQ2YsZ0RBQWdEO29CQUNoRCxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTt3QkFDekIsSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLENBQUMsY0FBYyxLQUFLLFVBQVUsRUFBRSxDQUFDOzRCQUNsRCxFQUFFLENBQUMsY0FBYyxDQUFDLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQzt3QkFDN0QsQ0FBQztvQkFDSCxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7b0JBQ2YsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUVqQixNQUFNLFNBQVMsR0FBRyxNQUFNLFVBQVUsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO29CQUU1RCxJQUFJLFNBQVMsRUFBRSxDQUFDO3dCQUNkLE1BQU0sVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO3dCQUN6QixNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7d0JBRW5DLDhCQUE4Qjt3QkFDOUIsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7d0JBQzFDLE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQzt3QkFFcEMsTUFBTSxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO3dCQUM3QixPQUFPO29CQUNULENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLDRCQUE0QjtZQUM5QixDQUFDO1FBQ0gsQ0FBQztRQUVELG9GQUFvRjtRQUNwRixJQUFJLENBQUM7WUFDSCxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUVuRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUMxQyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNCLElBQUksQ0FBQztvQkFDSCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBRXpFLHFDQUFxQztvQkFDckMsSUFBSSxJQUFJLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQzt3QkFDekMsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7NEJBQ3pCLElBQUksRUFBRSxJQUFJLE9BQU8sRUFBRSxDQUFDLGNBQWMsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQ0FDbEQsRUFBRSxDQUFDLGNBQWMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7NEJBQzdELENBQUM7d0JBQ0gsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO3dCQUNWLE1BQU0sdUJBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQzt3QkFFakIsTUFBTSxTQUFTLEdBQUcsTUFBTSxLQUFLLENBQUMsc0JBQXNCLEVBQUUsQ0FBQzt3QkFFdkQsSUFBSSxTQUFTLEVBQUUsQ0FBQzs0QkFDZCxNQUFNLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQzs0QkFDcEIsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDOzRCQUVqQiw4QkFBOEI7NEJBQzlCLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDOzRCQUNyQyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7NEJBRS9CLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs0QkFDeEIsT0FBTzt3QkFDVCxDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztnQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO29CQUNmLHlCQUF5QjtnQkFDM0IsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLHdCQUF3QjtRQUMxQixDQUFDO1FBRUQsTUFBTSxJQUFJLGtDQUFZLENBQUMsa0NBQWtDLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRVMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLElBQVU7UUFDM0MsSUFBSSxDQUFDO1lBQ0gsa0VBQWtFO1lBQ2xFLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBQ3BFLElBQUksZUFBZSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sU0FBUyxHQUFHLE1BQU0sZUFBZSxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0JBQ2pFLElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2QsT0FBTyxlQUFlLENBQUM7Z0JBQ3pCLENBQUM7WUFDSCxDQUFDO1lBRUQsaUZBQWlGO1lBQ2pGLE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQzVELElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ2pCLE1BQU0sU0FBUyxHQUFHLE1BQU0sWUFBWSxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0JBQzlELElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2QsT0FBTyxZQUFZLENBQUM7Z0JBQ3RCLENBQUM7WUFDSCxDQUFDO1lBRUQsa0ZBQWtGO1lBQ2xGLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1lBQ2hGLElBQUksV0FBVyxFQUFFLENBQUM7Z0JBQ2hCLE1BQU0sU0FBUyxHQUFHLE1BQU0sV0FBVyxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0JBQzdELElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2QsT0FBTyxXQUFXLENBQUM7Z0JBQ3JCLENBQUM7WUFDSCxDQUFDO1lBRUQsa0RBQWtEO1lBQ2xELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUMvQyxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUNiLE9BQU8sUUFBUSxDQUFDO1lBQ2xCLENBQUM7WUFFRCxzREFBc0Q7WUFDdEQsTUFBTSxnQkFBZ0IsR0FBRztnQkFDdkIscUJBQXFCO2dCQUNyQiw2QkFBNkI7Z0JBQzdCLHFCQUFxQjtnQkFDckIsNkJBQTZCO2dCQUM3QixpQkFBaUI7Z0JBQ2pCLHFCQUFxQjtnQkFDckIseUJBQXlCO2dCQUN6QixvQkFBb0I7YUFDckIsQ0FBQztZQUVGLEtBQUssTUFBTSxRQUFRLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztnQkFDeEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLE9BQU8sRUFBRSxDQUFDO29CQUNaLE9BQU8sT0FBTyxDQUFDO2dCQUNqQixDQUFDO1lBQ0gsQ0FBQztZQUVELDJEQUEyRDtZQUMzRCxNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQy9ELEtBQUssTUFBTSxPQUFPLElBQUksa0JBQWtCLEVBQUUsQ0FBQztnQkFDekMsTUFBTSxTQUFTLEdBQUcsTUFBTSxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztnQkFDekQsSUFBSSxTQUFTLEVBQUUsQ0FBQztvQkFDZCxPQUFPLE9BQU8sQ0FBQztnQkFDakIsQ0FBQztZQUNILENBQUM7WUFFRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxJQUFVO1FBQ2pELElBQUksQ0FBQztZQUNILHNCQUFzQjtZQUN0QixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFckMsNkRBQTZEO1lBQzdELEtBQUssTUFBTSxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQzFCLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUN4RixJQUFJLFdBQVcsRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztvQkFDcEMsT0FBTyxDQUFDLENBQUM7Z0JBQ1gsQ0FBQztZQUNILENBQUM7WUFFRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFVLEVBQUUsT0FBZ0I7UUFDNUQsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDdEUsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRVMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFVLEVBQUUsT0FBZTtRQUNyRCxrQ0FBa0M7UUFDbEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUN4QiwySkFBMkosRUFDM0osRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQ25CLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLDJCQUEyQjtRQUM3QixDQUFDO1FBRUQsSUFBSSxjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3BCLDJCQUEyQjtZQUMzQixNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNqRSxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNuQixjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3BCLHNEQUFzRDtZQUN0RCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQ3RDLHNMQUFzTCxDQUN2TCxDQUFDO2dCQUVGLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDbkQsTUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3RDLElBQUksQ0FBQzt3QkFDSCxNQUFNLFNBQVMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO3dCQUN6RCxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7d0JBQ2pFLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FDekMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsRUFDMUMsT0FBTyxDQUNSLENBQUM7d0JBQ0YsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO3dCQUMzRSxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7d0JBQ3JFLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQzt3QkFFckYsSUFDRSxTQUFTOzRCQUNULENBQUMsZUFBZSxLQUFLLE1BQU07Z0NBQ3pCLE9BQU8sS0FBSyxVQUFVO2dDQUN0QixJQUFJLEtBQUssU0FBUztnQ0FDbEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUM7Z0NBQy9CLFNBQVMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO2dDQUM1QixTQUFTLEtBQUssRUFBRSxDQUFDLEVBQ25CLENBQUM7NEJBQ0QsY0FBYyxHQUFHLE9BQU8sQ0FBQzs0QkFDekIsTUFBTTt3QkFDUixDQUFDO29CQUNILENBQUM7b0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzt3QkFDZiwyQkFBMkI7b0JBQzdCLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLDRCQUE0QjtZQUM5QixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNwQixpRUFBaUU7WUFDakUsSUFBSSxDQUFDO2dCQUNILE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFFdkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO29CQUMxRCw2QkFBNkI7b0JBQzdCLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDL0IsSUFBSSxDQUFDO3dCQUNILE1BQU0sU0FBUyxHQUFHLE1BQU0sT0FBTyxDQUFDLHNCQUFzQixFQUFFLENBQUM7d0JBQ3pELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQzt3QkFDakUsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUN6QyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxFQUMxQyxPQUFPLENBQ1IsQ0FBQzt3QkFDRixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7d0JBQ3JFLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FDckMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLEVBQ3RDLE9BQU8sQ0FDUixDQUFDO3dCQUVGLElBQ0UsU0FBUzs0QkFDVCxDQUFDLGVBQWUsS0FBSyxNQUFNO2dDQUN6QixPQUFPLEtBQUssVUFBVTtnQ0FDdEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7Z0NBQzdCLFNBQVMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO2dDQUM1QixXQUFXLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQztnQ0FDM0IsV0FBVyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUM5QixDQUFDOzRCQUNELGNBQWMsR0FBRyxPQUFPLENBQUM7NEJBQ3pCLE1BQU07d0JBQ1IsQ0FBQztvQkFDSCxDQUFDO29CQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7d0JBQ2Ysd0NBQXdDO29CQUMxQyxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZix3QkFBd0I7WUFDMUIsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLGtDQUFZLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxjQUFjLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDN0IsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsaUJBQWlCO1lBQ25DLE1BQU8sY0FBc0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksa0NBQVksQ0FBQywyQkFBMkIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM3RCxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBVSxFQUFFLGNBQW1CLEVBQUUsSUFBWTtRQUNyRSxNQUFNLE9BQU8sR0FBRyxJQUFJO2FBQ2pCLEtBQUssQ0FBQyxHQUFHLENBQUM7YUFDVixHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUN4QixNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFbkMsS0FBSyxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUMxQixNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNqRCxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBVSxFQUFFLGNBQW1CLEVBQUUsR0FBVztRQUNuRSxJQUFJLENBQUM7WUFDSCxlQUFlO1lBQ2YsTUFBTSxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztZQUNyQyxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFbEIseUNBQXlDO1lBQ3pDLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1lBRXZFLElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ25CLE1BQU0sU0FBUyxHQUFHLE1BQU0sY0FBYyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDbEQsSUFBSSxTQUFTLEVBQUUsQ0FBQztvQkFDZCxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDeEIsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNuQixDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGlDQUFpQztnQkFDakMsTUFBTSxjQUFjLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNwQyxNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2pCLCtCQUErQjtnQkFDL0IsTUFBTSxjQUFjLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNwQyxNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbkIsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Ysb0JBQU0sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsS0FBSyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELENBQUM7SUFDSCxDQUFDO0lBRVMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFVLEVBQUUsSUFBWTtRQUM5QyxJQUFJLENBQUM7WUFDSCxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzRCxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNuQixNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNuRCxDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixvQkFBTSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM5QyxDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBVTtRQUNuQyxJQUFJLENBQUM7WUFDSCx5RUFBeUU7WUFDekUsSUFBSSxZQUFZLEdBQWdFLElBQUksQ0FBQztZQUNyRixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUNsRCxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLDJFQUEyRTtnQkFDM0UsTUFBTSxLQUFLLEdBQUcsTUFBTSxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM5QyxTQUFTLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUM7b0JBQ3hDLFVBQVUsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQztvQkFDMUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUM7aUJBQ25ELENBQUMsQ0FBQyxDQUFDO2dCQUNKLG9CQUFNLENBQUMsS0FBSyxDQUFDLHlDQUF5QyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDL0UsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRSxDQUFDO29CQUM1RCxZQUFZLEdBQUcsU0FBaUUsQ0FBQztnQkFDbkYsQ0FBQztZQUNILENBQUM7WUFFRCxnRUFBZ0U7WUFDaEUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNsQixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3hDLEtBQUssTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7b0JBQzFCLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztvQkFDOUQsSUFBSSxJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7d0JBQ3pCLFlBQVksR0FBRyxHQUEyRCxDQUFDO3dCQUMzRSxNQUFNO29CQUNSLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ2xCLHdFQUF3RTtnQkFDeEUsTUFBTSxjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUNsRCxLQUFLLE1BQU0sRUFBRSxJQUFJLGNBQWMsRUFBRSxDQUFDO29CQUNoQyxJQUFJLENBQUM7d0JBQ0gsTUFBTSxJQUFJLEdBQUcsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO3dCQUM3RCxJQUFJLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEVBQUUsQ0FBQzs0QkFDN0MsTUFBTSxTQUFTLEdBQUcsTUFBTSxFQUFFLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7NEJBQ3ZFLElBQUksU0FBUyxFQUFFLENBQUM7Z0NBQ2QsWUFBWSxHQUFHLEVBQTBELENBQUM7Z0NBQzFFLE1BQU07NEJBQ1IsQ0FBQzt3QkFDSCxDQUFDO29CQUNILENBQUM7b0JBQUMsTUFBTSxDQUFDO3dCQUNQLFNBQVM7b0JBQ1gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDbEIsTUFBTSxjQUFjLEdBQUcsdUZBQXVGLENBQUM7Z0JBQy9HLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFnRSxDQUFDO1lBQzdHLENBQUM7WUFFRCwrQkFBK0I7WUFDL0IsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNsQixNQUFNLFlBQVksR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQzFDLEtBQUssTUFBTSxJQUFJLElBQUksWUFBWSxFQUFFLENBQUM7b0JBQ2hDLE1BQU0sUUFBUSxHQUFHLE1BQU8sSUFBWSxDQUFDLEVBQUUsQ0FBQyx5QkFBeUIsSUFBSSxLQUFLLENBQUMsQ0FBQztvQkFDNUUsS0FBSyxNQUFNLEVBQUUsSUFBSSxRQUFRLEVBQUUsQ0FBQzt3QkFDMUIsSUFBSSxDQUFDOzRCQUNILE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQVcsRUFBRSxFQUFFO2dDQUM3QyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMscUJBQXFCLEVBQUUsQ0FBQztnQ0FDckMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7NEJBQ3JDLENBQUMsQ0FBQyxDQUFDOzRCQUNILElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQ0FDN0IsWUFBWSxHQUFHLEVBQTBELENBQUM7Z0NBQzFFLE1BQU07NEJBQ1IsQ0FBQzt3QkFDSCxDQUFDO3dCQUFDLE1BQU0sQ0FBQzs0QkFDUCxTQUFTO3dCQUNYLENBQUM7b0JBQ0gsQ0FBQztvQkFDRCxJQUFJLFlBQVk7d0JBQUUsTUFBTTtnQkFDMUIsQ0FBQztZQUNILENBQUM7WUFFRCxtREFBbUQ7WUFDbkQsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNsQixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQzVDLElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2QsTUFBTSxJQUFJLEdBQUcsTUFBTSxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUNwRSxJQUFJLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzt3QkFDekIsTUFBTSxNQUFNLEdBQUcsTUFBTSxTQUFTLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQ2pELEVBQUUsQ0FBQyxPQUFPLENBQUMscUNBQXFDLENBQUMsSUFBSSxFQUFFLENBQUMsYUFBYSxDQUN0RSxDQUFDO3dCQUNGLElBQUksTUFBTSxFQUFFLENBQUM7NEJBQ1gsWUFBWSxHQUFHLE1BQThELENBQUM7d0JBQ2hGLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDbEIsNENBQTRDO2dCQUM1QyxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFO29CQUN6QyxrQ0FBa0M7b0JBQ2xDLE1BQU0sZUFBZSxHQUFpRixFQUFFLENBQUM7b0JBQ3pHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7d0JBQzFDLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUM7d0JBQ3BDLElBQUksSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDOzRCQUN6QixNQUFNLElBQUksR0FBRyxFQUFFLENBQUMscUJBQXFCLEVBQUUsQ0FBQzs0QkFDeEMsZUFBZSxDQUFDLElBQUksQ0FBQztnQ0FDbkIsR0FBRyxFQUFFLEVBQUUsQ0FBQyxPQUFPO2dDQUNmLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7Z0NBQzNCLEtBQUssRUFBRyxFQUFrQixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQ0FDdEQsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQ0FDMUMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7NkJBQzdHLENBQUMsQ0FBQzt3QkFDTCxDQUFDO29CQUNILENBQUMsQ0FBQyxDQUFDO29CQUVILE9BQU87d0JBQ0wsR0FBRyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSTt3QkFDekIsVUFBVSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWTt3QkFDdEMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxXQUFXO3dCQUNsQyxlQUFlLEVBQUUsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO3FCQUM5QyxDQUFDO2dCQUNKLENBQUMsQ0FBQyxDQUFDO2dCQUVILE1BQU0sSUFBSSxrQ0FBWSxDQUFDLHFDQUFxQyxTQUFTLENBQUMsR0FBRyxVQUFVLFNBQVMsQ0FBQyxVQUFVLFFBQVEsU0FBUyxDQUFDLGNBQWMsa0JBQWtCLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN4TSxDQUFDO1lBRUQsMkRBQTJEO1lBQzNELE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO2dCQUM3QyxJQUFJLENBQUMsRUFBRTtvQkFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDO2dCQUNsQyxNQUFNLE1BQU0sR0FBRyxFQUFpQixDQUFDO2dCQUNqQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzlDLE9BQU87b0JBQ0wsTUFBTSxFQUFFLElBQUk7b0JBQ1osUUFBUSxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksTUFBTSxDQUFDLFlBQVksQ0FBQyxlQUFlLENBQUMsS0FBSyxNQUFNO29CQUM1RixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7b0JBQ2xDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztvQkFDdEIsVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO29CQUM1QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87b0JBQ3RCLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztvQkFDdkIsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTO29CQUMzQixJQUFJLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztpQkFDbEQsQ0FBQztZQUNKLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNqQixvQkFBTSxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFcEUsSUFBSSxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3pCLG9CQUFNLENBQUMsSUFBSSxDQUFDLGlEQUFpRCxDQUFDLENBQUM7WUFDakUsQ0FBQztZQUVELG1DQUFtQztZQUNuQyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtnQkFDekIsSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLENBQUMsY0FBYyxLQUFLLFVBQVUsRUFBRSxDQUFDO29CQUNsRCxFQUFFLENBQUMsY0FBYyxDQUFDLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztnQkFDOUQsQ0FBQztZQUNILENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNqQixNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFakIscUZBQXFGO1lBQ3JGLE1BQU0sa0JBQWtCLEdBQUcsS0FBSyxJQUFzQixFQUFFO2dCQUN0RCxJQUFJLENBQUM7b0JBQ0gsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO29CQUM5QixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxXQUFXLElBQUksRUFBRSxDQUFDLENBQUM7b0JBQzdFLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDO3dCQUM3QyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQzt3QkFDekIsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDN0IsQ0FBQztnQkFBQyxNQUFNLENBQUM7b0JBQ1AsT0FBTyxLQUFLLENBQUM7Z0JBQ2YsQ0FBQztZQUNILENBQUMsQ0FBQztZQUVGLG9GQUFvRjtZQUNwRixNQUFNLGVBQWUsR0FBRyxNQUFNLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssaUJBQWlCLENBQUMsQ0FBQztZQUM5RixJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUNwQixJQUFJLENBQUM7b0JBQ0gsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7d0JBQ3pCLElBQUksQ0FBQyxFQUFFOzRCQUFFLE9BQU87d0JBQ2hCLEVBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxXQUFXLENBQUMsU0FBUyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUNsRixDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7b0JBQ2pCLG9CQUFNLENBQUMsS0FBSyxDQUFDLHNEQUFzRCxDQUFDLENBQUM7Z0JBQ3ZFLENBQUM7Z0JBQUMsT0FBTyxnQkFBZ0IsRUFBRSxDQUFDO29CQUMxQixvQkFBTSxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRSxDQUFDO2dCQUNELE1BQU0sdUJBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbEIsSUFBSSxNQUFNLGtCQUFrQixFQUFFO29CQUFFLE9BQU87WUFDekMsQ0FBQztZQUVELG1GQUFtRjtZQUNuRixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7b0JBQ3pCLElBQUksQ0FBQyxFQUFFO3dCQUFFLE9BQU87b0JBQ2hCLE1BQU0sTUFBTSxHQUFHLEVBQWlCLENBQUM7b0JBQ2pDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO29CQUM1QyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO29CQUNyQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO29CQUNyQyxNQUFNLFNBQVMsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQztvQkFDdEgsTUFBTSxNQUFNLEdBQUc7d0JBQ2IsSUFBSSxVQUFVLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQzt3QkFDdkMsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQzt3QkFDdEMsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQzt3QkFDdEMsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFLEVBQUUsR0FBRyxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7d0JBQ3BFLElBQUksVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQzt3QkFDMUMsSUFBSSxVQUFVLENBQUMsU0FBUyxFQUFFLEVBQUUsR0FBRyxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7d0JBQ2xFLElBQUksVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLEdBQUcsU0FBUyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO3FCQUNqRSxDQUFDO29CQUNGLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDbkQsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUNqQixvQkFBTSxDQUFDLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1lBQ3JFLENBQUM7WUFBQyxPQUFPLFVBQVUsRUFBRSxDQUFDO2dCQUNwQixvQkFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUMxRCxDQUFDO1lBQ0QsTUFBTSx1QkFBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xCLElBQUksTUFBTSxrQkFBa0IsRUFBRTtnQkFBRSxPQUFPO1lBRXZDLGlEQUFpRDtZQUNqRCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQzNCLG9CQUFNLENBQUMsS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7WUFDbkUsQ0FBQztZQUFDLE9BQU8sVUFBVSxFQUFFLENBQUM7Z0JBQ3BCLG9CQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixVQUFVLEVBQUUsQ0FBQyxDQUFDO1lBQ3hELENBQUM7WUFDRCxNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakIsSUFBSSxNQUFNLGtCQUFrQixFQUFFO2dCQUFFLE9BQU87WUFFdkMsNENBQTRDO1lBQzVDLElBQUksQ0FBQztnQkFDSCxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRTtvQkFBRyxFQUFrQixDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUNwRixvQkFBTSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1lBQzlELENBQUM7WUFBQyxPQUFPLFlBQVksRUFBRSxDQUFDO2dCQUN0QixvQkFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsWUFBWSxFQUFFLENBQUMsQ0FBQztZQUM1RCxDQUFDO1lBQ0QsTUFBTSx1QkFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLElBQUksTUFBTSxrQkFBa0IsRUFBRTtnQkFBRSxPQUFPO1lBRXZDLHdFQUF3RTtZQUN4RSxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQzdDLElBQUksR0FBRyxFQUFFLENBQUM7b0JBQ1IsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztvQkFDckUsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO29CQUN4QixNQUFNLHVCQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ2hCLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDdEIsb0JBQU0sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztnQkFDOUQsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLFVBQVUsRUFBRSxDQUFDO2dCQUNwQixvQkFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUNwRCxDQUFDO1lBQ0QsTUFBTSx1QkFBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxJQUFJLGtDQUFZLENBQUMsa0NBQWtDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDcEUsQ0FBQztJQUNILENBQUM7SUFFUyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsT0FBZ0I7UUFDL0MsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFPLE9BQWUsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQ3pELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxJQUFVO1FBQ2pELE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxDQUFDLGdDQUFnQztRQUMzRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDN0IsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRW5DLE9BQU8sSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsR0FBRyxXQUFXLEVBQUUsQ0FBQztZQUM1QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFFOUIsNkRBQTZEO1lBQzdELE1BQU0saUJBQWlCLEdBQUc7Z0JBQ3hCLGtCQUFrQjtnQkFDbEIsa0JBQWtCO2dCQUNsQixpQ0FBaUM7Z0JBQ2pDLGdCQUFnQjthQUNqQixDQUFDO1lBRUYsS0FBSyxNQUFNLFFBQVEsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO2dCQUN6QyxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksT0FBTyxFQUFFLENBQUM7b0JBQ1osb0JBQU0sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLFFBQVEsRUFBRSxDQUFDLENBQUM7b0JBQ3JELE1BQU0sdUJBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDbEIsT0FBTyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDaEQsQ0FBQztZQUNILENBQUM7WUFFRCx5Q0FBeUM7WUFDekMsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLGdCQUFnQjtnQkFDaEIsZ0JBQWdCO2dCQUNoQiwrQkFBK0I7Z0JBQy9CLGNBQWM7Z0JBQ2QsY0FBYzthQUNmLENBQUM7WUFFRixLQUFLLE1BQU0sUUFBUSxJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUN2QyxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksT0FBTyxFQUFFLENBQUM7b0JBQ1osTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO29CQUN2RSxNQUFNLElBQUksa0NBQVksQ0FBQyw4QkFBOEIsU0FBUyxFQUFFLENBQUMsQ0FBQztnQkFDcEUsQ0FBQztZQUNILENBQUM7WUFFRCx1REFBdUQ7WUFDdkQsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLG9CQUFvQixFQUFFLFlBQVksRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBRXRGLElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFDO1lBQy9CLEtBQUssTUFBTSxRQUFRLElBQUkscUJBQXFCLEVBQUUsQ0FBQztnQkFDN0MsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLE9BQU8sRUFBRSxDQUFDO29CQUNaLGtCQUFrQixHQUFHLElBQUksQ0FBQztvQkFDMUIsTUFBTTtnQkFDUixDQUFDO1lBQ0gsQ0FBQztZQUVELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUN4QixvQkFBTSxDQUFDLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO2dCQUNwRCxPQUFPLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hELENBQUM7WUFFRCwrREFBK0Q7WUFDL0QsTUFBTSxjQUFjLEdBQUcsQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBRWpGLEtBQUssTUFBTSxRQUFRLElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ3RDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7b0JBQ3ZFLElBQUksU0FBUyxFQUFFLENBQUM7d0JBQ2QsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLFNBQVMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQzs0QkFDOUQsb0JBQU0sQ0FBQyxLQUFLLENBQUMsd0JBQXdCLFNBQVMsRUFBRSxDQUFDLENBQUM7NEJBQ2xELE9BQU8sTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ2hELENBQUM7NkJBQU0sSUFDTCxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzs0QkFDeEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7NEJBQzNCLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQ3hCLENBQUM7NEJBQ0QsTUFBTSxJQUFJLGtDQUFZLENBQUMsbUJBQW1CLFNBQVMsRUFBRSxDQUFDLENBQUM7d0JBQ3pELENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELGlEQUFpRDtZQUNqRCxNQUFNLG1CQUFtQixHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1lBQzlFLEtBQUssTUFBTSxFQUFFLElBQUksbUJBQW1CLEVBQUUsQ0FBQztnQkFDckMsSUFBSSxDQUFDO29CQUNILE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUM3RCxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO3dCQUM3QixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7NEJBQzNFLG9CQUFNLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxJQUFJLEVBQUUsQ0FBQyxDQUFDOzRCQUN0RCxPQUFPLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUNoRCxDQUFDO3dCQUNELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7NEJBQ25ELE1BQU0sSUFBSSxrQ0FBWSxDQUFDLG1CQUFtQixJQUFJLEVBQUUsQ0FBQyxDQUFDO3dCQUNwRCxDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztnQkFBQyxNQUFNLENBQUM7b0JBQ1AsU0FBUztnQkFDWCxDQUFDO1lBQ0gsQ0FBQztZQUVELHNFQUFzRTtZQUN0RSxJQUFJLFVBQVUsS0FBSyxlQUFlLEVBQUUsQ0FBQztnQkFDbkMsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUN4RixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7b0JBQ2xCLG9CQUFNLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxVQUFVLG9CQUFvQixDQUFDLENBQUM7b0JBQ2pGLE9BQU8sTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2hELENBQUM7WUFDSCxDQUFDO1lBRUQsaURBQWlEO1lBQ2pELE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsb0JBQW9CLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztZQUMvRyxLQUFLLE1BQU0sUUFBUSxJQUFJLGdCQUFnQixFQUFFLENBQUM7Z0JBQ3hDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixJQUFJLENBQUM7d0JBQ0gsTUFBTSxTQUFTLEdBQUcsTUFBTSxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQzVFLElBQUksU0FBUyxFQUFFLENBQUM7NEJBQ2QsTUFBTSxJQUFJLEdBQUcsTUFBTSxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7NEJBQ2xFLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQ0FDekQsb0JBQU0sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQ0FDMUUsT0FBTyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQzs0QkFDaEQsQ0FBQzt3QkFDSCxDQUFDO29CQUNILENBQUM7b0JBQUMsTUFBTSxDQUFDO3dCQUNQLFNBQVM7b0JBQ1gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELE1BQU0sdUJBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLHlCQUF5QjtRQUM3QyxDQUFDO1FBRUQsOEJBQThCO1FBQzlCLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDekMsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO1lBQzlCLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO2dCQUMzRSxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDO2dCQUNwQyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO29CQUNqRCxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN0QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDSCxPQUFPO2dCQUNMLEdBQUcsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUk7Z0JBQ3pCLFFBQVEsRUFBRSxRQUFRLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUU7Z0JBQzdELFlBQVksRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7YUFDaEYsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsb0JBQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzlELG9CQUFNLENBQUMsS0FBSyxDQUFDLGtCQUFrQixTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFckUsaUZBQWlGO1FBQ2pGLE1BQU0sbUJBQW1CLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDL0QsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQzlDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUN2RixDQUFDO1FBRUYsSUFBSSxDQUFDLG1CQUFtQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDMUMsb0JBQU0sQ0FBQyxJQUFJLENBQUMsNkVBQTZFLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQzFHLE9BQU8sTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUVELE1BQU0sSUFBSSxrQ0FBWSxDQUNwQixnRUFBZ0UsU0FBUyxDQUFDLEdBQUcsV0FBVyxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQzlJLENBQUM7SUFDSixDQUFDO0lBRVMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLElBQVU7UUFDOUMsSUFBSSxDQUFDO1lBQ0gsK0RBQStEO1lBQy9ELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM5QixvQkFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUV6RCx3RUFBd0U7WUFDeEUsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQztnQkFDN0QsVUFBVSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1lBRWhELElBQUksV0FBVyxJQUFJLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNsQyxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlCLG9CQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixNQUFNLEVBQUUsQ0FBQyxDQUFDO2dCQUN0RCxPQUFPLE1BQU0sQ0FBQztZQUNoQixDQUFDO1lBRUQsbUVBQW1FO1lBQ25FLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7Z0JBQzlDLHNEQUFzRDtnQkFDdEQsTUFBTSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsOENBQThDLENBQUMsQ0FBQztnQkFDbkcsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO29CQUNqRCxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDcEMsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUM7d0JBQ2pELE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDO3dCQUMvQixPQUFPLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUM7b0JBQzFDLElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyw4QkFBOEI7d0JBQ2hFLE9BQU8sTUFBTSxDQUFDO29CQUNoQixDQUFDO2dCQUNILENBQUM7Z0JBRUQsK0JBQStCO2dCQUMvQixNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsOENBQThDLENBQUMsQ0FBQztnQkFDNUYsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDMUMsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUMxQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUN2QyxJQUFJLElBQUksRUFBRSxDQUFDO3dCQUNULE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUM7NEJBQ2pELElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQzt3QkFDMUMsSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7NEJBQ3RCLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUNsQixDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxnRUFBZ0U7Z0JBQ2hFLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQztnQkFDcEQsTUFBTSxhQUFhLEdBQUcsaUJBQWlCLENBQUM7Z0JBQ3hDLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ2pELElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ2xDLHlDQUF5QztvQkFDekMsT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BCLENBQUM7Z0JBRUQsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUMsQ0FBQztZQUVILElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ25CLG9CQUFNLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxjQUFjLEVBQUUsQ0FBQyxDQUFDO2dCQUN2RSxPQUFPLGNBQWMsQ0FBQztZQUN4QixDQUFDO1lBRUQsdUVBQXVFO1lBQ3ZFLG9CQUFNLENBQUMsS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7WUFDNUUsSUFBSSxDQUFDO2dCQUNILDBDQUEwQztnQkFDMUMsTUFBTSx1QkFBSyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVsQiw0Q0FBNEM7Z0JBQzVDLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxNQUFNLHlGQUErQixDQUFDO2dCQUM5RCxNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztnQkFDdEQsTUFBTSxTQUFTLEdBQUcsTUFBTSxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsMkJBQTJCO2dCQUVoRixJQUFJLFNBQVMsQ0FBQyxPQUFPLElBQUksU0FBUyxDQUFDLElBQUksSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDckUsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQzFDLG9CQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxZQUFZLEVBQUUsQ0FBQyxDQUFDO29CQUNwRSxPQUFPLFlBQVksQ0FBQztnQkFDdEIsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLG9CQUFNLENBQUMsSUFBSSxDQUFDLHVDQUF1QyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzlELENBQUM7WUFFRCxvQkFBTSxDQUFDLEtBQUssQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1lBQzFELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixvQkFBTSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNuRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0NBQ0Y7OztBQzkrQm1GO0FBR2Q7QUFDekI7QUFDRjtBQUNEO0FBQ2Q7QUFDZ0M7QUFFckQsTUFBTSxtQkFBb0IsU0FBUSxrQkFBa0I7SUFDekQsS0FBSyxDQUFDLFdBQVcsQ0FDZixLQUFhLEVBQ2IsT0FBZSxFQUNmLFVBQW9CLEVBQ3BCLE9BQWUsRUFBRSxFQUNqQixXQUFvQjtRQUVwQixrQkFBa0I7UUFDbEIsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ25CLE1BQU0sSUFBSSxrQ0FBWSxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELHFFQUFxRTtRQUNyRSxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QixvQkFBTSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsS0FBSyxNQUFNLGFBQWEsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFMUYsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sSUFBSSxrQ0FBWSxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFDekQsQ0FBQztRQUVELElBQUksQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzQyxNQUFNLElBQUksa0NBQVksQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFFRCwrREFBK0Q7UUFDL0QsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsNEJBQTRCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFMUUscUNBQXFDO1FBQ3JDLE1BQU0sY0FBYyxHQUFHLG9CQUFvQixDQUFDO1FBRTVDLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFakYsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsaUJBQWlCLENBQzlDLElBQUksRUFDSixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUN2QyxDQUFDO2dCQUVGLHdCQUF3QjtnQkFDeEIsTUFBTSx1QkFBSyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVsQixvREFBb0Q7Z0JBQ3BELE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFaEMsa0NBQWtDO2dCQUNsQyxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRWxCLElBQUksa0JBQWtCLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxrQkFBa0IsQ0FDeEUsSUFBSSxFQUNKLGNBQWMsRUFDZCxLQUFLLENBQ04sQ0FBQztnQkFFRixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztvQkFDeEIsaURBQWlEO29CQUNqRCxNQUFNLG9CQUFvQixHQUFHO3dCQUMzQixvQkFBb0I7d0JBQ3BCLGlCQUFpQjt3QkFDakIsc0JBQXNCO3dCQUN0QixxQkFBcUI7d0JBQ3JCLG9CQUFvQjtxQkFDckIsQ0FBQztvQkFFRixLQUFLLE1BQU0sUUFBUSxJQUFJLG9CQUFvQixFQUFFLENBQUM7d0JBQzVDLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsa0JBQWtCLENBQ3BFLElBQUksRUFDSixRQUFRLEVBQ1IsS0FBSyxDQUNOLENBQUM7d0JBQ0YsSUFBSSxrQkFBa0IsRUFBRSxDQUFDOzRCQUN2QixNQUFNO3dCQUNSLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO2dCQUVELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO29CQUN4QixNQUFNLElBQUksa0NBQVksQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO2dCQUM1RSxDQUFDO2dCQUVELGdCQUFnQjtnQkFDaEIsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsQ0FBQztnQkFFN0Msc0VBQXNFO2dCQUN0RSxvQkFBTSxDQUFDLEtBQUssQ0FBQywrREFBK0QsQ0FBQyxDQUFDO2dCQUM5RSxNQUFNLHVCQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBRW5CLDhFQUE4RTtnQkFDOUUsSUFBSSxDQUFDO29CQUNILE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FDeEIsNEVBQTRFLEVBQzVFLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUNuQixDQUFDO2dCQUNKLENBQUM7Z0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztvQkFDZiwyQkFBMkI7Z0JBQzdCLENBQUM7Z0JBRUQsdURBQXVEO2dCQUN2RCxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRWxCLGdCQUFnQjtnQkFDaEIsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFFbEMsNkNBQTZDO2dCQUM3QyxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRWxCLGtCQUFrQjtnQkFDbEIsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFFdEMsdUJBQXVCO2dCQUN2QixJQUFJLElBQUksRUFBRSxDQUFDO29CQUNULE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2pDLENBQUM7Z0JBRUQsa0JBQWtCO2dCQUNsQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRTVCLHVDQUF1QztnQkFDdkMsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRXpELGVBQWU7Z0JBQ2YsTUFBTSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFekQsT0FBTztvQkFDTCxPQUFPLEVBQUUsSUFBSTtvQkFDYixPQUFPLEVBQUUsNkJBQTZCO29CQUN0QyxLQUFLO29CQUNMLE9BQU87b0JBQ1AsVUFBVSxFQUFFLGFBQWEsQ0FBQyxNQUFNO29CQUNoQyxJQUFJO29CQUNKLEdBQUcsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLGlCQUFpQjtvQkFDM0MsTUFBTSxFQUFFLE1BQU0sSUFBSSxTQUFTO2lCQUM1QixDQUFDO1lBQ0osQ0FBQztvQkFBUyxDQUFDO2dCQUNULE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3JCLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLGtCQUFrQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3hDLE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxVQUFvQjtRQUM3RCwrRUFBK0U7UUFDL0UsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRS9FLDBCQUEwQjtRQUMxQixLQUFLLE1BQU0sWUFBWSxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ3pDLHFEQUFxRDtZQUNyRCxNQUFNLFFBQVEsR0FDWixZQUFZLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDO2dCQUM5RCxDQUFDLENBQUMsWUFBWTtnQkFDZCxDQUFDLENBQUMsdUJBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFFeEMsSUFBSSxDQUFDLDJCQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDMUIsTUFBTSxJQUFJLHVDQUFpQixDQUFDLHlCQUF5QixZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZFLENBQUM7WUFFRCxNQUFNLEtBQUssR0FBRyx5QkFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxJQUFJLHVDQUFpQixDQUFDLHVCQUF1QixZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ3JFLENBQUM7WUFFRCx1QkFBdUI7WUFDdkIsTUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUN4RCxNQUFNLGlCQUFpQixHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN2RSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzdDLE1BQU0sSUFBSSx1Q0FBaUIsQ0FDekIsNkJBQTZCLFlBQVksZ0JBQWdCLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUN4RixDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLGFBQWEsQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDOUIsTUFBTSxJQUFJLGtDQUFZLENBQUMsMkJBQTJCLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBRUQsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVPLEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBVTtRQUNyQyxJQUFJLENBQUM7WUFDSCxvQkFBTSxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO1lBRW5ELHFEQUFxRDtZQUNyRCxNQUFNLGVBQWUsR0FBRyx3RkFBd0YsQ0FBQztZQUNqSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNoRixvQkFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBNEMsZUFBZSxFQUFFLENBQUMsQ0FBQztZQUM1RSxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFbEIseURBQXlEO1lBQ3pELE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3pDLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsV0FBVyxJQUFJLEVBQUUsQ0FBQztnQkFDbEQsT0FBTztvQkFDTCxjQUFjLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztvQkFDdEUsY0FBYyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7b0JBQ3RFLEdBQUcsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUk7aUJBQzFCLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztZQUNILG9CQUFNLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUUxRSxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsSUFBSSxTQUFTLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQzFELG9CQUFNLENBQUMsSUFBSSxDQUFDLGtFQUFrRSxDQUFDLENBQUM7Z0JBRWhGLDZDQUE2QztnQkFDN0MsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLCtDQUErQyxDQUFDLENBQUM7Z0JBQzVFLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7b0JBQ3ZCLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztvQkFDOUQsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO3dCQUMzRCxNQUFNLFNBQVMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDeEUsSUFBSSxDQUFDLFNBQVM7NEJBQUUsU0FBUzt3QkFFekIsNkJBQTZCO3dCQUM3QixNQUFNLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTs0QkFDeEIsTUFBTSxNQUFNLEdBQUcsRUFBaUIsQ0FBQzs0QkFDakMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7NEJBQzVFLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0NBQ2xCLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBSSxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDOzRCQUNoRixDQUFDLENBQUMsQ0FBQzt3QkFDTCxDQUFDLENBQUMsQ0FBQzt3QkFDSCxNQUFNLHVCQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7d0JBRWpCLE1BQU0sR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO3dCQUNsQixvQkFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO3dCQUNoRCxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ2xCLE1BQU07b0JBQ1IsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELE1BQU0sdUJBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFVLEVBQUUsVUFBb0I7UUFDekQsSUFBSSxDQUFDO1lBQ0gsb0JBQU0sQ0FBQyxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQztZQUV0RSxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxJQUFJLGtDQUFZLENBQUMsMENBQTBDLENBQUMsQ0FBQztZQUNyRSxDQUFDO1lBRUQsZ0ZBQWdGO1lBQ2hGLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQWtCLEVBQUUsRUFBRTtnQkFDekMsSUFBSSxFQUFFLEVBQUUsQ0FBQztvQkFDUCxFQUFFLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztvQkFDeEMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDL0IsQ0FBQztZQUNILENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUVkLG9CQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsVUFBVSxDQUFDLE1BQU0sb0NBQW9DLENBQUMsQ0FBQztZQUNsRixNQUFNLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQztZQUUxQyxtRUFBbUU7WUFDbkUsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBa0IsRUFBRSxFQUFFO2dCQUN6QyxJQUFJLEVBQUUsRUFBRSxDQUFDO29CQUNQLEVBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDM0QsQ0FBQztZQUNILENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUVkLE1BQU0sdUJBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxrQ0FBWSxDQUFDLDRCQUE0QixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzlELENBQUM7SUFDSCxDQUFDO0NBRUY7OztBQzFSbUY7QUFDRjtBQUN0RDtBQUV1QjtBQUNOO0FBQ0Y7QUFDRDtBQUNrQjtBQUVyRCxNQUFNLG1CQUFvQixTQUFRLGtCQUFrQjtJQUNqRCxLQUFLLENBQUMsNkJBQTZCLENBQUMsSUFBVTtRQUNwRCxvQkFBTSxDQUFDLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1FBRXhELElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztRQUV6QixNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FDekIsS0FBSyxJQUFJLEVBQUU7WUFDVCwrQkFBK0I7WUFDL0IsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQ3RELElBQUksRUFDSixTQUFTLENBQUMsa0JBQWtCLEVBQzVCLGFBQWEsQ0FBQyxPQUFPLENBQ3RCLENBQUM7WUFFRixJQUFJLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDeEIsb0JBQU0sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUMvRCxNQUFNLHVCQUFLLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQzdDLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztZQUVELDZCQUE2QjtZQUM3QixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FDcEQsSUFBSSxFQUNKLFNBQVMsQ0FBQyxnQkFBZ0IsRUFDMUIsYUFBYSxDQUFDLEtBQUssQ0FDcEIsQ0FBQztZQUVGLElBQUksV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN0QixNQUFNLElBQUksa0NBQVksQ0FBQyxvQ0FBb0MsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDakYsQ0FBQztZQUVELHdEQUF3RDtZQUN4RCxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FDbkQsSUFBSSxFQUNKLFNBQVMsQ0FBQyx1QkFBdUIsQ0FDbEMsQ0FBQztZQUNGLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDakIsb0JBQU0sQ0FBQyxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQztnQkFDbEUsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1lBRUQsOEJBQThCO1lBQzlCLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQ3pELElBQUksRUFDSixTQUFTLENBQUMscUJBQXFCLEVBQy9CLGFBQWEsQ0FBQyxVQUFVLENBQ3pCLENBQUM7WUFFRixZQUFZLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDO1lBQ3RDLElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ2pCLG9CQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLENBQUM7WUFFRCwyQkFBMkI7WUFDM0IsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQ3BELElBQUksRUFDSixTQUFTLENBQUMsZUFBZSxFQUN6QixhQUFhLENBQUMsT0FBTyxDQUN0QixDQUFDO1lBRUYsSUFBSSxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3RCLG9CQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixXQUFXLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDekQsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1lBRUQsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FDekQsSUFBSSxFQUNKLFNBQVMsQ0FBQyxlQUFlLEVBQ3pCLGFBQWEsQ0FBQyxLQUFLLENBQ3BCLENBQUM7WUFFRixJQUFJLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUMzQixNQUFNLElBQUksa0NBQVksQ0FBQyx5QkFBeUIsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUMzRSxDQUFDO1lBRUQsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDLEVBQ0QsY0FBYyxDQUFDLGtCQUFrQixFQUNqQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLGdCQUFnQixFQUNyRCwrRUFBK0UsQ0FDaEYsQ0FBQztRQUVGLDhDQUE4QztRQUM5QyxPQUFPLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWSxDQUNoQixLQUFhLEVBQ2IsT0FBZSxFQUNmLFNBQWlCLEVBQ2pCLE9BQWUsRUFBRSxFQUNqQixXQUFvQjtRQUVwQixrQkFBa0I7UUFDbEIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFcEQsa0NBQWtDO1FBQ2xDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXRFLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFakYsSUFBSSxDQUFDO2dCQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUVyRyxlQUFlO2dCQUNmLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRXpELE9BQU87b0JBQ0wsT0FBTyxFQUFFLElBQUk7b0JBQ2IsT0FBTyxFQUFFLDhCQUE4QjtvQkFDdkMsS0FBSztvQkFDTCxPQUFPO29CQUNQLFVBQVUsRUFBRSxDQUFDLEVBQUUsZ0NBQWdDO29CQUMvQyxJQUFJO29CQUNKLEdBQUcsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLHNCQUFzQjtvQkFDaEQsTUFBTSxFQUFFLE1BQU0sSUFBSSxTQUFTO2lCQUM1QixDQUFDO1lBQ0osQ0FBQztvQkFBUyxDQUFDO2dCQUNULE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3JCLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxLQUFhLEVBQUUsT0FBZSxFQUFFLFNBQWlCO1FBQzNFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUNuQixNQUFNLElBQUksa0NBQVksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFFRCwyQ0FBMkM7UUFDM0MscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0Isb0JBQU0sQ0FBQyxLQUFLLENBQUMseUNBQXlDLEtBQUssTUFBTSxhQUFhLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWhHLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUNyQixNQUFNLElBQUksa0NBQVksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBQzFELENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUM7WUFDdkIsTUFBTSxJQUFJLGtDQUFZLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUNuRCxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQywyQkFBMkIsQ0FDdkMsSUFBVSxFQUNWLEtBQWEsRUFDYixPQUFlLEVBQ2YsU0FBaUIsRUFDakIsSUFBWTtRQUVaLGdDQUFnQztRQUNoQyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLGlCQUFpQixDQUM5QyxJQUFJLEVBQ0osSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FDNUMsQ0FBQztRQUVGLHdCQUF3QjtRQUN4QixNQUFNLHVCQUFLLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXRDLHVDQUF1QztRQUN2QyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVyQyxrQ0FBa0M7UUFDbEMsTUFBTSx1QkFBSyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUV2QyxlQUFlO1FBQ2YsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUV4QyxrRUFBa0U7UUFDbEUsTUFBTSx1QkFBSyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRTdDLGdCQUFnQjtRQUNoQixNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRWxDLHdDQUF3QztRQUN4QyxNQUFNLHVCQUFLLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXpDLGtCQUFrQjtRQUNsQixNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRXRDLHVCQUF1QjtRQUN2QixJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBRUQsbUJBQW1CO1FBQ25CLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU1QixvRUFBb0U7UUFDcEUsT0FBTyxNQUFNLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRU8sMkJBQTJCLENBQUMsU0FBaUI7UUFDbkQsTUFBTSxZQUFZLEdBQ2hCLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7WUFDeEQsQ0FBQyxDQUFDLFNBQVM7WUFDWCxDQUFDLENBQUMsdUJBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFckMsSUFBSSxDQUFDLDJCQUFVLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksa0NBQVksQ0FBQyx5QkFBeUIsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcseUJBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLGtDQUFZLENBQUMsdUJBQXVCLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDN0QsQ0FBQztRQUVELHVCQUF1QjtRQUN2QixNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3JELE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM3RSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDN0MsTUFBTSxJQUFJLGtDQUFZLENBQ3BCLDZCQUE2QixTQUFTLGdCQUFnQixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDckYsQ0FBQztRQUNKLENBQUM7UUFFRCw2Q0FBNkM7UUFDN0MsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLENBQUMsY0FBYztRQUN2QyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ2hELElBQUksWUFBWSxHQUFHLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxrQ0FBWSxDQUNwQix5QkFBeUIsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsd0JBQXdCLFdBQVcsSUFBSSxDQUN4RixDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sWUFBWSxDQUFDO0lBQ3RCLENBQUM7SUFFTyxLQUFLLENBQUMsbUJBQW1CLENBQUMsSUFBVTtRQUMxQyxJQUFJLENBQUM7WUFDSCx1Q0FBdUM7WUFDdkMsTUFBTSxpQkFBaUIsR0FBRztnQkFDeEIsaUJBQWlCO2dCQUNqQixjQUFjO2dCQUNkLGNBQWM7Z0JBQ2QsTUFBTTtnQkFDTixtQkFBbUI7YUFDcEIsQ0FBQztZQUVGLElBQUksSUFBSSxHQUFVLEVBQUUsQ0FBQztZQUNyQixLQUFLLE1BQU0sUUFBUSxJQUFJLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3pDLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDMUMsSUFBSSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUN6QixJQUFJLEdBQUcsU0FBUyxDQUFDO29CQUNqQixNQUFNO2dCQUNSLENBQUM7WUFDSCxDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUN0QixvQkFBTSxDQUFDLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO2dCQUM5QyxPQUFPO1lBQ1QsQ0FBQztZQUVELDZDQUE2QztZQUM3QyxJQUFJLFFBQVEsR0FBUSxJQUFJLENBQUM7WUFDekIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNwQixJQUFJLENBQUM7b0JBQ0gsTUFBTSxTQUFTLEdBQUcsTUFBTSxHQUFHLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztvQkFDckQsSUFBSSxDQUFDLFNBQVM7d0JBQUUsU0FBUztvQkFFekIsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDO29CQUU5RCx3Q0FBd0M7b0JBQ3hDLElBQ0UsSUFBSTt3QkFDSixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQ3hFLENBQUM7d0JBQ0QsUUFBUSxHQUFHLEdBQUcsQ0FBQzt3QkFDZixNQUFNO29CQUNSLENBQUM7Z0JBQ0gsQ0FBQztnQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO29CQUNmLCtCQUErQjtnQkFDakMsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUNiLE1BQU0sUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN2QixNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxzQkFBc0I7WUFDM0MsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLHVEQUF1RDtnQkFDdkQsTUFBTSxXQUFXLEdBQVUsRUFBRSxDQUFDO2dCQUM5QixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO29CQUN2QixNQUFNLFNBQVMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO29CQUNyRCxJQUFJLFNBQVMsRUFBRSxDQUFDO3dCQUNkLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3hCLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQzNCLE1BQU0sV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsd0NBQXdDO29CQUN0RSxNQUFNLHVCQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3BCLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixvQkFBTSxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM1RCxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBVSxFQUFFLFNBQWlCO1FBQ3JELG9CQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBRTlDLDBCQUEwQjtRQUMxQixNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2hGLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxrQ0FBWSxDQUFDLHVEQUF1RCxDQUFDLENBQUM7UUFDbEYsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILGlDQUFpQztZQUNqQyxNQUFNLHVCQUFLLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRXpDLHdCQUF3QjtZQUN4QixNQUFNLFNBQVMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdEMsb0JBQU0sQ0FBQyxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztZQUUvRCw2Q0FBNkM7WUFDN0MsTUFBTSx1QkFBSyxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUV6QyxnRUFBZ0U7WUFDaEUsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksa0NBQVksQ0FBQywwQkFBMEIsU0FBUyxLQUFLLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDMUUsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsc0JBQXNCLENBQUMsSUFBVTtRQUM3QyxvQkFBTSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBRTVELElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUN6QixLQUFLLElBQUksRUFBRTtnQkFDVCxrQ0FBa0M7Z0JBQ2xDLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLHVCQUF1QixDQUN2RCxJQUFJLEVBQ0osU0FBUyxDQUFDLHFCQUFxQixFQUMvQixhQUFhLENBQUMsT0FBTyxDQUN0QixDQUFDO2dCQUVGLElBQUksY0FBYyxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUN6QixvQkFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7b0JBQ2xFLE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUM7Z0JBRUQsNEJBQTRCO2dCQUM1QixNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBSSxDQUFDLHVCQUF1QixDQUN6RCxJQUFJLEVBQ0osU0FBUyxDQUFDLHFCQUFxQixFQUMvQixhQUFhLENBQUMsVUFBVSxDQUN6QixDQUFDO2dCQUVGLElBQUksZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQzNCLG9CQUFNLENBQUMsS0FBSyxDQUFDLHFCQUFxQixnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUMzRCxPQUFPLEtBQUssQ0FBQyxDQUFDLHFDQUFxQztnQkFDckQsQ0FBQztnQkFFRCxrRUFBa0U7Z0JBQ2xFLG9CQUFNLENBQUMsS0FBSyxDQUFDLG9FQUFvRSxDQUFDLENBQUM7Z0JBQ25GLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQyxFQUNELGNBQWMsQ0FBQyxrQkFBa0IsRUFDakMsY0FBYyxDQUFDLGdCQUFnQixFQUMvQiwwQkFBMEIsQ0FDM0IsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Ysb0JBQU0sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELENBQUMsQ0FBQztRQUNoRSxDQUFDO0lBQ0gsQ0FBQztDQUVGOzs7QUM5WHVEO0FBRU07QUFDQTtBQUV2RCxNQUFNLGNBQWUsU0FBUSwrQkFBVztJQUNyQyxZQUFZLENBQXNCO0lBQ2xDLFlBQVksQ0FBc0I7SUFFMUMsWUFBWSxNQUFjLEVBQUUsY0FBK0I7UUFDekQsS0FBSyxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksbUJBQW1CLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksbUJBQW1CLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRU0sS0FBSyxDQUFDLFdBQVcsQ0FDdEIsS0FBYSxFQUNiLE9BQWUsRUFDZixVQUFvQixFQUNwQixPQUFlLEVBQUUsRUFDakIsV0FBb0I7UUFFcEIsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDdEYsQ0FBQztJQUVNLEtBQUssQ0FBQyxZQUFZLENBQ3ZCLEtBQWEsRUFDYixPQUFlLEVBQ2YsU0FBaUIsRUFDakIsT0FBZSxFQUFFLEVBQ2pCLFdBQW9CO1FBRXBCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFFTSxLQUFLLENBQUMsY0FBYyxDQUN6QixJQUF1QixFQUN2QixLQUFhLEVBQ2IsT0FBZSxFQUNmLFVBQW9CLEVBQ3BCLE9BQWUsRUFBRSxFQUNqQixXQUFvQjtRQUVwQixJQUFJLElBQUksS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUNyQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3pFLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztRQUM3RSxDQUFDO0lBQ0gsQ0FBQztDQUNGOzs7Ozs7O0FDbEREOztHQUVHO0FBRXdEO0FBQ0M7QUFDVztBQUNYO0FBQ1E7QUFDcEI7QUFDRDtBQU1uQjtBQUNpQjtBQUN3QjtBQXNCOUQsTUFBTSxZQUFZO0lBQ2YsV0FBVyxDQUFjO0lBQ3pCLFdBQVcsQ0FBYztJQUN6QixjQUFjLENBQWlCO0lBQy9CLFdBQVcsQ0FBYztJQUN6QixjQUFjLENBQWlCO0lBRXZDO1FBQ0UsTUFBTSxNQUFNLEdBQUcsbUNBQVMsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxzQ0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSx3QkFBVyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVELEtBQUssQ0FBQyxlQUFlLENBQ25CLFdBQW9CO1FBRXBCLDJEQUEyRDtRQUMzRCxrRUFBa0U7UUFDbEUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDbEQsa0NBQWdCLENBQUMsS0FBSyxFQUFFLHdCQUF3QixFQUFFLG9CQUFNLENBQUMsQ0FBQztRQUM1RCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU87WUFDTCxPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsSUFBSSxFQUFFLE1BQU07b0JBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQ2xCO3dCQUNFLE9BQU8sRUFBRSxJQUFJO3dCQUNiLE9BQU8sRUFDTCxrRkFBa0Y7d0JBQ3BGLE1BQU0sRUFBRSxlQUFlO3dCQUN2QixNQUFNLEVBQUUsZ0JBQWdCO3dCQUN4QixZQUFZLEVBQUU7NEJBQ1osNERBQTREOzRCQUM1RCwyQ0FBMkM7NEJBQzNDLDJEQUEyRDs0QkFDM0Qsb0RBQW9EO3lCQUNyRDt3QkFDRCxJQUFJLEVBQUUscUdBQXFHO3FCQUM1RyxFQUNELElBQUksRUFDSixDQUFDLENBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsS0FBSyxDQUFDLGdCQUFnQjtRQUNwQixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDL0MsT0FBTyx1Q0FBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsS0FBSyxDQUFDLGdCQUFnQixDQUNwQixXQUFvQjtRQUVwQixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQy9ELE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELEtBQUssQ0FBQyxtQkFBbUIsQ0FDdkIsV0FBb0I7UUFFcEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMvRCxPQUFPLHVDQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxLQUFLLENBQUMsZ0JBQWdCLENBQ3BCLE9BQWdCLEVBQ2hCLFdBQW9CO1FBRXBCLHdDQUFzQixDQUFDLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsT0FBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3pFLE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELEtBQUssQ0FBQyxtQkFBbUIsQ0FDdkIsTUFBZSxFQUNmLFNBQWtCLEVBQ2xCLFdBQW9CO1FBRXBCLHdDQUFzQixDQUFDLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxFQUFFLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDdkUsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxNQUFPLEVBQUUsU0FBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3RGLE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELEtBQUssQ0FBQyxtQkFBbUIsQ0FDdkIsTUFBZSxFQUNmLFNBQWtCLEVBQ2xCLElBQWEsRUFDYixXQUFvQjtRQUVwQix3Q0FBc0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDckYsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxNQUFPLEVBQUUsU0FBVSxFQUFFLElBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztRQUM3RixPQUFPLHVDQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxLQUFLLENBQUMsb0JBQW9CLENBQ3hCLElBQWEsRUFDYixLQUFjLEVBQ2QsT0FBZ0IsRUFDaEIsVUFBcUIsRUFDckIsSUFBYSxFQUNiLFdBQW9CO1FBRXBCLHdDQUFzQixDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEVBQUU7WUFDM0QsTUFBTTtZQUNOLE9BQU87WUFDUCxTQUFTO1lBQ1QsWUFBWTtTQUNiLENBQUMsQ0FBQztRQUVILHdCQUF3QjtRQUN4QixJQUFJLElBQUksS0FBSyxPQUFPLElBQUksSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ3pDLE1BQU0sSUFBSSxLQUFLLENBQUMseUNBQXlDLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBRUQsb0VBQW9FO1FBQ3BFLHFCQUFxQixDQUFDLEtBQU0sQ0FBQyxDQUFDO1FBQzlCLElBQUksT0FBUSxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQztZQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7UUFDN0QsQ0FBQztRQUVELHFDQUFxQztRQUNyQyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUNyRCxJQUF5QixFQUN6QixLQUFNLEVBQ04sT0FBUSxFQUNSLFVBQVcsRUFDWCxJQUFJLEVBQ0osV0FBVyxDQUNaLENBQUM7UUFDRixPQUFPLHVDQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxLQUFLLENBQUMsa0JBQWtCLENBQ3RCLEtBQWMsRUFDZCxNQUFlLEVBQ2YsV0FBb0I7UUFFcEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQy9FLE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FDcEIsTUFBZSxFQUNmLGFBQXVCLEVBQ3ZCLFdBQW9CO1FBRXBCLElBQUksYUFBYSxFQUFFLENBQUM7WUFDbEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLHVCQUF1QixDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzNFLE9BQU8sdUNBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkMsQ0FBQzthQUFNLElBQUksTUFBTSxFQUFFLENBQUM7WUFDbEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDdEUsT0FBTyx1Q0FBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QyxDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUN4RSxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUIsQ0FDckIsSUFBWSxFQUNaLE9BQXdCLEVBQUU7UUFFMUIsSUFBSSxDQUFDO1lBQ0gsUUFBUSxJQUFJLEVBQUUsQ0FBQztnQkFDYixLQUFLLGdCQUFnQjtvQkFDbkIsT0FBTyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLFlBQXNCLENBQUMsQ0FBQztnQkFFbEUsS0FBSyxpQkFBaUI7b0JBQ3BCLE9BQU8sTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztnQkFFdkMsS0FBSyxpQkFBaUI7b0JBQ3BCLE9BQU8sTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFlBQXNCLENBQUMsQ0FBQztnQkFFbkUsS0FBSyxvQkFBb0I7b0JBQ3ZCLE9BQU8sTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLFlBQXNCLENBQUMsQ0FBQztnQkFFdEUsS0FBSyxpQkFBaUI7b0JBQ3BCLE9BQU8sTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLE9BQWlCLEVBQUUsSUFBSSxFQUFFLFlBQXNCLENBQUMsQ0FBQztnQkFFNUYsS0FBSyxxQkFBcUI7b0JBQ3hCLE9BQU8sTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQ25DLElBQUksRUFBRSxPQUFpQixFQUN2QixJQUFJLEVBQUUsVUFBb0IsRUFDMUIsSUFBSSxFQUFFLFlBQXNCLENBQzdCLENBQUM7Z0JBRUosS0FBSyxxQkFBcUI7b0JBQ3hCLE9BQU8sTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQ25DLElBQUksRUFBRSxPQUFpQixFQUN2QixJQUFJLEVBQUUsVUFBb0IsRUFDMUIsSUFBSSxFQUFFLElBQWMsRUFDcEIsSUFBSSxFQUFFLFlBQXNCLENBQzdCLENBQUM7Z0JBRUosS0FBSyxxQkFBcUI7b0JBQ3hCLE9BQU8sTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQ3BDLElBQUksRUFBRSxJQUFjLEVBQ3BCLElBQUksRUFBRSxLQUFlLEVBQ3JCLElBQUksRUFBRSxPQUFpQixFQUN2QixJQUFJLEVBQUUsV0FBdUIsRUFDN0IsSUFBSSxFQUFFLElBQWMsRUFDcEIsSUFBSSxFQUFFLFlBQXNCLENBQzdCLENBQUM7Z0JBRUosS0FBSyxvQkFBb0I7b0JBQ3ZCLE9BQU8sTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQ2xDLElBQUksRUFBRSxLQUFlLEVBQ3JCLElBQUksRUFBRSxNQUFnQixFQUN0QixJQUFJLEVBQUUsWUFBc0IsQ0FDN0IsQ0FBQztnQkFFSixLQUFLLGlCQUFpQjtvQkFDcEIsT0FBTyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FDaEMsSUFBSSxFQUFFLE9BQWlCLEVBQ3ZCLElBQUksRUFBRSxjQUF5QixFQUMvQixJQUFJLEVBQUUsWUFBc0IsQ0FDN0IsQ0FBQztnQkFFSjtvQkFDRSxNQUFNLElBQUksS0FBSyxDQUFDLGlCQUFpQixJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzdDLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLDhCQUFRLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyx1Q0FBcUIsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUMvQyxDQUFDO1lBQ0QsT0FBTyx3Q0FBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QyxDQUFDO0lBQ0gsQ0FBQztDQUNGOzs7QUNsUkQ7O0dBRUc7QUFFSCwwQkFBMEI7QUFDRDtBQUNEO0FBRXhCLFlBQVk7QUFDWTtBQUNJO0FBQ0Y7QUFDUztBQUNEO0FBRWxDLDZCQUE2QjtBQUNKO0FBQ0E7QUFFekIsZUFBZTtBQUNnQjs7O0FDcEIvQjs7R0FFRztBQUV3RDtBQUNJO0FBRXhELE1BQU0sZ0JBQWdCO0lBQ25CLFdBQVcsQ0FBYztJQUVqQztRQUNFLE1BQU0sTUFBTSxHQUFHLG1DQUFTLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxLQUFLLENBQUMsa0JBQWtCO1FBQ3RCLElBQUksQ0FBQztZQUNILE1BQU0sV0FBVyxHQUFHLGtDQUFjLEVBQUUsQ0FBQztZQUNyQyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0QsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCO1FBQ3JCLElBQUksQ0FBQztZQUNILE1BQU0sVUFBVSxHQUFHLG1DQUFTLEVBQUUsQ0FBQztZQUMvQixNQUFNLG1CQUFtQixHQUFHO2dCQUMxQixHQUFHLFVBQVU7Z0JBQ2IsU0FBUyxFQUFFLGdCQUFnQjtnQkFDM0IsT0FBTyxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTzthQUNuQyxDQUFDO1lBQ0YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLG1CQUFtQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0QsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCO1FBQ3JCLElBQUksQ0FBQztZQUNILG1EQUFtRDtZQUNuRCxJQUFJLFVBQVUsR0FBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLDRCQUE0QixFQUFFLENBQUM7WUFDakYsSUFBSSxDQUFDO2dCQUNILFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDcEQsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsVUFBVSxHQUFHLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekQsQ0FBQztZQUVELE1BQU0sV0FBVyxHQUFHLGtDQUFjLEVBQUUsQ0FBQztZQUNyQyxNQUFNLE1BQU0sR0FBRyxtQ0FBUyxFQUFFLENBQUM7WUFFM0IsTUFBTSxVQUFVLEdBQUc7Z0JBQ2pCLE1BQU0sRUFBRTtvQkFDTixNQUFNLEVBQUUsU0FBUztvQkFDakIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSTtvQkFDeEIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTztvQkFDOUIsU0FBUyxFQUFFLGdCQUFnQjtpQkFDNUI7Z0JBQ0QsY0FBYyxFQUFFLFVBQVU7Z0JBQzFCLE9BQU8sRUFBRTtvQkFDUCxVQUFVLEVBQUUsV0FBVyxDQUFDLFVBQVU7b0JBQ2xDLFdBQVcsRUFBRSxXQUFXLENBQUMsV0FBVztpQkFDckM7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLGNBQWMsRUFBRSxDQUFDO29CQUNqQixnQkFBZ0IsRUFBRSxDQUFDO29CQUNuQixrQkFBa0IsRUFBRSxDQUFDO2lCQUN0QjthQUNGLENBQUM7WUFFRixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FDbkI7Z0JBQ0UsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUNqRCxTQUFTLEVBQUUsZ0JBQWdCO2FBQzVCLEVBQ0QsSUFBSSxFQUNKLENBQUMsQ0FDRixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMscUJBQXFCLENBQUMsR0FBVztRQUNyQyxJQUFJLENBQUM7WUFDSCxJQUFJLE9BQWUsQ0FBQztZQUVwQixRQUFRLEdBQUcsRUFBRSxDQUFDO2dCQUNaLEtBQUssZUFBZTtvQkFDbEIsT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7b0JBQzFDLE1BQU07Z0JBRVIsS0FBSyxjQUFjO29CQUNqQixPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztvQkFDekMsTUFBTTtnQkFFUixLQUFLLGNBQWM7b0JBQ2pCLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO29CQUN6QyxNQUFNO2dCQUVSO29CQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDaEQsQ0FBQztZQUVELE9BQU87Z0JBQ0wsUUFBUSxFQUFFO29CQUNSO3dCQUNFLEdBQUc7d0JBQ0gsUUFBUSxFQUFFLGtCQUFrQjt3QkFDNUIsSUFBSSxFQUFFLE9BQU87cUJBQ2Q7aUJBQ0Y7YUFDRixDQUFDO1FBQ0osQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPO2dCQUNMLFFBQVEsRUFBRTtvQkFDUjt3QkFDRSxHQUFHO3dCQUNILFFBQVEsRUFBRSxrQkFBa0I7d0JBQzVCLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7cUJBQ3hEO2lCQUNGO2FBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0Y7OztBQzdIRDs7R0FFRztBQVlJLE1BQU0sZ0JBQWdCLEdBQWlCO0lBQzVDO1FBQ0UsSUFBSSxFQUFFLGdCQUFnQjtRQUN0QixXQUFXLEVBQUUsa0NBQWtDO1FBQy9DLFdBQVcsRUFBRTtZQUNYLElBQUksRUFBRSxRQUFRO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLFlBQVksRUFBRTtvQkFDWixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUscUNBQXFDO2lCQUNuRDthQUNGO1NBQ0Y7S0FDRjtJQUNEO1FBQ0UsSUFBSSxFQUFFLGlCQUFpQjtRQUN2QixXQUFXLEVBQUUsaURBQWlEO1FBQzlELFdBQVcsRUFBRTtZQUNYLElBQUksRUFBRSxRQUFRO1lBQ2QsVUFBVSxFQUFFLEVBQUU7U0FDZjtLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsaUJBQWlCO1FBQ3ZCLFdBQVcsRUFBRSwyREFBMkQ7UUFDeEUsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7U0FDRjtLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsb0JBQW9CO1FBQzFCLFdBQVcsRUFBRSwwQkFBMEI7UUFDdkMsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7U0FDRjtLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsaUJBQWlCO1FBQ3ZCLFdBQVcsRUFBRSw4QkFBOEI7UUFDM0MsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSwyQkFBMkI7aUJBQ3pDO2dCQUNELFlBQVksRUFBRTtvQkFDWixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUscUNBQXFDO2lCQUNuRDthQUNGO1lBQ0QsUUFBUSxFQUFFLENBQUMsU0FBUyxDQUFDO1NBQ3RCO0tBQ0Y7SUFDRDtRQUNFLElBQUksRUFBRSxxQkFBcUI7UUFDM0IsV0FBVyxFQUFFLGlEQUFpRDtRQUM5RCxXQUFXLEVBQUU7WUFDWCxJQUFJLEVBQUUsUUFBUTtZQUNkLFVBQVUsRUFBRTtnQkFDVixPQUFPLEVBQUU7b0JBQ1AsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLG9CQUFvQjtpQkFDbEM7Z0JBQ0QsVUFBVSxFQUFFO29CQUNWLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSx3Q0FBd0M7aUJBQ3REO2dCQUNELFlBQVksRUFBRTtvQkFDWixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUscUNBQXFDO2lCQUNuRDthQUNGO1lBQ0QsUUFBUSxFQUFFLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQztTQUNwQztLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUscUJBQXFCO1FBQzNCLFdBQVcsRUFBRSxvQkFBb0I7UUFDakMsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxvQkFBb0I7aUJBQ2xDO2dCQUNELFVBQVUsRUFBRTtvQkFDVixJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUsd0NBQXdDO2lCQUN0RDtnQkFDRCxJQUFJLEVBQUU7b0JBQ0osSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLHlCQUF5QjtpQkFDdkM7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7WUFDRCxRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQztTQUM1QztLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUscUJBQXFCO1FBQzNCLFdBQVcsRUFBRSxtRUFBbUU7UUFDaEYsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSxFQUFFO29CQUNKLElBQUksRUFBRSxRQUFRO29CQUNkLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUM7b0JBQ3hCLFdBQVcsRUFBRSxpRUFBaUU7aUJBQy9FO2dCQUNELEtBQUssRUFBRTtvQkFDTCxJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUsNkNBQTZDO29CQUMxRCxTQUFTLEVBQUUsRUFBRTtpQkFDZDtnQkFDRCxPQUFPLEVBQUU7b0JBQ1AsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLHFEQUFxRDtvQkFDbEUsU0FBUyxFQUFFLElBQUk7aUJBQ2hCO2dCQUNELFdBQVcsRUFBRTtvQkFDWCxJQUFJLEVBQUUsT0FBTztvQkFDYixLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO29CQUN6QixXQUFXLEVBQ1QsaUhBQWlIO29CQUNuSCxRQUFRLEVBQUUsRUFBRTtpQkFDYjtnQkFDRCxJQUFJLEVBQUU7b0JBQ0osSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLGlDQUFpQztpQkFDL0M7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7WUFDRCxRQUFRLEVBQUUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLENBQUM7U0FDdEQ7S0FDRjtJQUNEO1FBQ0UsSUFBSSxFQUFFLG9CQUFvQjtRQUMxQixXQUFXLEVBQUUsOEJBQThCO1FBQzNDLFdBQVcsRUFBRTtZQUNYLElBQUksRUFBRSxRQUFRO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEtBQUssRUFBRTtvQkFDTCxJQUFJLEVBQUUsUUFBUTtvQkFDZCxXQUFXLEVBQUUsd0NBQXdDO2lCQUN0RDtnQkFDRCxNQUFNLEVBQUU7b0JBQ04sSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLGlDQUFpQztpQkFDL0M7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxxQ0FBcUM7aUJBQ25EO2FBQ0Y7U0FDRjtLQUNGO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsaUJBQWlCO1FBQ3ZCLFdBQVcsRUFBRSw2REFBNkQ7UUFDMUUsV0FBVyxFQUFFO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSxpRUFBaUU7aUJBQy9FO2dCQUNELGNBQWMsRUFBRTtvQkFDZCxJQUFJLEVBQUUsU0FBUztvQkFDZixXQUFXLEVBQUUsa0VBQWtFO2lCQUNoRjtnQkFDRCxZQUFZLEVBQUU7b0JBQ1osSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLHFDQUFxQztpQkFDbkQ7YUFDRjtTQUNGO0tBQ0Y7Q0FDRixDQUFDO0FBRUssTUFBTSxvQkFBb0IsR0FBRztJQUNsQztRQUNFLEdBQUcsRUFBRSxlQUFlO1FBQ3BCLElBQUksRUFBRSw0QkFBNEI7UUFDbEMsV0FBVyxFQUFFLHFEQUFxRDtRQUNsRSxRQUFRLEVBQUUsa0JBQWtCO0tBQzdCO0lBQ0Q7UUFDRSxHQUFHLEVBQUUsY0FBYztRQUNuQixJQUFJLEVBQUUsMEJBQTBCO1FBQ2hDLFdBQVcsRUFBRSw4QkFBOEI7UUFDM0MsUUFBUSxFQUFFLGtCQUFrQjtLQUM3QjtJQUNEO1FBQ0UsR0FBRyxFQUFFLGNBQWM7UUFDbkIsSUFBSSxFQUFFLG1CQUFtQjtRQUN6QixXQUFXLEVBQUUsMENBQTBDO1FBQ3ZELFFBQVEsRUFBRSxrQkFBa0I7S0FDN0I7Q0FDRixDQUFDOzs7QUN2T0Y7O0dBRUc7QUFFZ0U7QUFDYztBQU1yQztBQUNDO0FBQ1c7QUFDUTtBQUNnQjtBQUV6RSxNQUFNLFlBQVk7SUFDZixNQUFNLENBQVM7SUFDZixZQUFZLENBQWU7SUFDM0IsZ0JBQWdCLENBQW1CO0lBQ25DLE1BQU0sQ0FBK0I7SUFFN0M7UUFDRSxJQUFJLENBQUMsTUFBTSxHQUFHLG1DQUFTLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksd0JBQU0sQ0FDdEI7WUFDRSxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSTtZQUM3QixPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTztTQUNwQyxFQUNEO1lBQ0UsWUFBWSxFQUFFO2dCQUNaLEtBQUssRUFBRSxFQUFFO2dCQUNULFNBQVMsRUFBRSxFQUFFO2FBQ2Q7U0FDRixDQUNGLENBQUM7UUFFRixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsbUNBQXFCLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ3JFLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFDakQsT0FBTyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxvQ0FBc0IsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMvRCxPQUFPO2dCQUNMLEtBQUssRUFBRSxnQkFBZ0I7YUFDeEIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLHFCQUFxQjtRQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLHdDQUEwQixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ25FLE9BQU87Z0JBQ0wsU0FBUyxFQUFFLG9CQUFvQjthQUNoQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLHVDQUF5QixFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUN6RSxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztZQUMvQixPQUFPLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2hFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFLO1FBQ1QsTUFBTSxTQUFTLEdBQUcsSUFBSSxpQ0FBb0IsRUFBRSxDQUFDO1FBQzdDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsMkVBQTJFO0lBQzdFLENBQUM7Q0FDRjs7O0FDM0VELE1BQU0sZ0NBQTRCLHNCOzs7QUNBbEMsTUFBTSw2QkFBNEIsbUI7Ozs7Ozs7OztBQ0FsQzs7R0FFRztBQUUyQjtBQUNOO0FBQ2lCO0FBQzBCO0FBQ1U7QUFDc0I7QUFDMUI7QUFDNUI7QUFDSDtBQUNjO0FBQ1E7QUFDZ0I7QUFNcEM7QUFFckMsTUFBTSxnQkFBZ0I7SUFDbkIsR0FBRyxDQUFzQjtJQUN6QixNQUFNLENBQStCO0lBQ3JDLFlBQVksQ0FBZTtJQUMzQixnQkFBZ0IsQ0FBbUI7SUFDbkMsVUFBVSxHQUFvRSxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3hGLElBQUksQ0FBUztJQUVyQixZQUFZLE9BQWUsSUFBSTtRQUM3QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLG1DQUFTLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsR0FBRyxHQUFHLDBCQUFPLEVBQUUsQ0FBQztRQUVyQixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFTyxlQUFlO1FBQ3JCLG9CQUFvQjtRQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQywrQkFBWSxFQUFFLENBQUMsQ0FBQztRQUU3QiwyRUFBMkU7UUFDM0UsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQ1YsdUJBQUksQ0FBQztZQUNILE1BQU0sRUFBRSxHQUFHLEVBQUUsc0RBQXNEO1lBQ25FLGNBQWMsRUFBRSxDQUFDLGdCQUFnQixDQUFDO1NBQ25DLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVPLFdBQVc7UUFDakIsMERBQTBEO1FBQzFELElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFM0QsOERBQThEO1FBQzlELElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUU3RCx3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQ25DLEdBQUcsQ0FBQyxJQUFJLENBQUM7Z0JBQ1AsTUFBTSxFQUFFLFNBQVM7Z0JBQ2pCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJO2dCQUMvQixPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTztnQkFDbkMsVUFBVSxFQUFFLENBQUMsaUJBQWlCLEVBQUUsS0FBSyxDQUFDO2FBQ3ZDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxHQUFvQixFQUFFLEdBQXFCO1FBQzVFLG9CQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLE1BQU0sa0JBQWtCLENBQUMsQ0FBQztRQUV0RCxJQUFJLENBQUM7WUFDSCxnQ0FBZ0M7WUFDaEMsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBVyxDQUFDO1lBQzFELElBQUksU0FBb0QsQ0FBQztZQUV6RCxJQUFJLFNBQVMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUNoRCxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUN6RCxJQUFJLGlCQUFpQixZQUFZLG1EQUE2QixFQUFFLENBQUM7b0JBQy9ELFNBQVMsR0FBRyxpQkFBaUIsQ0FBQztnQkFDaEMsQ0FBQztxQkFBTSxDQUFDO29CQUNOLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO3dCQUNuQixPQUFPLEVBQUUsS0FBSzt3QkFDZCxLQUFLLEVBQUU7NEJBQ0wsSUFBSSxFQUFFLENBQUMsS0FBSzs0QkFDWixPQUFPLEVBQUUscUVBQXFFO3lCQUMvRTt3QkFDRCxFQUFFLEVBQUUsSUFBSTtxQkFDVCxDQUFDLENBQUM7b0JBQ0gsT0FBTztnQkFDVCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxJQUFJLENBQUMsU0FBUyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTSxJQUFJLHFDQUFtQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNoRix1Q0FBdUM7Z0JBQ3ZDLFNBQVMsR0FBRyxJQUFJLG1EQUE2QixDQUFDO29CQUM1QyxrQkFBa0IsRUFBRSxHQUFXLEVBQUUsQ0FBQyxvQ0FBVSxFQUFFO29CQUM5QyxvQkFBb0IsRUFBRSxDQUFDLFNBQWlCLEVBQVEsRUFBRTt3QkFDaEQsb0JBQU0sQ0FBQyxJQUFJLENBQUMsK0NBQStDLFNBQVMsRUFBRSxDQUFDLENBQUM7d0JBQ3hFLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxTQUFVLENBQUMsQ0FBQztvQkFDN0MsQ0FBQztvQkFDRCxlQUFlLEVBQUUsQ0FBQyxTQUFpQixFQUFRLEVBQUU7d0JBQzNDLG9CQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO3dCQUMzRCxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDcEMsQ0FBQztpQkFDRixDQUFDLENBQUM7Z0JBRUgsMkRBQTJEO2dCQUMzRCxTQUFTLENBQUMsT0FBTyxHQUFHLEdBQVMsRUFBRTtvQkFDN0IsTUFBTSxHQUFHLEdBQUcsU0FBVSxDQUFDLFNBQVMsQ0FBQztvQkFDakMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQzt3QkFDcEMsb0JBQU0sQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLEdBQUcsZ0NBQWdDLENBQUMsQ0FBQzt3QkFDakYsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQzlCLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDO2dCQUVGLDBDQUEwQztnQkFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN0QyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbEMsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGdFQUFnRTtnQkFDaEUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ25CLE9BQU8sRUFBRSxLQUFLO29CQUNkLEtBQUssRUFBRTt3QkFDTCxJQUFJLEVBQUUsQ0FBQyxLQUFLO3dCQUNaLE9BQU8sRUFBRSwyQ0FBMkM7cUJBQ3JEO29CQUNELEVBQUUsRUFBRSxJQUFJO2lCQUNULENBQUMsQ0FBQztnQkFDSCxPQUFPO1lBQ1QsQ0FBQztZQUVELHdDQUF3QztZQUN4QyxNQUFNLFNBQVMsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEQsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixvQkFBTSxDQUFDLEtBQUssQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNyQixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDbkIsT0FBTyxFQUFFLEtBQUs7b0JBQ2QsS0FBSyxFQUFFO3dCQUNMLElBQUksRUFBRSxDQUFDLEtBQUs7d0JBQ1osT0FBTyxFQUFFLHVCQUF1QjtxQkFDakM7b0JBQ0QsRUFBRSxFQUFFLElBQUk7aUJBQ1QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLG1CQUFtQixDQUFDLEdBQW9CLEVBQUUsR0FBcUI7UUFDM0Usb0JBQU0sQ0FBQyxJQUFJLENBQUMseURBQXlELENBQUMsQ0FBQztRQUV2RSxJQUFJLENBQUM7WUFDSCxNQUFNLFNBQVMsR0FBRyxJQUFJLDZCQUFrQixDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMzRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBRXBELEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzlDLENBQUMsQ0FBQyxDQUFDO1lBRUgsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3RDLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNsQyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3JCLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO29CQUNuQixPQUFPLEVBQUUsS0FBSztvQkFDZCxLQUFLLEVBQUU7d0JBQ0wsSUFBSSxFQUFFLENBQUMsS0FBSzt3QkFDWixPQUFPLEVBQUUsdUJBQXVCO3FCQUNqQztvQkFDRCxFQUFFLEVBQUUsSUFBSTtpQkFDVCxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsR0FBb0IsRUFBRSxHQUFxQjtRQUN4RSxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLFNBQW1CLENBQUM7UUFFaEQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFakQsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsU0FBUyxZQUFZLDZCQUFrQixDQUFDLEVBQUUsQ0FBQztnQkFDN0QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ25CLE9BQU8sRUFBRSxLQUFLO29CQUNkLEtBQUssRUFBRTt3QkFDTCxJQUFJLEVBQUUsQ0FBQyxLQUFLO3dCQUNaLE9BQU8sRUFBRSxxRUFBcUU7cUJBQy9FO29CQUNELEVBQUUsRUFBRSxJQUFJO2lCQUNULENBQUMsQ0FBQztnQkFDSCxPQUFPO1lBQ1QsQ0FBQztZQUVELE1BQU0sU0FBUyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Ysb0JBQU0sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDckIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ25CLE9BQU8sRUFBRSxLQUFLO29CQUNkLEtBQUssRUFBRTt3QkFDTCxJQUFJLEVBQUUsQ0FBQyxLQUFLO3dCQUNaLE9BQU8sRUFBRSx1QkFBdUI7cUJBQ2pDO29CQUNELEVBQUUsRUFBRSxJQUFJO2lCQUNULENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLGVBQWU7UUFDckIsTUFBTSxNQUFNLEdBQUcsSUFBSSx3QkFBTSxDQUN2QjtZQUNFLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJO1lBQzdCLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPO1NBQ3BDLEVBQ0Q7WUFDRSxZQUFZLEVBQUU7Z0JBQ1osS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsU0FBUyxFQUFFLEVBQUU7YUFDZDtTQUNGLENBQ0YsQ0FBQztRQUVGLHNCQUFzQjtRQUN0QixNQUFNLENBQUMsaUJBQWlCLENBQUMsbUNBQXFCLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ2hFLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFDakQsT0FBTyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLGlCQUFpQixDQUFDLG9DQUFzQixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzFELE9BQU87Z0JBQ0wsS0FBSyxFQUFFLGdCQUFnQjthQUN4QixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCwwQkFBMEI7UUFDMUIsTUFBTSxDQUFDLGlCQUFpQixDQUFDLHdDQUEwQixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlELE9BQU87Z0JBQ0wsU0FBUyxFQUFFLG9CQUFvQjthQUNoQyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsaUJBQWlCLENBQUMsdUNBQXlCLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ3BFLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQy9CLE9BQU8sTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsS0FBSyxDQUFDLEtBQUs7UUFDVCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFhLEVBQUUsRUFBRTtnQkFDMUQsSUFBSSxLQUFLLEVBQUUsQ0FBQztvQkFDVixvQkFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDcEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNkLE9BQU87Z0JBQ1QsQ0FBQztnQkFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLHlDQUF5QyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLEdBQUcsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBd0JuQixDQUFDLENBQUM7Z0JBQ0ssT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDLENBQUMsQ0FBQztZQUVILHlCQUF5QjtZQUN6QixPQUFPLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDOUIsb0JBQU0sQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQztnQkFFNUMsS0FBSyxNQUFNLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztvQkFDckQsSUFBSSxDQUFDO3dCQUNILG9CQUFNLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO3dCQUMxRCxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDMUIsQ0FBQztvQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO3dCQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxTQUFTLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDM0UsQ0FBQztnQkFDSCxDQUFDO2dCQUVELElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3hCLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFO29CQUNoQixvQkFBTSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO29CQUM3QyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNsQixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1lBRUgsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQy9CLG9CQUFNLENBQUMsSUFBSSxDQUFDLDhCQUE4QixDQUFDLENBQUM7Z0JBRTVDLEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7b0JBQ3JELElBQUksQ0FBQzt3QkFDSCxvQkFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsU0FBUyxFQUFFLENBQUMsQ0FBQzt3QkFDMUQsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQzFCLENBQUM7b0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzt3QkFDZixvQkFBTSxDQUFDLEtBQUssQ0FBQyx1Q0FBdUMsU0FBUyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQzNFLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN4QixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRTtvQkFDaEIsb0JBQU0sQ0FBQyxJQUFJLENBQUMsK0JBQStCLENBQUMsQ0FBQztvQkFDN0MsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEIsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFJO1FBQ1IsOEJBQThCO1FBQzlCLEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDckQsSUFBSSxDQUFDO2dCQUNILE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzFCLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLG9CQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxTQUFTLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzRSxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDMUIsQ0FBQztDQUNGOzs7QUMxVkQ7O0dBRUc7QUFFNkI7QUFDSTs7O0FDTHBDOztHQUVHO0FBRTBCO0FBQ0M7QUFDRzs7OztBQ0pqQzs7R0FFRztBQUVpQztBQUNTO0FBQ1c7QUFDdEI7QUFDYTtBQUNrQjtBQUNDO0FBQ1Q7QUFDVztBQUNYO0FBRXpEOztHQUVHO0FBQ0gsTUFBTSxRQUFRO0lBQ1E7SUFBcEIsWUFBb0IsT0FBZ0I7UUFBaEIsWUFBTyxHQUFQLE9BQU8sQ0FBUztJQUFHLENBQUM7SUFFeEMsa0JBQWtCLENBQUMsS0FBYztRQUMvQixNQUFNLEdBQUcsR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFcEYsaUNBQWlDO1FBQ2pDLElBQUksc0RBQXNELENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckUsT0FBTywwRkFBMEYsQ0FBQztRQUNwRyxDQUFDO1FBRUQsc0VBQXNFO1FBQ3RFLElBQUksS0FBSyxZQUFZLEtBQUssRUFBRSxDQUFDO1lBQzNCLHFFQUFxRTtZQUNyRSxJQUNFLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLHdEQUF3RCxDQUFDO2dCQUNoRixLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQztnQkFDL0MsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUM7Z0JBQzVDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDO2dCQUN4QyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxFQUNqRCxDQUFDO2dCQUNELE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQztZQUN2QixDQUFDO1lBRUQsMkNBQTJDO1lBQzNDLE1BQU0sU0FBUyxHQUFHLEdBQUc7aUJBQ2xCLE9BQU8sQ0FDTix5S0FBeUssRUFDekssRUFBRSxDQUNIO2lCQUNBLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLENBQUMsQ0FBQyx5QkFBeUI7aUJBQzFELE9BQU8sQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUMsMkJBQTJCO2lCQUN4RCxJQUFJLEVBQUUsQ0FBQztZQUVWLE9BQU8sU0FBUyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDcEMsQ0FBQztRQUVELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxTQUFTLENBQUMsTUFBZSxFQUFFLFFBQVEsR0FBRyxDQUFDO1FBQ3JDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssSUFBSSxDQUFDO1FBQ2xFLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hGLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztRQUNsQywwREFBMEQ7UUFDMUQsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdkIsQ0FBQztRQUNELE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVELFlBQVksQ0FBQyxNQUFlLEVBQUUsT0FBZ0I7UUFDNUMseURBQXlEO1FBQ3pELElBQUksTUFBTSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsSUFBSSxTQUFTLElBQUksTUFBTSxFQUFFLENBQUM7WUFDaEUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUIsQ0FBQzthQUFNLENBQUM7WUFDTixxQkFBcUI7WUFDckIsTUFBTSxPQUFPLEdBQUc7Z0JBQ2QsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsT0FBTyxFQUFFLE9BQU8sSUFBSyxNQUErQixFQUFFLE9BQU8sSUFBSSxTQUFTO2dCQUMxRSxJQUFJLEVBQUUsTUFBTTthQUNiLENBQUM7WUFDRixJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3QixDQUFDO0lBQ0gsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFjLEVBQUUsSUFBYTtRQUN0QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0MsTUFBTSxPQUFPLEdBQUcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxJQUFJLFNBQVMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFXLENBQUM7UUFDL0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELGVBQWUsQ0FBQyxPQUFlLEVBQUUsT0FBZTtRQUM5QyxNQUFNLE9BQU8sR0FBRztZQUNkLE9BQU8sRUFBRSxLQUFLO1lBQ2QsT0FBTztZQUNQLE1BQU0sRUFBRSxPQUFPO1lBQ2YsS0FBSyxFQUFFLGdCQUFnQixPQUFPLCtCQUErQjtTQUNyRCxDQUFDO1FBQ1gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0IsQ0FBQztDQUNGO0FBRUQsS0FBSyxVQUFVLElBQUk7SUFDakIsTUFBTSxNQUFNLEdBQUcsbUNBQVMsRUFBRSxDQUFDO0lBQzNCLE1BQU0sT0FBTyxHQUFHLElBQUksMENBQU8sRUFBRSxDQUFDO0lBQzlCLE1BQU0sS0FBSyxHQUFHLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXBDLE9BQU87U0FDSixJQUFJLENBQUMsU0FBUyxDQUFDO1NBQ2YsV0FBVyxDQUFDLGtDQUFrQyxDQUFDO1NBQy9DLE1BQU0sQ0FBQyxXQUFXLEVBQUUsZ0RBQWdELENBQUM7U0FDckUsa0JBQWtCLEVBQUUsQ0FBQztJQUV4QixPQUFPO1NBQ0osT0FBTyxDQUFDLE9BQU8sQ0FBQztTQUNoQixXQUFXLENBQUMsNkRBQTZELENBQUM7U0FDMUUsTUFBTSxDQUFDLHlCQUF5QixFQUFFLDBCQUEwQixFQUFFLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQztTQUMvRixNQUFNLENBQUMsS0FBSyxFQUFFLElBQTBCLEVBQUUsRUFBRTtRQUMzQyxNQUFNLFdBQVcsR0FBRyxTQUFTLENBQUM7UUFDOUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDO1FBQzNGLE1BQU0sV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sV0FBVyxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDaEUsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUwsT0FBTztTQUNKLE9BQU8sQ0FBQyxRQUFRLENBQUM7U0FDakIsV0FBVyxDQUFDLGlEQUFpRCxDQUFDO1NBQzlELE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRTtRQUNqQixNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMxQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCxPQUFPO1NBQ0osT0FBTyxDQUFDLFFBQVEsQ0FBQztTQUNqQixXQUFXLENBQUMsd0NBQXdDLENBQUM7U0FDckQsTUFBTSxDQUFDLEtBQUssSUFBSSxFQUFFO1FBQ2pCLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQztRQUM5QixNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDMUQsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUwsT0FBTztTQUNKLE9BQU8sQ0FBQyxTQUFTLENBQUM7U0FDbEIsV0FBVyxDQUFDLDRFQUE0RSxDQUFDO1NBQ3pGLE1BQU0sQ0FBQyxhQUFhLEVBQUUsMERBQTBELENBQUM7U0FDakYsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUE0QixFQUFFLEVBQUU7UUFDN0MsS0FBSyxVQUFVLGlCQUFpQjtZQUM5QixJQUFJLENBQUM7Z0JBQ0gsMkNBQTJDO2dCQUMzQyxNQUFNLGNBQWMsR0FBRywyQ0FBd0IsRUFBRSxDQUFDO2dCQUVsRCxNQUFNLE9BQU8sR0FBRyxNQUFNLG1DQUFnQixDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQzNELE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUV0QixPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsQ0FBQztZQUM3QyxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDOUIsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRyxNQUFNLGlCQUFpQixFQUFFLENBQUM7UUFDOUMsSUFBSSxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDMUIsS0FBSyxDQUFDLFlBQVksQ0FDaEI7Z0JBQ0UsU0FBUyxFQUFFLElBQUk7Z0JBQ2YsY0FBYyxFQUFFLFdBQVcsQ0FBQyxjQUFjO2FBQzNDLEVBQ0QsbUJBQW1CLENBQ3BCLENBQUM7WUFDRixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLENBQUMsV0FBVyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDNUQsSUFBSSxJQUFJLENBQUMsUUFBUTtZQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDNUMsTUFBTSxNQUFNLEdBQUcseURBQVMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFFOUUsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLGlCQUFpQixFQUFFLENBQUM7UUFDbkQsSUFBSSxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUMvQixLQUFLLENBQUMsWUFBWSxDQUNoQjtnQkFDRSxTQUFTLEVBQUUsSUFBSTtnQkFDZixjQUFjLEVBQUUsZ0JBQWdCLENBQUMsY0FBYztnQkFDL0MsUUFBUSxFQUFFLE1BQU0sQ0FBQyxNQUFNLElBQUksSUFBSTthQUNoQyxFQUNELDhCQUE4QixDQUMvQixDQUFDO1FBQ0osQ0FBQzthQUFNLENBQUM7WUFDTixLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxDQUFDLHNDQUFzQyxDQUFDLENBQUMsQ0FBQztRQUN0RSxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCxrQkFBa0I7SUFDbEIsT0FBTztTQUNKLE9BQU8sQ0FBQyxPQUFPLENBQUM7U0FDaEIsV0FBVyxDQUFDLDBCQUEwQixDQUFDO1NBQ3ZDLE1BQU0sQ0FBQywyQkFBMkIsRUFBRSw0QkFBNEIsQ0FBQztTQUNqRSxNQUFNLENBQUMsS0FBSyxFQUFFLElBQThCLEVBQUUsRUFBRTtRQUMvQyxNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQy9ELEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVMLHFCQUFxQjtJQUNyQixPQUFPO1NBQ0osT0FBTyxDQUFDLFFBQVEsQ0FBQztTQUNqQixXQUFXLENBQUMseUJBQXlCLENBQUM7U0FDdEMsY0FBYyxDQUFDLHlCQUF5QixFQUFFLGdCQUFnQixDQUFDO1NBQzNELE1BQU0sQ0FBQywyQkFBMkIsRUFBRSw0QkFBNEIsQ0FBQztTQUNqRSxNQUFNLENBQUMsS0FBSyxFQUFFLElBQStDLEVBQUUsRUFBRTtRQUNoRSxNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDN0UsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUwsK0NBQStDO0lBQy9DLE1BQU0sZUFBZSxHQUFHLE9BQU87U0FDNUIsT0FBTyxDQUFDLFVBQVUsQ0FBQztTQUNuQixXQUFXLENBQUMsMkNBQTJDLENBQUMsQ0FBQztJQUU1RCw0QkFBNEI7SUFDNUIsZUFBZTtTQUNaLE9BQU8sQ0FBQyxNQUFNLENBQUM7U0FDZixXQUFXLENBQUMscUNBQXFDLENBQUM7U0FDbEQsTUFBTSxDQUFDLHNCQUFzQixFQUFFLHFDQUFxQyxFQUFFLElBQUksQ0FBQztTQUMzRSxNQUFNLENBQUMsdUJBQXVCLEVBQUUsaUNBQWlDLENBQUM7U0FDbEUsTUFBTSxDQUFDLDJCQUEyQixFQUFFLDRCQUE0QixDQUFDO1NBQ2pFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBOEQsRUFBRSxFQUFFO1FBQy9FLE1BQU0sV0FBVyxHQUFHLElBQUksd0JBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUM7WUFDSCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN6QyxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3BGLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVMLDhCQUE4QjtJQUM5QixlQUFlO1NBQ1osT0FBTyxDQUFDLFFBQVEsQ0FBQztTQUNqQixXQUFXLENBQUMsbUJBQW1CLENBQUM7U0FDaEMsTUFBTSxDQUFDLGdCQUFnQixFQUFFLDRCQUE0QixDQUFDO1NBQ3RELE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxnQ0FBZ0MsQ0FBQztTQUM1RCxNQUFNLENBQUMsMkJBQTJCLEVBQUUsNEJBQTRCLENBQUM7U0FDakUsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUF3RSxFQUFFLEVBQUU7UUFDekYsTUFBTSxXQUFXLEdBQUcsSUFBSSx3QkFBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN2QixNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQzNFLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDN0IsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdkIsTUFBTSxNQUFNLEdBQUcsTUFBTSxXQUFXLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUMzRSxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzdCLENBQUM7aUJBQU0sQ0FBQztnQkFDTiw2REFBNkQ7Z0JBQzdELE9BQU8sQ0FBQyxHQUFHLENBQUMsNENBQTRDLENBQUMsQ0FBQztnQkFDMUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO2dCQUNuQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUN4QixPQUFPLENBQUMsR0FBRyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7Z0JBQ3ZFLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkRBQTZELENBQUMsQ0FBQztnQkFDM0UsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5REFBeUQsQ0FBQyxDQUFDO2dCQUN2RSxPQUFPLENBQUMsR0FBRyxDQUFDLHVEQUF1RCxDQUFDLENBQUM7Z0JBQ3JFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEIsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCx5QkFBeUI7SUFDekIsT0FBTztTQUNKLE9BQU8sQ0FBQyxTQUFTLENBQUM7U0FDbEIsV0FBVyxDQUFDLG1CQUFtQixDQUFDO1NBQ2hDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFBRSxTQUFTLENBQUM7U0FDM0MsY0FBYyxDQUFDLHNCQUFzQixFQUFFLDZCQUE2QixDQUFDO1NBQ3JFLGNBQWMsQ0FBQyxtQkFBbUIsRUFBRSxpQkFBaUIsQ0FBQztTQUN0RCxNQUFNLENBQUMsMkJBQTJCLEVBQUUsNEJBQTRCLENBQUM7U0FDakUsTUFBTSxDQUNMLEtBQUssRUFBRSxJQUErRSxFQUFFLEVBQUU7UUFDeEYsTUFBTSxXQUFXLEdBQUcsSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxXQUFXLENBQUMsYUFBYSxDQUM1QyxJQUFJLENBQUMsTUFBTSxFQUNYLElBQUksQ0FBQyxTQUFTLEVBQ2QsSUFBSSxDQUFDLElBQUksRUFDVCxJQUFJLENBQUMsV0FBVyxDQUNqQixDQUFDO1lBQ0YsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FDRixDQUFDO0lBRUosc0NBQXNDO0lBQ3RDLE9BQU87U0FDSixPQUFPLENBQUMsU0FBUyxDQUFDO1NBQ2xCLFdBQVcsQ0FBQyxrRUFBa0UsQ0FBQztTQUMvRSxjQUFjLENBQUMsbUJBQW1CLEVBQUUsc0RBQXNELENBQUM7U0FDM0YsY0FBYyxDQUFDLGlCQUFpQixFQUFFLDZCQUE2QixDQUFDO1NBQ2hFLGNBQWMsQ0FBQyxxQkFBcUIsRUFBRSxxQ0FBcUMsQ0FBQztTQUM1RSxjQUFjLENBQ2IscUJBQXFCLEVBQ3JCLDRGQUE0RixDQUM3RjtTQUNBLE1BQU0sQ0FBQyxlQUFlLEVBQUUsc0JBQXNCLENBQUM7U0FDL0MsTUFBTSxDQUFDLDJCQUEyQixFQUFFLDRCQUE0QixDQUFDO1NBQ2pFLE1BQU0sQ0FDTCxLQUFLLEVBQUUsSUFPTixFQUFFLEVBQUU7UUFDSCxNQUFNLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUM7WUFDSCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7Z0JBQ25ELEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQyxDQUFDO2dCQUMvRCxPQUFPO1lBQ1QsQ0FBQztZQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLO2lCQUMxQixLQUFLLENBQUMsR0FBRyxDQUFDO2lCQUNWLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2lCQUNwQixNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbkIsTUFBTSxNQUFNLEdBQUcsTUFBTSxjQUFjLENBQUMsY0FBYyxDQUNoRCxJQUFJLENBQUMsSUFBSSxFQUNULElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLE9BQU8sRUFDWixVQUFVLEVBQ1YsSUFBSSxDQUFDLElBQUksRUFDVCxJQUFJLENBQUMsV0FBVyxDQUNqQixDQUFDO1lBQ0YsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUMsQ0FDRixDQUFDO0lBRUosT0FBTztTQUNKLE9BQU8sQ0FBQyxLQUFLLENBQUM7U0FDZCxXQUFXLENBQUMsMkNBQTJDLENBQUM7U0FDeEQsTUFBTSxDQUFDLG1CQUFtQixFQUFFLDRCQUE0QixFQUFFLE9BQU8sQ0FBQztTQUNsRSxNQUFNLENBQUMsbUJBQW1CLEVBQUUsdUNBQXVDLEVBQUUsTUFBTSxDQUFDO1NBQzVFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBc0MsRUFBRSxFQUFFO1FBQ3ZELElBQUksQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztnQkFDekIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztnQkFDeEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDOUMsTUFBTSxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDM0IsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLDJGQUEyRjtnQkFDM0Ysb0RBQW9EO2dCQUNwRCxNQUFNLE1BQU0sR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUNsQyxNQUFNLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixzREFBc0Q7WUFDdEQsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixLQUFLLE1BQU0sRUFBRSxDQUFDO2dCQUM5QyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsS0FBSyxJQUFJLENBQUMsQ0FBQztZQUM3RCxDQUFDO1lBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCxpQkFBaUI7SUFDakIsT0FBTztTQUNKLE9BQU8sQ0FBQyxPQUFPLENBQUM7U0FDaEIsV0FBVyxDQUFDLDBCQUEwQixDQUFDO1NBQ3ZDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsdUJBQXVCLENBQUM7U0FDN0MsTUFBTSxDQUFDLGdCQUFnQixFQUFFLGdDQUFnQyxDQUFDO1NBQzFELE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBNEMsRUFBRSxFQUFFO1FBQzdELElBQUksQ0FBQztZQUNILE1BQU0sV0FBVyxHQUFHLGdCQUFnQixDQUFDO1lBRXJDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNkLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUNsQixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFDM0MsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO3dCQUNmLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztxQkFDOUIsQ0FBQyxDQUFDLENBQUM7b0JBQ0osT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEQsQ0FBQztZQUNILENBQUM7aUJBQU0sQ0FBQztnQkFDTixPQUFPLENBQUMsR0FBRyxDQUFDLDZCQUE2QixDQUFDLENBQUM7Z0JBRTNDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7b0JBQ2xDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUMxQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7b0JBRXRDLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO3dCQUNsQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7d0JBQ2pELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQzt3QkFFckQsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQzs0QkFDdkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDOzRCQUM5QixNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBb0IsRUFBRSxFQUFFO2dDQUNwRSxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQztnQ0FDNUUsTUFBTSxRQUFRLEdBQUksSUFBaUMsQ0FBQyxXQUFXLENBQUM7Z0NBQ2hFLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxHQUFHLEtBQUssUUFBUSxJQUFJLGdCQUFnQixHQUFHLFlBQVksRUFBRSxDQUFDLENBQUM7NEJBQy9FLENBQUMsQ0FBQyxDQUFDO3dCQUNMLENBQUM7b0JBQ0gsQ0FBQztvQkFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNsQixDQUFDLENBQUMsQ0FBQztnQkFFSCxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsV0FBVyxDQUFDLE1BQU0sa0JBQWtCLENBQUMsQ0FBQztnQkFDNUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO2dCQUMxRCxPQUFPLENBQUMsR0FBRyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7WUFDeEQsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFTCxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBRUQsK0NBQStDO0FBQy9DLE9BQU8sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRTtJQUN4QiwyRUFBMkU7SUFDM0UsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixDQUFDLENBQUMsQ0FBQztBQUVILE9BQU8sQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtJQUN6QiwyRUFBMkU7SUFDM0UsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixDQUFDLENBQUMsQ0FBQztBQUVILGdCQUFnQjtBQUNoQixJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtJQUNyQixzREFBc0Q7SUFDdEQsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQzlDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixLQUFLLElBQUksQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBjb21tb25qczIgXCJjb21tYW5kZXJcIj9jNDQ4Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL3hocy51dGlscy50cz9iMjVlIiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9hdXRoL2F1dGguc2VydmljZS50cz82OWZlIiwid2VicGFjazovL3hocy1tY3AvZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiPzk4NWQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL2ZlZWRzL2ZlZWQuc2VydmljZS50cz82NGI3Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2hhcmVkL3RpdGxlLXZhbGlkYXRvci50cz8yNDM5Iiwid2VicGFjazovL3hocy1tY3AvZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImNyeXB0b1wiP2E4YjIiLCJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBjb21tb25qczIgXCJub2RlLWZldGNoXCI/MzZlNSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NoYXJlZC9pbWFnZS1kb3dubG9hZGVyLnRzPzUzNTYiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9jb3JlL3B1Ymxpc2hpbmcvcHVibGlzaC1iYXNlLnNlcnZpY2UudHM/Njc4YyIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvcHVibGlzaGluZy9wdWJsaXNoLWltYWdlLnNlcnZpY2UudHM/ZDVmNCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvcHVibGlzaGluZy9wdWJsaXNoLXZpZGVvLnNlcnZpY2UudHM/NTQwNiIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvcHVibGlzaGluZy9wdWJsaXNoLnNlcnZpY2UudHM/MTdlOSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9oYW5kbGVycy90b29sLmhhbmRsZXJzLnRzPzdmNzQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvaW5kZXgudHM/ODQ1ZSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9oYW5kbGVycy9yZXNvdXJjZS5oYW5kbGVycy50cz9hYTM5Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2VydmVyL3NjaGVtYXMvdG9vbC5zY2hlbWFzLnRzP2RmOGYiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zZXJ2ZXIvbWNwLnNlcnZlci50cz8zMzk0Iiwid2VicGFjazovL3hocy1tY3AvZXh0ZXJuYWwgY29tbW9uanMyIFwiZXhwcmVzc1wiPzVlM2EiLCJ3ZWJwYWNrOi8veGhzLW1jcC9leHRlcm5hbCBjb21tb25qczIgXCJjb3JzXCI/OWM3ZCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL3NlcnZlci9odHRwLnNlcnZlci50cz84Y2Q0Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvc2VydmVyL2hhbmRsZXJzL2luZGV4LnRzPzFlOTQiLCJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zZXJ2ZXIvaW5kZXgudHM/NWVlNiIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NsaS9jbGkudHM/Y2I5ZCJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBfX1dFQlBBQ0tfTkFNRVNQQUNFX09CSkVDVF9fID0gcmVxdWlyZShcImNvbW1hbmRlclwiKTsiLCIvKipcbiAqIFV0aWxpdHkgZnVuY3Rpb25zIGZvciBYSFMgb3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCB7IFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuXG5leHBvcnQgY29uc3QgWEhTX0hPTUVfVVJMID0gJ2h0dHBzOi8vd3d3LnhpYW9ob25nc2h1LmNvbSc7XG5leHBvcnQgY29uc3QgWEhTX0VYUExPUkVfVVJMID0gYCR7WEhTX0hPTUVfVVJMfS9leHBsb3JlYDtcbmV4cG9ydCBjb25zdCBYSFNfU0VBUkNIX1VSTCA9IGAke1hIU19IT01FX1VSTH0vc2VhcmNoX3Jlc3VsdGA7XG5leHBvcnQgY29uc3QgWEhTX0NSRUFUT1JfUFVCTElTSF9VUkwgPVxuICAnaHR0cHM6Ly9jcmVhdG9yLnhpYW9ob25nc2h1LmNvbS9wdWJsaXNoL3B1Ymxpc2g/c291cmNlPW9mZmljaWFsJztcbmV4cG9ydCBjb25zdCBMT0dJTl9PS19TRUxFQ1RPUiA9ICcubWFpbi1jb250YWluZXIgLnVzZXIgLmxpbmstd3JhcHBlciAuY2hhbm5lbCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlU2VhcmNoVXJsKGtleXdvcmQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgIGtleXdvcmQsXG4gICAgc291cmNlOiAnd2ViX2V4cGxvcmVfZmVlZCcsXG4gIH0pO1xuICByZXR1cm4gYCR7WEhTX1NFQVJDSF9VUkx9PyR7cGFyYW1zLnRvU3RyaW5nKCl9YDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1ha2VGZWVkRGV0YWlsVXJsKGZlZWRJZDogc3RyaW5nLCB4c2VjVG9rZW46IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoe1xuICAgIHhzZWNfdG9rZW46IHhzZWNUb2tlbixcbiAgICB4c2VjX3NvdXJjZTogJ3BjX2ZlZWQnLFxuICB9KTtcbiAgcmV0dXJuIGAke1hIU19FWFBMT1JFX1VSTH0vJHtmZWVkSWR9PyR7cGFyYW1zLnRvU3RyaW5nKCl9YDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RJbml0aWFsU3RhdGUocGFnZTogUGFnZSk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsPiB7XG4gIHRyeSB7XG4gICAgLy8gV2FpdCBmb3IgcGFnZSB0byBiZSBmdWxseSBsb2FkZWQgLSBQdXBwZXRlZXIgZG9lc24ndCBoYXZlIHdhaXRGb3JMb2FkU3RhdGVcbiAgICAvLyBXZSdsbCBqdXN0IHdhaXQgYSBiaXQgZm9yIHRoZSBwYWdlIHRvIHNldHRsZVxuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiBnbG9iYWxUaGlzLnNldFRpbWVvdXQocmVzb2x2ZSwgMTAwMCkpO1xuICB9IGNhdGNoIHtcbiAgICAvLyBJZ25vcmUgbG9hZCBzdGF0ZSBlcnJvcnNcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZShgXG4gICAgICAoKCkgPT4ge1xuICAgICAgICAvLyBUcnkgbXVsdGlwbGUgcG9zc2libGUgc3RhdGUgb2JqZWN0c1xuICAgICAgICBjb25zdCBwb3NzaWJsZVN0YXRlcyA9IFtcbiAgICAgICAgICB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18sXG4gICAgICAgICAgd2luZG93Ll9fSU5JVElBTF9TU1JfU1RBVEVfXyxcbiAgICAgICAgICB3aW5kb3cuX19ORVhUX0RBVEFfXyxcbiAgICAgICAgICB3aW5kb3cuX19OVVhUX18sXG4gICAgICAgICAgd2luZG93Ll9fVlVFX18sXG4gICAgICAgICAgd2luZG93Ll9fUkVBQ1RfUVVFUllfU1RBVEVfX1xuICAgICAgICBdO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc3RhdGUgb2YgcG9zc2libGVTdGF0ZXMpIHtcbiAgICAgICAgICBpZiAoc3RhdGUgJiYgdHlwZW9mIHN0YXRlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgLy8gVXNlIGEgbW9yZSByb2J1c3QgSlNPTiBzZXJpYWxpemF0aW9uIHRoYXQgaGFuZGxlcyBjaXJjdWxhciByZWZlcmVuY2VzXG4gICAgICAgICAgICAgIGNvbnN0IHNlZW4gPSBuZXcgV2Vha1NldCgpO1xuICAgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc3RhdGUsIChrZXksIHZhbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWwgIT0gbnVsbCAmJiB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICBpZiAoc2Vlbi5oYXModmFsKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJbQ2lyY3VsYXJdXCI7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBzZWVuLmFkZCh2YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0pTT04uc3RyaW5naWZ5IGZhaWxlZCBmb3Igc3RhdGU6JywgZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgbm8gc3RhdGUgZm91bmQsIHRyeSB0byBmaW5kIGFueSBnbG9iYWwgc3RhdGVcbiAgICAgICAgY29uc3QgZ2xvYmFsS2V5cyA9IE9iamVjdC5rZXlzKHdpbmRvdykuZmlsdGVyKGtleSA9PlxuICAgICAgICAgIGtleS5pbmNsdWRlcygnU1RBVEUnKSB8fCBrZXkuaW5jbHVkZXMoJ0RBVEEnKSB8fCBrZXkuaW5jbHVkZXMoJ0lOSVRJQUwnKVxuICAgICAgICApO1xuXG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGdsb2JhbEtleXMpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHdpbmRvd1trZXldO1xuICAgICAgICAgIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCBzZWVuID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlLCAoa2V5LCB2YWwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodmFsICE9IG51bGwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgICAgaWYgKHNlZW4uaGFzKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiW0NpcmN1bGFyXVwiO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgc2Vlbi5hZGQodmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdKU09OLnN0cmluZ2lmeSBmYWlsZWQgZm9yIGdsb2JhbCBrZXk6Jywga2V5LCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9KSgpXG4gICAgYCk7XG5cbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVzdWx0IGFzIHN0cmluZyk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpc0xvZ2dlZEluKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBlbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoTE9HSU5fT0tfU0VMRUNUT1IpO1xuICAgIHJldHVybiBlbGVtZW50cy5sZW5ndGggPiAwO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldExvZ2luU3RhdHVzV2l0aFByb2ZpbGUocGFnZTogUGFnZSk6IFByb21pc2U8e1xuICBpc0xvZ2dlZEluOiBib29sZWFuO1xuICBwcm9maWxlPzoge1xuICAgIHVzZXJJZD86IHN0cmluZztcbiAgICBuaWNrbmFtZT86IHN0cmluZztcbiAgICB1c2VybmFtZT86IHN0cmluZztcbiAgICBhdmF0YXI/OiBzdHJpbmc7XG4gICAgZm9sbG93ZXJzPzogbnVtYmVyO1xuICAgIGZvbGxvd2luZz86IG51bWJlcjtcbiAgICBsaWtlcz86IG51bWJlcjtcbiAgICB4aHNOdW1iZXI/OiBzdHJpbmc7XG4gICAgaXBMb2NhdGlvbj86IHN0cmluZztcbiAgICBwcm9maWxlVXJsPzogc3RyaW5nO1xuICB9O1xufT4ge1xuICB0cnkge1xuICAgIC8vIEZpcnN0IGNoZWNrIGlmIGxvZ2dlZCBpbiB1c2luZyB0aGUgZXhpc3RpbmcgbWV0aG9kXG4gICAgY29uc3QgZWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKExPR0lOX09LX1NFTEVDVE9SKTtcbiAgICBjb25zdCBpc0xvZ2dlZEluID0gZWxlbWVudHMubGVuZ3RoID4gMDtcblxuICAgIGlmICghaXNMb2dnZWRJbikge1xuICAgICAgcmV0dXJuIHsgaXNMb2dnZWRJbjogZmFsc2UgfTtcbiAgICB9XG5cbiAgICAvLyBJZiBsb2dnZWQgaW4sIHRyeSB0byBleHRyYWN0IHByb2ZpbGUgaW5mb3JtYXRpb24gZnJvbSBjdXJyZW50IHBhZ2VcbiAgICBsZXQgcHJvZmlsZURhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgdHJ5IHtcbiAgICAgIHByb2ZpbGVEYXRhID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByb2ZpbGU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgICAgICAgLy8gRXh0cmFjdCB1c2VyIElEIGZyb20gVVJMIGlmIG9uIHByb2ZpbGUgcGFnZVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgY29uc3QgdXJsTWF0Y2ggPSB3aW5kb3cubG9jYXRpb24uaHJlZi5tYXRjaCgvXFwvdXNlclxcL3Byb2ZpbGVcXC8oW2EtZjAtOV0rKS8pO1xuICAgICAgICBpZiAodXJsTWF0Y2gpIHtcbiAgICAgICAgICBwcm9maWxlLnVzZXJJZCA9IHVybE1hdGNoWzFdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHJ5IHRvIGZpbmQgdXNlciBuaWNrbmFtZVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgICAgY29uc3QgbmFtZUVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICcudXNlci1uYW1lLCBbY2xhc3MqPVwidXNlci1uYW1lXCJdLCBbY2xhc3MqPVwibmlja25hbWVcIl0nXG4gICAgICAgICk7XG4gICAgICAgIGlmIChuYW1lRWxlbWVudCkge1xuICAgICAgICAgIHByb2ZpbGUubmlja25hbWUgPSBuYW1lRWxlbWVudC50ZXh0Q29udGVudD8udHJpbSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHJ5IHRvIGZpbmQgdXNlciBpbmZvIHRleHQgdGhhdCBtaWdodCBjb250YWluIHN0YXRzXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgICAgICBjb25zdCBpbmZvRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy51c2VyLWluZm8sIFtjbGFzcyo9XCJ1c2VyLWluZm9cIl0nKTtcbiAgICAgICAgaWYgKGluZm9FbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgaW5mb1RleHQgPSBpbmZvRWxlbWVudC50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgICBwcm9maWxlLmluZm9UZXh0ID0gaW5mb1RleHQ7XG5cbiAgICAgICAgICAvLyBUcnkgdG8gZXh0cmFjdCBudW1iZXJzIGZyb20gdGhlIGluZm8gdGV4dCAoZm9sbG93ZXJzLCBmb2xsb3dpbmcsIGxpa2VzKVxuICAgICAgICAgIGNvbnN0IG51bWJlcnMgPSBpbmZvVGV4dC5tYXRjaCgvXFxkKy9nKTtcbiAgICAgICAgICBpZiAobnVtYmVycyAmJiBudW1iZXJzLmxlbmd0aCA+PSAzKSB7XG4gICAgICAgICAgICAvLyBDb21tb24gcGF0dGVybjogZm9sbG93ZXJzLCBmb2xsb3dpbmcsIGxpa2VzXG4gICAgICAgICAgICBwcm9maWxlLmZvbGxvd2luZyA9IHBhcnNlSW50KG51bWJlcnNbMF0pIHx8IDA7XG4gICAgICAgICAgICBwcm9maWxlLmZvbGxvd2VycyA9IHBhcnNlSW50KG51bWJlcnNbMV0pIHx8IDA7XG4gICAgICAgICAgICBwcm9maWxlLmxpa2VzID0gcGFyc2VJbnQobnVtYmVyc1syXSkgfHwgMDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBFeHRyYWN0IOWwj+e6ouS5puWPtyAoWEhTIG51bWJlcilcbiAgICAgICAgICBjb25zdCB4aHNNYXRjaCA9IGluZm9UZXh0Lm1hdGNoKC/lsI/nuqLkuablj7fvvJooXFxkKykvKTtcbiAgICAgICAgICBpZiAoeGhzTWF0Y2gpIHtcbiAgICAgICAgICAgIHByb2ZpbGUueGhzTnVtYmVyID0geGhzTWF0Y2hbMV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gRXh0cmFjdCBJUOWxnuWcsCAoSVAgbG9jYXRpb24pXG4gICAgICAgICAgY29uc3QgaXBNYXRjaCA9IGluZm9UZXh0Lm1hdGNoKC9JUOWxnuWcsO+8mihbXjAtOV0rKS8pO1xuICAgICAgICAgIGlmIChpcE1hdGNoKSB7XG4gICAgICAgICAgICBwcm9maWxlLmlwTG9jYXRpb24gPSBpcE1hdGNoWzFdLnRyaW0oKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUcnkgdG8gZmluZCBhdmF0YXJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgIGNvbnN0IGF2YXRhckVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICdpbWdbY2xhc3MqPVwiYXZhdGFyXCJdLCBpbWdbY2xhc3MqPVwicHJvZmlsZVwiXSwgLmF2YXRhciBpbWcsIC5wcm9maWxlIGltZydcbiAgICAgICAgKSBhcyBIVE1MSW1hZ2VFbGVtZW50O1xuICAgICAgICBpZiAoYXZhdGFyRWxlbWVudCkge1xuICAgICAgICAgIHByb2ZpbGUuYXZhdGFyID0gYXZhdGFyRWxlbWVudC5zcmM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcHJvZmlsZTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBpbiBwYWdlLmV2YWx1YXRlJyk7XG4gICAgICBwcm9maWxlRGF0YSA9IHt9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBpc0xvZ2dlZEluOiB0cnVlLFxuICAgICAgcHJvZmlsZTogT2JqZWN0LmtleXMocHJvZmlsZURhdGEpLmxlbmd0aCA+IDAgPyBwcm9maWxlRGF0YSA6IHVuZGVmaW5lZCxcbiAgICB9O1xuICB9IGNhdGNoIHtcbiAgICAvLyBJZiB0aGVyZSdzIGFuIGVycm9yLCBmYWxsIGJhY2sgdG8gYmFzaWMgbG9naW4gY2hlY2tcbiAgICB0cnkge1xuICAgICAgY29uc3QgZWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKExPR0lOX09LX1NFTEVDVE9SKTtcbiAgICAgIHJldHVybiB7IGlzTG9nZ2VkSW46IGVsZW1lbnRzLmxlbmd0aCA+IDAgfTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB7IGlzTG9nZ2VkSW46IGZhbHNlIH07XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIEF1dGhlbnRpY2F0aW9uIHNlcnZpY2UgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHsgQ29uZmlnLCBMb2dpblJlc3VsdCwgU3RhdHVzUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7XG4gIExvZ2luVGltZW91dEVycm9yLFxuICBMb2dpbkZhaWxlZEVycm9yLFxuICBYSFNFcnJvcixcbn0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBCYXNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQnJvd3Nlck1hbmFnZXIgfSBmcm9tICcuLi9icm93c2VyL2Jyb3dzZXIubWFuYWdlcic7XG5pbXBvcnQgeyBkZWxldGVDb29raWVzRmlsZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9jb29raWVzJztcbmltcG9ydCB7IGlzTG9nZ2VkSW4sIGdldExvZ2luU3RhdHVzV2l0aFByb2ZpbGUgfSBmcm9tICcuLi8uLi9zaGFyZWQveGhzLnV0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5cbmV4cG9ydCBjbGFzcyBBdXRoU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcsIGJyb3dzZXJNYW5hZ2VyPzogQnJvd3Nlck1hbmFnZXIpIHtcbiAgICBzdXBlcihjb25maWcsIGJyb3dzZXJNYW5hZ2VyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0IHByb2ZpbGUgVVJMIGFuZCB1c2VyIElEIGZyb20gdGhlIGN1cnJlbnQgcGFnZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleHRyYWN0UHJvZmlsZUZyb21QYWdlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcHJvZmlsZVVybCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICBjb25zdCB1c2VyTGlua3MgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZio9XCIvdXNlci9wcm9maWxlL1wiXScpKTtcbiAgICAgICAgY29uc3QgY3VycmVudFVzZXJMaW5rID0gdXNlckxpbmtzLmZpbmQoKGxpbmspID0+IHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gbGluay50ZXh0Q29udGVudD8udHJpbSgpO1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0ZXh0ID09PSAn5oiRJyB8fFxuICAgICAgICAgICAgKHRleHQgJiYgdGV4dC5pbmNsdWRlcygncHJvZmlsZScpKSB8fFxuICAgICAgICAgICAgKHRleHQgJiYgdGV4dC5pbmNsdWRlcygn55So5oi3JykpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjdXJyZW50VXNlckxpbmsgPyAoY3VycmVudFVzZXJMaW5rIGFzIEhUTUxBbmNob3JFbGVtZW50KS5ocmVmIDogbnVsbDtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocHJvZmlsZVVybCkge1xuICAgICAgICBjb25zdCB1c2VySWRNYXRjaCA9IHByb2ZpbGVVcmwubWF0Y2goL1xcL3VzZXJcXC9wcm9maWxlXFwvKFthLWYwLTldKykvKTtcbiAgICAgICAgaWYgKHVzZXJJZE1hdGNoKSB7XG4gICAgICAgICAgcmV0dXJuIHsgdXNlcklkOiB1c2VySWRNYXRjaFsxXSwgcHJvZmlsZVVybCB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAocHJvZmlsZUVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIGdldCBwcm9maWxlIGluZm9ybWF0aW9uOicsIHByb2ZpbGVFcnJvcik7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBhc3luYyBsb2dpbihicm93c2VyUGF0aD86IHN0cmluZywgdGltZW91dDogbnVtYmVyID0gMzAwKTogUHJvbWlzZTxMb2dpblJlc3VsdD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UoZmFsc2UsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gTmF2aWdhdGUgdG8gZXhwbG9yZSBwYWdlXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShwYWdlLCB0aGlzLmdldENvbmZpZygpLnhocy5leHBsb3JlVXJsKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBhbHJlYWR5IGxvZ2dlZCBpblxuICAgICAgICBpZiAoYXdhaXQgaXNMb2dnZWRJbihwYWdlKSkge1xuICAgICAgICAgIGxldCBwcm9maWxlOiBhbnkgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGV4dHJhY3RlZCA9IGF3YWl0IHRoaXMuZXh0cmFjdFByb2ZpbGVGcm9tUGFnZShwYWdlKTtcbiAgICAgICAgICAgIGNvbnN0IGxvZ2luU3RhdHVzID0gYXdhaXQgZ2V0TG9naW5TdGF0dXNXaXRoUHJvZmlsZShwYWdlKTtcbiAgICAgICAgICAgIHByb2ZpbGUgPSB7IC4uLmV4dHJhY3RlZCwgLi4ubG9naW5TdGF0dXMucHJvZmlsZSB9O1xuICAgICAgICAgIH0gY2F0Y2ggKHByb2ZpbGVFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBnZXQgcHJvZmlsZSBpbmZvcm1hdGlvbjonLCBwcm9maWxlRXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0FscmVhZHkgbG9nZ2VkIGluJyxcbiAgICAgICAgICAgIHN0YXR1czogJ2xvZ2dlZF9pbicsXG4gICAgICAgICAgICBhY3Rpb246ICdub25lJyxcbiAgICAgICAgICAgIHByb2ZpbGUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdhaXQgZm9yIGxvZ2luIGNvbXBsZXRpb25cbiAgICAgICAgY29uc3QgY2hlY2tJbnRlcnZhbCA9IDU7XG4gICAgICAgIGNvbnN0IG1heENoZWNrcyA9IHRpbWVvdXQgLyBjaGVja0ludGVydmFsO1xuXG4gICAgICAgIGZvciAobGV0IGNoZWNrQ291bnQgPSAwOyBjaGVja0NvdW50IDwgbWF4Q2hlY2tzOyBjaGVja0NvdW50KyspIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yU2VsZWN0b3IodGhpcy5nZXRDb25maWcoKS54aHMubG9naW5Pa1NlbGVjdG9yLCB7XG4gICAgICAgICAgICAgIHRpbWVvdXQ6IGNoZWNrSW50ZXJ2YWwgKiAxMDAwLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc3QgZWxhcHNlZCA9IChjaGVja0NvdW50ICsgMSkgKiBjaGVja0ludGVydmFsO1xuXG4gICAgICAgICAgICBpZiAoY2hlY2tDb3VudCA9PT0gbWF4Q2hlY2tzIC0gMSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgTG9naW5UaW1lb3V0RXJyb3IoXG4gICAgICAgICAgICAgICAgYExvZ2luIHRpbWVkIG91dCBhZnRlciAke3RpbWVvdXR9IHNlY29uZHMuIFBsZWFzZSBjb21wbGV0ZSBRUiBjb2RlIHNjYW5uaW5nIG9yIG1hbnVhbCBsb2dpbiBpbiB0aGUgYnJvd3NlciB3aW5kb3cuYCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICB0aW1lb3V0LFxuICAgICAgICAgICAgICAgICAgdXJsOiB0aGlzLmdldENvbmZpZygpLnhocy5leHBsb3JlVXJsLFxuICAgICAgICAgICAgICAgICAgZWxhcHNlZFRpbWU6IGVsYXBzZWQsXG4gICAgICAgICAgICAgICAgICBzdWdnZXN0aW9uOiAnSW5jcmVhc2UgdGltZW91dCBwYXJhbWV0ZXIgb3IgY29tcGxldGUgbG9naW4gZmFzdGVyJyxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2F2ZSBjb29raWVzIGFmdGVyIHN1Y2Nlc3NmdWwgbG9naW5cbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLnNhdmVDb29raWVzRnJvbVBhZ2UocGFnZSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGxvZ2luIHN1Y2Nlc3MgYW5kIGdldCBwcm9maWxlIGluZm9ybWF0aW9uXG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuICAgICAgICBjb25zdCBsb2dpblN0YXR1cyA9IGF3YWl0IGdldExvZ2luU3RhdHVzV2l0aFByb2ZpbGUocGFnZSk7XG4gICAgICAgIGlmIChsb2dpblN0YXR1cy5pc0xvZ2dlZEluKSB7XG4gICAgICAgICAgbGV0IHByb2ZpbGUgPSBsb2dpblN0YXR1cy5wcm9maWxlO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBleHRyYWN0ZWQgPSBhd2FpdCB0aGlzLmV4dHJhY3RQcm9maWxlRnJvbVBhZ2UocGFnZSk7XG4gICAgICAgICAgICBpZiAoZXh0cmFjdGVkKSB7XG4gICAgICAgICAgICAgIHByb2ZpbGUgPSB7IC4uLnByb2ZpbGUsIC4uLmV4dHJhY3RlZCB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKHByb2ZpbGVFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBnZXQgYWRkaXRpb25hbCBwcm9maWxlIGluZm9ybWF0aW9uOicsIHByb2ZpbGVFcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiAnTG9naW4gc3VjY2Vzc2Z1bCcsXG4gICAgICAgICAgICBzdGF0dXM6ICdsb2dnZWRfaW4nLFxuICAgICAgICAgICAgYWN0aW9uOiAnbG9nZ2VkX2luJyxcbiAgICAgICAgICAgIHByb2ZpbGUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTG9naW5GYWlsZWRFcnJvcihcbiAgICAgICAgICAgICdMb2dpbiBwcm9jZXNzIGNvbXBsZXRlZCBidXQgYXV0aGVudGljYXRpb24gdmVyaWZpY2F0aW9uIGZhaWxlZCdcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIExvZ2luVGltZW91dEVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTG9naW5GYWlsZWRFcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgTG9naW4gZmFpbGVkIHdpdGggdW5leHBlY3RlZCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcihgTG9naW4gZmFpbGVkOiAke2Vycm9yfWAsICdMb2dpbkVycm9yJywgeyB0aW1lb3V0IH0sIGVycm9yIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBsb2dvdXQoKTogUHJvbWlzZTxMb2dpblJlc3VsdD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzdWNjZXNzID0gZGVsZXRlQ29va2llc0ZpbGUoKTtcblxuICAgICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdMb2dnZWQgb3V0IHN1Y2Nlc3NmdWxseSAoY29va2llcyBkZWxldGVkKScsXG4gICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX291dCcsXG4gICAgICAgICAgYWN0aW9uOiAnbG9nZ2VkX291dCcsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gZGVsZXRlIGNvb2tpZXMgZmlsZScsXG4gICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX291dCcsXG4gICAgICAgICAgYWN0aW9uOiAnbm9uZScsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgTG9nb3V0IGZhaWxlZDogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiBgTG9nb3V0IGZhaWxlZDogJHtlcnJvcn1gLFxuICAgICAgICBzdGF0dXM6ICdsb2dnZWRfb3V0JyxcbiAgICAgICAgYWN0aW9uOiAnbm9uZScsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNoZWNrU3RhdHVzKGJyb3dzZXJQYXRoPzogc3RyaW5nKTogUHJvbWlzZTxTdGF0dXNSZXN1bHQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmV4cGxvcmVVcmwpO1xuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgICBjb25zdCBsb2dnZWRJbiA9IGF3YWl0IGlzTG9nZ2VkSW4ocGFnZSk7XG5cbiAgICAgICAgaWYgKCFsb2dnZWRJbikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgbG9nZ2VkSW46IGZhbHNlLFxuICAgICAgICAgICAgc3RhdHVzOiAnbG9nZ2VkX291dCcsXG4gICAgICAgICAgICB1cmxDaGVja2VkOiB0aGlzLmdldENvbmZpZygpLnhocy5leHBsb3JlVXJsLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcm9maWxlID0gYXdhaXQgdGhpcy5leHRyYWN0UHJvZmlsZUZyb21QYWdlKHBhZ2UpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBsb2dnZWRJbjogdHJ1ZSxcbiAgICAgICAgICBzdGF0dXM6ICdsb2dnZWRfaW4nLFxuICAgICAgICAgIHVybENoZWNrZWQ6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmV4cGxvcmVVcmwsXG4gICAgICAgICAgcHJvZmlsZSxcbiAgICAgICAgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBTdGF0dXMgY2hlY2sgZmFpbGVkOiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKGBTdGF0dXMgY2hlY2sgZmFpbGVkOiAke2Vycm9yfWAsICdTdGF0dXNDaGVja0Vycm9yJywge30sIGVycm9yIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cbn1cbiIsImNvbnN0IF9fV0VCUEFDS19OQU1FU1BBQ0VfT0JKRUNUX18gPSByZXF1aXJlKFwibm9kZTpjaGlsZF9wcm9jZXNzXCIpOyIsIi8qKlxuICogRmVlZCBvcGVyYXRpb25zIHNlcnZpY2UgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHtcbiAgQ29uZmlnLFxuICBGZWVkTGlzdFJlc3VsdCxcbiAgU2VhcmNoUmVzdWx0LFxuICBGZWVkRGV0YWlsUmVzdWx0LFxuICBDb21tZW50UmVzdWx0LFxuICBGZWVkSXRlbSxcbn0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7XG4gIEZlZWRFcnJvcixcbiAgRmVlZFBhcnNpbmdFcnJvcixcbiAgRmVlZE5vdEZvdW5kRXJyb3IsXG4gIE5vdExvZ2dlZEluRXJyb3IsXG4gIFhIU0Vycm9yLFxufSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBCcm93c2VyTWFuYWdlciB9IGZyb20gJy4uL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyJztcbmltcG9ydCB7XG4gIG1ha2VTZWFyY2hVcmwsXG4gIG1ha2VGZWVkRGV0YWlsVXJsLFxuICBleHRyYWN0SW5pdGlhbFN0YXRlLFxuICBpc0xvZ2dlZEluLFxufSBmcm9tICcuLi8uLi9zaGFyZWQveGhzLnV0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgRmVlZFNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnLCBicm93c2VyTWFuYWdlcj86IEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgc3VwZXIoY29uZmlnLCBicm93c2VyTWFuYWdlcik7XG4gIH1cblxuICBhc3luYyBnZXRGZWVkTGlzdChicm93c2VyUGF0aD86IHN0cmluZyk6IFByb21pc2U8RmVlZExpc3RSZXN1bHQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmhvbWVVcmwpO1xuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBsb2dnZWQgaW5cbiAgICAgICAgaWYgKCEoYXdhaXQgaXNMb2dnZWRJbihwYWdlKSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm90TG9nZ2VkSW5FcnJvcignTXVzdCBiZSBsb2dnZWQgaW4gdG8gYWNjZXNzIGZlZWQgbGlzdCcsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogJ2dldF9mZWVkX2xpc3QnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRXh0cmFjdCBmZWVkIGRhdGEgdXNpbmcgYSBtb3JlIHRhcmdldGVkIGFwcHJvYWNoXG4gICAgICAgIGxldCBmZWVkRGF0YTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG4gICAgICAgIGNvbnN0IG1heEF0dGVtcHRzID0gMTA7XG5cbiAgICAgICAgd2hpbGUgKGF0dGVtcHRzIDwgbWF4QXR0ZW1wdHMgJiYgIWZlZWREYXRhKSB7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7IC8vIFdhaXQgMiBzZWNvbmRzIGJldHdlZW4gYXR0ZW1wdHNcbiAgICAgICAgICBhdHRlbXB0cysrO1xuXG4gICAgICAgICAgZmVlZERhdGEgPSAoYXdhaXQgcGFnZS5ldmFsdWF0ZShgXG4gICAgICAgICAgICAoKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAod2luZG93Ll9fSU5JVElBTF9TVEFURV9fICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5mZWVkICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5mZWVkLmZlZWRzICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5mZWVkLmZlZWRzLl92YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAvLyBUcnkgdG8gc2VyaWFsaXplIGp1c3QgdGhlIGZlZWRzIGRhdGEgdG8gYXZvaWQgY2lyY3VsYXIgcmVmZXJlbmNlIGlzc3Vlc1xuICAgICAgICAgICAgICAgICAgY29uc3QgZmVlZHNEYXRhID0gd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLmZlZWQuZmVlZHMuX3ZhbHVlO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGZlZWRzRGF0YSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBzZXJpYWxpemUgZmVlZHMgZGF0YTonLCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfSkoKVxuICAgICAgICAgIGApKSBhcyBzdHJpbmcgfCBudWxsO1xuXG4gICAgICAgICAgaWYgKGZlZWREYXRhKSB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhgRmVlZCByZXN1bHRzIGxvYWRlZCBhZnRlciAke2F0dGVtcHRzfSBhdHRlbXB0c2ApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFmZWVkRGF0YSkge1xuICAgICAgICAgIHRocm93IG5ldyBGZWVkUGFyc2luZ0Vycm9yKFxuICAgICAgICAgICAgYENvdWxkIG5vdCBleHRyYWN0IGZlZWQgZGF0YSBhZnRlciAke21heEF0dGVtcHRzfSBhdHRlbXB0cy4gVGhlIHBhZ2UgbWF5IG5vdCBiZSBmdWxseSBsb2FkZWQgb3IgdGhlIHN0YXRlIHN0cnVjdHVyZSBoYXMgY2hhbmdlZC5gLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1cmw6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmhvbWVVcmwsXG4gICAgICAgICAgICAgIHN1Z2dlc3Rpb246ICdUcnkgbG9nZ2luZyBpbiBmaXJzdCB1c2luZyB4aHNfYXV0aF9sb2dpbiB0b29sJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmVlZHNWYWx1ZSA9IEpTT04ucGFyc2UoZmVlZERhdGEpIGFzIHVua25vd25bXTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgZmVlZHM6IGZlZWRzVmFsdWUgYXMgRmVlZEl0ZW1bXSxcbiAgICAgICAgICBjb3VudDogZmVlZHNWYWx1ZS5sZW5ndGgsXG4gICAgICAgICAgc291cmNlOiAnaG9tZV9wYWdlJyxcbiAgICAgICAgICB1cmw6IHRoaXMuZ2V0Q29uZmlnKCkueGhzLmhvbWVVcmwsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vdExvZ2dlZEluRXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBGZWVkUGFyc2luZ0Vycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IGZlZWQgbGlzdDogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IG5ldyBYSFNFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBnZXQgZmVlZCBsaXN0OiAke2Vycm9yfWAsXG4gICAgICAgICdHZXRGZWVkTGlzdEVycm9yJyxcbiAgICAgICAge30sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNlYXJjaEZlZWRzKGtleXdvcmQ6IHN0cmluZywgYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPFNlYXJjaFJlc3VsdD4ge1xuICAgIGlmICgha2V5d29yZCB8fCAha2V5d29yZC50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBGZWVkRXJyb3IoJ1NlYXJjaCBrZXl3b3JkIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIGNvbnN0IHRyaW1tZWRLZXl3b3JkID0ga2V5d29yZC50cmltKCk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc2VhcmNoVXJsID0gbWFrZVNlYXJjaFVybCh0cmltbWVkS2V5d29yZCk7XG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShwYWdlLCBzZWFyY2hVcmwpO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHNlYXJjaCByZXN1bHRzIHRvIGxvYWQgd2l0aCBtdWx0aXBsZSBhdHRlbXB0c1xuICAgICAgICBsZXQgc2VhcmNoRGF0YTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XG4gICAgICAgIGNvbnN0IG1heEF0dGVtcHRzID0gMTA7XG5cbiAgICAgICAgd2hpbGUgKGF0dGVtcHRzIDwgbWF4QXR0ZW1wdHMgJiYgIXNlYXJjaERhdGEpIHtcbiAgICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTsgLy8gV2FpdCAyIHNlY29uZHMgYmV0d2VlbiBhdHRlbXB0c1xuICAgICAgICAgIGF0dGVtcHRzKys7XG5cbiAgICAgICAgICBzZWFyY2hEYXRhID0gKGF3YWl0IHBhZ2UuZXZhbHVhdGUoYFxuICAgICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXyAmJiB3aW5kb3cuX19JTklUSUFMX1NUQVRFX18uc2VhcmNoICYmIHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5zZWFyY2guZmVlZHMgJiYgd2luZG93Ll9fSU5JVElBTF9TVEFURV9fLnNlYXJjaC5mZWVkcy5fdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgLy8gVHJ5IHRvIHNlcmlhbGl6ZSBqdXN0IHRoZSBmZWVkcyBkYXRhIHRvIGF2b2lkIGNpcmN1bGFyIHJlZmVyZW5jZSBpc3N1ZXNcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZlZWRzRGF0YSA9IHdpbmRvdy5fX0lOSVRJQUxfU1RBVEVfXy5zZWFyY2guZmVlZHMuX3ZhbHVlO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGZlZWRzRGF0YSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBzZXJpYWxpemUgZmVlZHMgZGF0YTonLCBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfSkoKVxuICAgICAgICAgIGApKSBhcyBzdHJpbmcgfCBudWxsO1xuXG4gICAgICAgICAgaWYgKHNlYXJjaERhdGEpIHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBTZWFyY2ggcmVzdWx0cyBsb2FkZWQgYWZ0ZXIgJHthdHRlbXB0c30gYXR0ZW1wdHNgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc2VhcmNoRGF0YSkge1xuICAgICAgICAgIHRocm93IG5ldyBGZWVkUGFyc2luZ0Vycm9yKFxuICAgICAgICAgICAgYENvdWxkIG5vdCBleHRyYWN0IHNlYXJjaCByZXN1bHRzIGZvciBrZXl3b3JkOiAke3RyaW1tZWRLZXl3b3JkfSBhZnRlciAke21heEF0dGVtcHRzfSBhdHRlbXB0c2AsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGtleXdvcmQ6IHRyaW1tZWRLZXl3b3JkLFxuICAgICAgICAgICAgICB1cmw6IHNlYXJjaFVybCxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmVlZHNWYWx1ZSA9IEpTT04ucGFyc2Uoc2VhcmNoRGF0YSkgYXMgdW5rbm93bltdO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBrZXl3b3JkOiB0cmltbWVkS2V5d29yZCxcbiAgICAgICAgICBmZWVkczogZmVlZHNWYWx1ZSBhcyBGZWVkSXRlbVtdLFxuICAgICAgICAgIGNvdW50OiBmZWVkc1ZhbHVlLmxlbmd0aCxcbiAgICAgICAgICBzZWFyY2hVcmwsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEZlZWRFcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgRmVlZCBzZWFyY2ggZmFpbGVkIGZvciBrZXl3b3JkICcke3RyaW1tZWRLZXl3b3JkfSc6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgWEhTRXJyb3IoXG4gICAgICAgIGBGZWVkIHNlYXJjaCBmYWlsZWQ6ICR7ZXJyb3J9YCxcbiAgICAgICAgJ1NlYXJjaEZlZWRzRXJyb3InLFxuICAgICAgICB7IGtleXdvcmQ6IHRyaW1tZWRLZXl3b3JkIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldEZlZWREZXRhaWwoXG4gICAgZmVlZElkOiBzdHJpbmcsXG4gICAgeHNlY1Rva2VuOiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxGZWVkRGV0YWlsUmVzdWx0PiB7XG4gICAgaWYgKCFmZWVkSWQgfHwgIXhzZWNUb2tlbikge1xuICAgICAgdGhyb3cgbmV3IEZlZWRFcnJvcignQm90aCBmZWVkX2lkIGFuZCB4c2VjX3Rva2VuIGFyZSByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkZXRhaWxVcmwgPSBtYWtlRmVlZERldGFpbFVybChmZWVkSWQsIHhzZWNUb2tlbik7XG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5uYXZpZ2F0ZVdpdGhSZXRyeShwYWdlLCBkZXRhaWxVcmwpO1xuICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgICBjb25zdCBzdGF0ZSA9IGF3YWl0IGV4dHJhY3RJbml0aWFsU3RhdGUocGFnZSk7XG5cbiAgICAgICAgY29uc3Qgbm90ZURhdGEgPSBzdGF0ZT8ubm90ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgaWYgKCFzdGF0ZSB8fCAhbm90ZURhdGEgfHwgIW5vdGVEYXRhLm5vdGVEZXRhaWxNYXApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmVlZFBhcnNpbmdFcnJvcihgQ291bGQgbm90IGV4dHJhY3Qgbm90ZSBkZXRhaWxzIGZvciBmZWVkOiAke2ZlZWRJZH1gLCB7XG4gICAgICAgICAgICBmZWVkSWQsXG4gICAgICAgICAgICB1cmw6IGRldGFpbFVybCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5vdGVEZXRhaWxNYXAgPSBub3RlRGF0YS5ub3RlRGV0YWlsTWFwIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICBpZiAoIShmZWVkSWQgaW4gbm90ZURldGFpbE1hcCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmVlZE5vdEZvdW5kRXJyb3IoYEZlZWQgJHtmZWVkSWR9IG5vdCBmb3VuZCBpbiBub3RlIGRldGFpbHNgLCB7XG4gICAgICAgICAgICBmZWVkSWQsXG4gICAgICAgICAgICBhdmFpbGFibGVGZWVkczogT2JqZWN0LmtleXMobm90ZURldGFpbE1hcCksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZXRhaWwgPSBub3RlRGV0YWlsTWFwW2ZlZWRJZF0gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIGZlZWRJZCxcbiAgICAgICAgICBkZXRhaWwsXG4gICAgICAgICAgdXJsOiBkZXRhaWxVcmwsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBGZWVkRXJyb3IgfHxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBGZWVkTm90Rm91bmRFcnJvciB8fFxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEZlZWRQYXJzaW5nRXJyb3JcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGdldCBmZWVkIGRldGFpbCBmb3IgJHtmZWVkSWR9OiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgbmV3IFhIU0Vycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGdldCBmZWVkIGRldGFpbDogJHtlcnJvcn1gLFxuICAgICAgICAnR2V0RmVlZERldGFpbEVycm9yJyxcbiAgICAgICAgeyBmZWVkSWQgfSxcbiAgICAgICAgZXJyb3IgYXMgRXJyb3JcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY29tbWVudE9uRmVlZChcbiAgICBmZWVkSWQ6IHN0cmluZyxcbiAgICB4c2VjVG9rZW46IHN0cmluZyxcbiAgICBub3RlOiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDb21tZW50UmVzdWx0PiB7XG4gICAgaWYgKCFmZWVkSWQgfHwgIXhzZWNUb2tlbiB8fCAhbm90ZSkge1xuICAgICAgdGhyb3cgbmV3IEZlZWRFcnJvcignZmVlZF9pZCwgeHNlY190b2tlbiwgYW5kIG5vdGUgYXJlIGFsbCByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmIChub3RlLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBGZWVkRXJyb3IoJ0NvbW1lbnQgbm90ZSBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKGZhbHNlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRldGFpbFVybCA9IG1ha2VGZWVkRGV0YWlsVXJsKGZlZWRJZCwgeHNlY1Rva2VuKTtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIGRldGFpbFVybCk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIGxvZ2dlZCBpblxuICAgICAgICBpZiAoIShhd2FpdCBpc0xvZ2dlZEluKHBhZ2UpKSkge1xuICAgICAgICAgIHRocm93IG5ldyBOb3RMb2dnZWRJbkVycm9yKCdNdXN0IGJlIGxvZ2dlZCBpbiB0byBjb21tZW50IG9uIGZlZWRzJywge1xuICAgICAgICAgICAgb3BlcmF0aW9uOiAnY29tbWVudF9vbl9mZWVkJyxcbiAgICAgICAgICAgIGZlZWRJZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENsaWNrIG9uIGNvbW1lbnQgaW5wdXRcbiAgICAgICAgY29uc3QgY29tbWVudElucHV0U2VsZWN0b3IgPSAnZGl2LmlucHV0LWJveCBkaXYuY29udGVudC1lZGl0IHNwYW4nO1xuICAgICAgICBpZiAoIShhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkudHJ5V2FpdEZvclNlbGVjdG9yKHBhZ2UsIGNvbW1lbnRJbnB1dFNlbGVjdG9yKSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmVlZEVycm9yKCdDb21tZW50IGlucHV0IG5vdCBmb3VuZCBvbiBwYWdlJywge1xuICAgICAgICAgICAgZmVlZElkLFxuICAgICAgICAgICAgc2VsZWN0b3I6IGNvbW1lbnRJbnB1dFNlbGVjdG9yLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29tbWVudElucHV0ID0gYXdhaXQgcGFnZS4kKGNvbW1lbnRJbnB1dFNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGNvbW1lbnRJbnB1dCkge1xuICAgICAgICAgIGF3YWl0IGNvbW1lbnRJbnB1dC5jbGljaygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmlsbCBjb21tZW50IG5vdGVcbiAgICAgICAgY29uc3QgZWRpdG9yU2VsZWN0b3IgPSAnZGl2LmlucHV0LWJveCBkaXYuY29udGVudC1lZGl0IHAuY29udGVudC1pbnB1dCc7XG4gICAgICAgIGNvbnN0IGVkaXRvciA9IGF3YWl0IHBhZ2UuJChlZGl0b3JTZWxlY3Rvcik7XG5cbiAgICAgICAgaWYgKGVkaXRvcikge1xuICAgICAgICAgIGF3YWl0IGVkaXRvci5jbGljaygpO1xuICAgICAgICAgIGF3YWl0IGVkaXRvci50eXBlKG5vdGUsIHsgZGVsYXk6IDMwIH0pO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAgIC8vIFN1Ym1pdCBjb21tZW50XG4gICAgICAgIGNvbnN0IHN1Ym1pdFNlbGVjdG9yID0gJ2Rpdi5ib3R0b20gYnV0dG9uLnN1Ym1pdCc7XG4gICAgICAgIGNvbnN0IHN1Ym1pdEJ1dHRvbiA9IGF3YWl0IHBhZ2UuJChzdWJtaXRTZWxlY3Rvcik7XG4gICAgICAgIGlmIChzdWJtaXRCdXR0b24pIHtcbiAgICAgICAgICBhd2FpdCBzdWJtaXRCdXR0b24uY2xpY2soKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTsgLy8gV2FpdCBmb3Igc3VibWlzc2lvblxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBtZXNzYWdlOiAnQ29tbWVudCBzdWJtaXR0ZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICBmZWVkSWQsXG4gICAgICAgICAgbm90ZSxcbiAgICAgICAgICB1cmw6IGRldGFpbFVybCxcbiAgICAgICAgfTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRmVlZEVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTm90TG9nZ2VkSW5FcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGNvbW1lbnQgb24gZmVlZCAke2ZlZWRJZH06ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgWEhTRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gY29tbWVudCBvbiBmZWVkOiAke2Vycm9yfWAsXG4gICAgICAgICdDb21tZW50T25GZWVkRXJyb3InLFxuICAgICAgICB7IGZlZWRJZCB9LFxuICAgICAgICBlcnJvciBhcyBFcnJvclxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogVGl0bGUgdmFsaWRhdGlvbiB1dGlsaXR5IGZvciBYSFMgTUNQIFNlcnZlclxuICogVmFsaWRhdGVzIHRpdGxlIHdpZHRoIGFjY29yZGluZyB0byBYaWFvSG9uZ1NodSdzIGRpc3BsYXkgd2lkdGggcnVsZXNcbiAqXG4gKiBYSFMgUnVsZXM6XG4gKiAtIE1heCB3aWR0aDogNDAgdW5pdHNcbiAqIC0gQ0pLIGNoYXJhY3RlcnMgKENoaW5lc2UvSmFwYW5lc2UvS29yZWFuKTogMiB1bml0cyBlYWNoXG4gKiAtIE90aGVyIGNoYXJhY3RlcnMgKEVuZ2xpc2gvTnVtYmVycyk6IDEgdW5pdCBlYWNoXG4gKi9cblxuaW1wb3J0IHN0cmluZ1dpZHRoIGZyb20gJ3N0cmluZy13aWR0aCc7XG5pbXBvcnQgeyBQdWJsaXNoRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGl0bGVWYWxpZGF0aW9uUmVzdWx0IHtcbiAgdmFsaWQ6IGJvb2xlYW47XG4gIHdpZHRoOiBudW1iZXI7XG4gIG1heFdpZHRoOiBudW1iZXI7XG4gIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIHN1Z2dlc3Rpb24/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogWGlhb0hvbmdTaHUgdGl0bGUgY29uc3RyYWludHNcbiAqL1xuZXhwb3J0IGNvbnN0IFhIU19USVRMRV9DT05TVFJBSU5UUyA9IHtcbiAgTUFYX1dJRFRIOiA0MCwgLy8gTWF4aW11bSBkaXNwbGF5IHdpZHRoIGluIHVuaXRzXG4gIE1BWF9MRU5HVEg6IDIwLCAvLyBBcHByb3hpbWF0ZSBtYXggY2hhcmFjdGVyIGNvdW50IChmb3IgcmVmZXJlbmNlKVxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBWYWxpZGF0ZSB0aXRsZSB3aWR0aCBhY2NvcmRpbmcgdG8gWEhTIGRpc3BsYXkgcnVsZXNcbiAqXG4gKiBAcGFyYW0gdGl0bGUgLSBUaGUgdGl0bGUgdG8gdmFsaWRhdGVcbiAqIEByZXR1cm5zIFZhbGlkYXRpb24gcmVzdWx0IHdpdGggd2lkdGggaW5mb3JtYXRpb25cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVzdWx0ID0gdmFsaWRhdGVUaXRsZVdpZHRoKCdIZWxsb+S4lueVjCcpO1xuICogY29uc29sZS5sb2cocmVzdWx0LndpZHRoKTsgLy8gMTAgKDUgKyAyKjIgKyAxID0gMTApXG4gKiBjb25zb2xlLmxvZyhyZXN1bHQudmFsaWQpOyAvLyB0cnVlXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlVGl0bGVXaWR0aCh0aXRsZTogc3RyaW5nKTogVGl0bGVWYWxpZGF0aW9uUmVzdWx0IHtcbiAgaWYgKCF0aXRsZSkge1xuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogZmFsc2UsXG4gICAgICB3aWR0aDogMCxcbiAgICAgIG1heFdpZHRoOiBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRILFxuICAgICAgbWVzc2FnZTogJ1RpdGxlIGNhbm5vdCBiZSBlbXB0eScsXG4gICAgICBzdWdnZXN0aW9uOiAnUGxlYXNlIHByb3ZpZGUgYSB2YWxpZCB0aXRsZScsXG4gICAgfTtcbiAgfVxuXG4gIC8vIENhbGN1bGF0ZSBkaXNwbGF5IHdpZHRoIHVzaW5nIHN0cmluZy13aWR0aFxuICAvLyBUaGlzIGNvcnJlY3RseSBoYW5kbGVzIENKSyBjaGFyYWN0ZXJzLCBlbW9qaSwgYW5kIG90aGVyIFVuaWNvZGVcbiAgY29uc3Qgd2lkdGggPSBzdHJpbmdXaWR0aCh0aXRsZSk7XG5cbiAgaWYgKHdpZHRoID4gWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSCkge1xuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogZmFsc2UsXG4gICAgICB3aWR0aCxcbiAgICAgIG1heFdpZHRoOiBYSFNfVElUTEVfQ09OU1RSQUlOVFMuTUFYX1dJRFRILFxuICAgICAgbWVzc2FnZTogYFRpdGxlIHdpZHRoIGV4Y2VlZHMgbGltaXQ6ICR7d2lkdGh9IHVuaXRzIChtYXg6ICR7WEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSH0gdW5pdHMpYCxcbiAgICAgIHN1Z2dlc3Rpb246IGBDdXJyZW50IHRpdGxlIGlzIHRvbyBsb25nLiBDSksgY2hhcmFjdGVycyBjb3VudCBhcyAyIHVuaXRzLCBFbmdsaXNoL251bWJlcnMgYXMgMSB1bml0LiBQbGVhc2Ugc2hvcnRlbiB5b3VyIHRpdGxlLmAsXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdmFsaWQ6IHRydWUsXG4gICAgd2lkdGgsXG4gICAgbWF4V2lkdGg6IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgsXG4gIH07XG59XG5cbi8qKlxuICogVmFsaWRhdGUgYW5kIHRocm93IGVycm9yIGlmIHRpdGxlIHdpZHRoIGlzIGludmFsaWRcbiAqXG4gKiBAcGFyYW0gdGl0bGUgLSBUaGUgdGl0bGUgdG8gdmFsaWRhdGVcbiAqIEB0aHJvd3MgUHVibGlzaEVycm9yIGlmIHRpdGxlIHdpZHRoIGlzIGludmFsaWRcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogdHJ5IHtcbiAqICAgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkKCflvojplb/lvojplb/nmoTmoIfpopgnLnJlcGVhdCgxMCkpO1xuICogfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0VGl0bGVXaWR0aFZhbGlkKHRpdGxlOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgcmVzdWx0ID0gdmFsaWRhdGVUaXRsZVdpZHRoKHRpdGxlKTtcblxuICBpZiAoIXJlc3VsdC52YWxpZCkge1xuICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IocmVzdWx0Lm1lc3NhZ2UhLCB7XG4gICAgICB0aXRsZSxcbiAgICAgIHdpZHRoOiByZXN1bHQud2lkdGgsXG4gICAgICBtYXhXaWR0aDogcmVzdWx0Lm1heFdpZHRoLFxuICAgICAgc3VnZ2VzdGlvbjogcmVzdWx0LnN1Z2dlc3Rpb24sXG4gICAgICBkZXRhaWxzOiB7XG4gICAgICAgIHRpdGxlTGVuZ3RoOiB0aXRsZS5sZW5ndGgsXG4gICAgICAgIGRpc3BsYXlXaWR0aDogcmVzdWx0LndpZHRoLFxuICAgICAgICBtYXhEaXNwbGF5V2lkdGg6IHJlc3VsdC5tYXhXaWR0aCxcbiAgICAgICAgZXhjZWVkZWQ6IHJlc3VsdC53aWR0aCAtIHJlc3VsdC5tYXhXaWR0aCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgdGhlIGRpc3BsYXkgd2lkdGggb2YgYSB0aXRsZVxuICpcbiAqIEBwYXJhbSB0aXRsZSAtIFRoZSB0aXRsZSB0byBtZWFzdXJlXG4gKiBAcmV0dXJucyBEaXNwbGF5IHdpZHRoIGluIHVuaXRzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnNvbGUubG9nKGdldFRpdGxlV2lkdGgoJ0hlbGxvJykpOyAgICAgICAgLy8gNVxuICogY29uc29sZS5sb2coZ2V0VGl0bGVXaWR0aCgn5L2g5aW9JykpOyAgICAgICAgIC8vIDQgKDIqMilcbiAqIGNvbnNvbGUubG9nKGdldFRpdGxlV2lkdGgoJ0hlbGxv5LiW55WMJykpOyAgICAvLyAxMCAoNSArIDIqMiArIDEpXG4gKiBjb25zb2xlLmxvZyhnZXRUaXRsZVdpZHRoKCfwn5GLSGVsbG8nKSk7ICAgICAgLy8gNyAoMiArIDUpXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRpdGxlV2lkdGgodGl0bGU6IHN0cmluZyk6IG51bWJlciB7XG4gIHJldHVybiBzdHJpbmdXaWR0aCh0aXRsZSk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIGhvdyBtYW55IGNoYXJhY3RlcnMgY2FuIGJlIGFkZGVkIHRvIHRoZSB0aXRsZVxuICpcbiAqIEBwYXJhbSB0aXRsZSAtIEN1cnJlbnQgdGl0bGVcbiAqIEByZXR1cm5zIFJlbWFpbmluZyB3aWR0aCB1bml0cyBhdmFpbGFibGVcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVtYWluaW5nID0gZ2V0UmVtYWluaW5nVGl0bGVXaWR0aCgnSGVsbG8nKTsgLy8gMzVcbiAqIGNvbnNvbGUubG9nKGBZb3UgY2FuIGFkZCAke3JlbWFpbmluZ30gbW9yZSB1bml0c2ApO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVSZW1haW5pbmdUaXRsZVdpZHRoKHRpdGxlOiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCBjdXJyZW50V2lkdGggPSBnZXRUaXRsZVdpZHRoKHRpdGxlKTtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEggLSBjdXJyZW50V2lkdGgpO1xufVxuXG4vKipcbiAqIFRydW5jYXRlIHRpdGxlIHRvIGZpdCB3aXRoaW4gd2lkdGggbGltaXRcbiAqXG4gKiBAcGFyYW0gdGl0bGUgLSBUaGUgdGl0bGUgdG8gdHJ1bmNhdGVcbiAqIEBwYXJhbSBtYXhXaWR0aCAtIE1heGltdW0gd2lkdGggKGRlZmF1bHQ6IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgpXG4gKiBAcmV0dXJucyBUcnVuY2F0ZWQgdGl0bGUgdGhhdCBmaXRzIHdpdGhpbiB3aWR0aCBsaW1pdFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBsb25nID0gJ+i/meaYr+S4gOS4quW+iOmVv+W+iOmVv+eahOagh+mimCcucmVwZWF0KDUpO1xuICogY29uc3QgdHJ1bmNhdGVkID0gdHJ1bmNhdGVUaXRsZVRvV2lkdGgobG9uZyk7XG4gKiBjb25zb2xlLmxvZyhnZXRUaXRsZVdpZHRoKHRydW5jYXRlZCkpOyAvLyA8PSA0MFxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cnVuY2F0ZVRpdGxlVG9XaWR0aChcbiAgdGl0bGU6IHN0cmluZyxcbiAgbWF4V2lkdGg6IG51bWJlciA9IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEhcbik6IHN0cmluZyB7XG4gIGlmIChnZXRUaXRsZVdpZHRoKHRpdGxlKSA8PSBtYXhXaWR0aCkge1xuICAgIHJldHVybiB0aXRsZTtcbiAgfVxuXG4gIGxldCB0cnVuY2F0ZWQgPSAnJztcbiAgbGV0IGN1cnJlbnRXaWR0aCA9IDA7XG5cbiAgZm9yIChjb25zdCBjaGFyIG9mIHRpdGxlKSB7XG4gICAgY29uc3QgY2hhcldpZHRoID0gc3RyaW5nV2lkdGgoY2hhcik7XG5cbiAgICBpZiAoY3VycmVudFdpZHRoICsgY2hhcldpZHRoID4gbWF4V2lkdGgpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHRydW5jYXRlZCArPSBjaGFyO1xuICAgIGN1cnJlbnRXaWR0aCArPSBjaGFyV2lkdGg7XG4gIH1cblxuICByZXR1cm4gdHJ1bmNhdGVkO1xufVxuXG4vKipcbiAqIEdldCBodW1hbi1yZWFkYWJsZSB3aWR0aCBicmVha2Rvd25cbiAqIFVzZWZ1bCBmb3IgZGVidWdnaW5nIGFuZCB1c2VyIGZlZWRiYWNrXG4gKlxuICogQHBhcmFtIHRpdGxlIC0gVGhlIHRpdGxlIHRvIGFuYWx5emVcbiAqIEByZXR1cm5zIFdpZHRoIGJyZWFrZG93biBpbmZvcm1hdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGl0bGVXaWR0aEJyZWFrZG93bih0aXRsZTogc3RyaW5nKToge1xuICB0aXRsZTogc3RyaW5nO1xuICB0b3RhbFdpZHRoOiBudW1iZXI7XG4gIHRvdGFsQ2hhcnM6IG51bWJlcjtcbiAgbWF4V2lkdGg6IG51bWJlcjtcbiAgcmVtYWluaW5nOiBudW1iZXI7XG4gIHZhbGlkOiBib29sZWFuO1xuICBicmVha2Rvd246IEFycmF5PHtcbiAgICBjaGFyOiBzdHJpbmc7XG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICB0eXBlOiAnQ0pLJyB8ICdBU0NJSScgfCAnRW1vamknIHwgJ090aGVyJztcbiAgfT47XG59IHtcbiAgY29uc3QgdG90YWxXaWR0aCA9IGdldFRpdGxlV2lkdGgodGl0bGUpO1xuICBjb25zdCBicmVha2Rvd246IEFycmF5PHtcbiAgICBjaGFyOiBzdHJpbmc7XG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICB0eXBlOiAnQ0pLJyB8ICdBU0NJSScgfCAnRW1vamknIHwgJ090aGVyJztcbiAgfT4gPSBbXTtcblxuICBmb3IgKGNvbnN0IGNoYXIgb2YgdGl0bGUpIHtcbiAgICBjb25zdCBjaGFyV2lkdGggPSBzdHJpbmdXaWR0aChjaGFyKTtcbiAgICBsZXQgdHlwZTogJ0NKSycgfCAnQVNDSUknIHwgJ0Vtb2ppJyB8ICdPdGhlcicgPSAnT3RoZXInO1xuXG4gICAgY29uc3QgY29kZSA9IGNoYXIuY2hhckNvZGVBdCgwKTtcbiAgICBpZiAoY2hhci5tYXRjaCgvW1xcdTRlMDAtXFx1OWZmZlxcdTM0MDAtXFx1NGRiZlxcdWY5MDAtXFx1ZmFmZl0vKSkge1xuICAgICAgdHlwZSA9ICdDSksnO1xuICAgIH0gZWxzZSBpZiAoY29kZSA8IDEyOCkge1xuICAgICAgdHlwZSA9ICdBU0NJSSc7XG4gICAgfSBlbHNlIGlmIChjaGFyLm1hdGNoKC9bXFx1ezFGMzAwfS1cXHV7MUY5RkZ9XS91KSkge1xuICAgICAgdHlwZSA9ICdFbW9qaSc7XG4gICAgfVxuXG4gICAgYnJlYWtkb3duLnB1c2goeyBjaGFyLCB3aWR0aDogY2hhcldpZHRoLCB0eXBlIH0pO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0aXRsZSxcbiAgICB0b3RhbFdpZHRoLFxuICAgIHRvdGFsQ2hhcnM6IHRpdGxlLmxlbmd0aCxcbiAgICBtYXhXaWR0aDogWEhTX1RJVExFX0NPTlNUUkFJTlRTLk1BWF9XSURUSCxcbiAgICByZW1haW5pbmc6IGNhbGN1bGF0ZVJlbWFpbmluZ1RpdGxlV2lkdGgodGl0bGUpLFxuICAgIHZhbGlkOiB0b3RhbFdpZHRoIDw9IFhIU19USVRMRV9DT05TVFJBSU5UUy5NQVhfV0lEVEgsXG4gICAgYnJlYWtkb3duLFxuICB9O1xufVxuIiwiY29uc3QgX19XRUJQQUNLX05BTUVTUEFDRV9PQkpFQ1RfXyA9IHJlcXVpcmUoXCJjcnlwdG9cIik7IiwiY29uc3QgX19XRUJQQUNLX05BTUVTUEFDRV9PQkpFQ1RfXyA9IHJlcXVpcmUoXCJub2RlLWZldGNoXCIpOyIsIi8qKlxuICogSW1hZ2UgZG93bmxvYWRlciB1dGlsaXR5IGZvciBYSFMgTUNQIFNlcnZlclxuICogU3VwcG9ydHMgZG93bmxvYWRpbmcgaW1hZ2VzIGZyb20gSFRUUC9IVFRQUyBVUkxzXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCBta2RpclN5bmMsIHdyaXRlRmlsZVN5bmMsIHN0YXRTeW5jIH0gZnJvbSAnZnMnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IGZldGNoIGZyb20gJ25vZGUtZmV0Y2gnO1xuaW1wb3J0IHsgSW52YWxpZEltYWdlRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRG93bmxvYWRSZXN1bHQge1xuICBvcmlnaW5hbFVybDogc3RyaW5nO1xuICBsb2NhbFBhdGg6IHN0cmluZztcbiAgY2FjaGVkOiBib29sZWFuO1xuICBmaWxlU2l6ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgSW1hZ2VEb3dubG9hZGVyIHtcbiAgcHJpdmF0ZSBzYXZlRGlyOiBzdHJpbmc7XG4gIHByaXZhdGUgdGltZW91dDogbnVtYmVyO1xuICBwcml2YXRlIG1heEZpbGVTaXplOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2F2ZURpcjogc3RyaW5nID0gJy4vdGVtcF9pbWFnZXMnLFxuICAgIHRpbWVvdXQ6IG51bWJlciA9IDMwMDAwLFxuICAgIG1heEZpbGVTaXplOiBudW1iZXIgPSAxMCAqIDEwMjQgKiAxMDI0IC8vIDEwTUIgZGVmYXVsdFxuICApIHtcbiAgICB0aGlzLnNhdmVEaXIgPSBzYXZlRGlyO1xuICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXQ7XG4gICAgdGhpcy5tYXhGaWxlU2l6ZSA9IG1heEZpbGVTaXplO1xuXG4gICAgLy8gRW5zdXJlIHNhdmUgZGlyZWN0b3J5IGV4aXN0c1xuICAgIGlmICghZXhpc3RzU3luYyh0aGlzLnNhdmVEaXIpKSB7XG4gICAgICBta2RpclN5bmModGhpcy5zYXZlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBIVFRQL0hUVFBTIFVSTFxuICAgKi9cbiAgc3RhdGljIGlzSW1hZ2VVcmwocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFwYXRoKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgbG93ZXJQYXRoID0gcGF0aC50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcbiAgICByZXR1cm4gbG93ZXJQYXRoLnN0YXJ0c1dpdGgoJ2h0dHA6Ly8nKSB8fCBsb3dlclBhdGguc3RhcnRzV2l0aCgnaHR0cHM6Ly8nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIHVuaXF1ZSBmaWxlbmFtZSBmb3IgYW4gaW1hZ2UgVVJMXG4gICAqIFVzZXMgb25seSBVUkwgaGFzaCBmb3IgY29uc2lzdGVudCBjYWNoaW5nXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlRmlsZU5hbWUoaW1hZ2VVcmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgLy8gVXNlIFNIQTI1NiBoYXNoIG9mIFVSTCBmb3IgdW5pcXVlbmVzc1xuICAgIGNvbnN0IGhhc2ggPSBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoaW1hZ2VVcmwpLmRpZ2VzdCgnaGV4Jyk7XG4gICAgY29uc3Qgc2hvcnRIYXNoID0gaGFzaC5zdWJzdHJpbmcoMCwgMTYpO1xuXG4gICAgLy8gVHJ5IHRvIGV4dHJhY3QgZXh0ZW5zaW9uIGZyb20gVVJMXG4gICAgbGV0IGV4dGVuc2lvbiA9ICdqcGcnOyAvLyBkZWZhdWx0XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVybCA9IG5ldyBVUkwoaW1hZ2VVcmwpO1xuICAgICAgY29uc3QgcGF0aG5hbWUgPSB1cmwucGF0aG5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICAgIGNvbnN0IG1hdGNoID0gcGF0aG5hbWUubWF0Y2goL1xcLihqcGd8anBlZ3xwbmd8Z2lmfHdlYnB8Ym1wKSQvaSk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgZXh0ZW5zaW9uID0gbWF0Y2hbMV07XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBVc2UgZGVmYXVsdCBleHRlbnNpb25cbiAgICB9XG5cbiAgICAvLyBGaXhlZCBmaWxlbmFtZSBmb3IgcHJvcGVyIGNhY2hpbmcgKG5vIHRpbWVzdGFtcClcbiAgICByZXR1cm4gYGltZ18ke3Nob3J0SGFzaH0uJHtleHRlbnNpb259YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGF0IGRvd25sb2FkZWQgZGF0YSBpcyBhY3R1YWxseSBhbiBpbWFnZVxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUltYWdlRGF0YShidWZmZXI6IEJ1ZmZlcik6IHsgaXNWYWxpZDogYm9vbGVhbjsgZXh0ZW5zaW9uOiBzdHJpbmcgfSB7XG4gICAgLy8gQ2hlY2sgZmlsZSBzaWduYXR1cmVzIChtYWdpYyBudW1iZXJzKVxuICAgIGlmIChidWZmZXIubGVuZ3RoIDwgMTIpIHtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCBleHRlbnNpb246ICcnIH07XG4gICAgfVxuXG4gICAgLy8gSlBFR1xuICAgIGlmIChidWZmZXJbMF0gPT09IDB4ZmYgJiYgYnVmZmVyWzFdID09PSAweGQ4ICYmIGJ1ZmZlclsyXSA9PT0gMHhmZikge1xuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogdHJ1ZSwgZXh0ZW5zaW9uOiAnanBnJyB9O1xuICAgIH1cblxuICAgIC8vIFBOR1xuICAgIGlmIChidWZmZXJbMF0gPT09IDB4ODkgJiYgYnVmZmVyWzFdID09PSAweDUwICYmIGJ1ZmZlclsyXSA9PT0gMHg0ZSAmJiBidWZmZXJbM10gPT09IDB4NDcpIHtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IHRydWUsIGV4dGVuc2lvbjogJ3BuZycgfTtcbiAgICB9XG5cbiAgICAvLyBHSUZcbiAgICBpZiAoYnVmZmVyWzBdID09PSAweDQ3ICYmIGJ1ZmZlclsxXSA9PT0gMHg0OSAmJiBidWZmZXJbMl0gPT09IDB4NDYpIHtcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IHRydWUsIGV4dGVuc2lvbjogJ2dpZicgfTtcbiAgICB9XG5cbiAgICAvLyBXZWJQXG4gICAgaWYgKFxuICAgICAgYnVmZmVyWzBdID09PSAweDUyICYmXG4gICAgICBidWZmZXJbMV0gPT09IDB4NDkgJiZcbiAgICAgIGJ1ZmZlclsyXSA9PT0gMHg0NiAmJlxuICAgICAgYnVmZmVyWzNdID09PSAweDQ2ICYmXG4gICAgICBidWZmZXJbOF0gPT09IDB4NTcgJiZcbiAgICAgIGJ1ZmZlcls5XSA9PT0gMHg0NSAmJlxuICAgICAgYnVmZmVyWzEwXSA9PT0gMHg0MiAmJlxuICAgICAgYnVmZmVyWzExXSA9PT0gMHg1MFxuICAgICkge1xuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogdHJ1ZSwgZXh0ZW5zaW9uOiAnd2VicCcgfTtcbiAgICB9XG5cbiAgICAvLyBCTVBcbiAgICBpZiAoYnVmZmVyWzBdID09PSAweDQyICYmIGJ1ZmZlclsxXSA9PT0gMHg0ZCkge1xuICAgICAgcmV0dXJuIHsgaXNWYWxpZDogdHJ1ZSwgZXh0ZW5zaW9uOiAnYm1wJyB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCBleHRlbnNpb246ICcnIH07XG4gIH1cblxuICAvKipcbiAgICogRG93bmxvYWQgYSBzaW5nbGUgaW1hZ2UgZnJvbSBVUkxcbiAgICovXG4gIGFzeW5jIGRvd25sb2FkSW1hZ2UoaW1hZ2VVcmw6IHN0cmluZyk6IFByb21pc2U8RG93bmxvYWRSZXN1bHQ+IHtcbiAgICAvLyBWYWxpZGF0ZSBVUkwgZm9ybWF0XG4gICAgaWYgKCFJbWFnZURvd25sb2FkZXIuaXNJbWFnZVVybChpbWFnZVVybCkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihgSW52YWxpZCBpbWFnZSBVUkwgZm9ybWF0OiAke2ltYWdlVXJsfWAsIHtcbiAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgc3VnZ2VzdGlvbjogJ1VSTCBtdXN0IHN0YXJ0IHdpdGggaHR0cDovLyBvciBodHRwczovLycsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSBmaWxlbmFtZSBhbmQgcGF0aFxuICAgIGNvbnN0IGZpbGVOYW1lID0gdGhpcy5nZW5lcmF0ZUZpbGVOYW1lKGltYWdlVXJsKTtcbiAgICBjb25zdCBsb2NhbFBhdGggPSBqb2luKHRoaXMuc2F2ZURpciwgZmlsZU5hbWUpO1xuXG4gICAgLy8gQ2hlY2sgaWYgZmlsZSBhbHJlYWR5IGV4aXN0cyAoY2FjaGUpXG4gICAgaWYgKGV4aXN0c1N5bmMobG9jYWxQYXRoKSkge1xuICAgICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhsb2NhbFBhdGgpO1xuICAgICAgbG9nZ2VyLmRlYnVnKGBVc2luZyBjYWNoZWQgaW1hZ2U6ICR7bG9jYWxQYXRofWApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3JpZ2luYWxVcmw6IGltYWdlVXJsLFxuICAgICAgICBsb2NhbFBhdGgsXG4gICAgICAgIGNhY2hlZDogdHJ1ZSxcbiAgICAgICAgZmlsZVNpemU6IHN0YXRzLnNpemUsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGxvZ2dlci5kZWJ1ZyhgRG93bmxvYWRpbmcgaW1hZ2UgZnJvbTogJHtpbWFnZVVybH1gKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBEb3dubG9hZCBpbWFnZSB3aXRoIHRpbWVvdXRcbiAgICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICBjb25zdCB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgdGhpcy50aW1lb3V0KTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChpbWFnZVVybCwge1xuICAgICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1VzZXItQWdlbnQnOiAnTW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTBfMTVfNykgQXBwbGVXZWJLaXQvNTM3LjM2JyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcblxuICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgICAgYEZhaWxlZCB0byBkb3dubG9hZCBpbWFnZTogSFRUUCAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBDb250ZW50LUxlbmd0aCBpZiBhdmFpbGFibGVcbiAgICAgIGNvbnN0IGNvbnRlbnRMZW5ndGggPSByZXNwb25zZS5oZWFkZXJzLmdldCgnY29udGVudC1sZW5ndGgnKTtcbiAgICAgIGlmIChjb250ZW50TGVuZ3RoICYmIHBhcnNlSW50KGNvbnRlbnRMZW5ndGgpID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgICAgYEltYWdlIGZpbGUgdG9vIGxhcmdlOiAkeyhwYXJzZUludChjb250ZW50TGVuZ3RoKSAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKFxuICAgICAgICAgICAgMlxuICAgICAgICAgICl9TUIgKG1heDogJHsodGhpcy5tYXhGaWxlU2l6ZSAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKDIpfU1CKWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgICAgIGZpbGVTaXplOiBwYXJzZUludChjb250ZW50TGVuZ3RoKSxcbiAgICAgICAgICAgIG1heFNpemU6IHRoaXMubWF4RmlsZVNpemUsXG4gICAgICAgICAgICBzdWdnZXN0aW9uOiAnVHJ5IHVzaW5nIGEgc21hbGxlciBpbWFnZSBvciBpbmNyZWFzZSBtYXhGaWxlU2l6ZScsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBHZXQgaW1hZ2UgZGF0YVxuICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oYXJyYXlCdWZmZXIpO1xuXG4gICAgICAvLyBWZXJpZnkgYWN0dWFsIHNpemVcbiAgICAgIGlmIChidWZmZXIubGVuZ3RoID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgICAgYERvd25sb2FkZWQgZmlsZSB0b28gbGFyZ2U6ICR7KGJ1ZmZlci5sZW5ndGggLyAxMDI0IC8gMTAyNCkudG9GaXhlZCgyKX1NQiAobWF4OiAkeyhcbiAgICAgICAgICAgIHRoaXMubWF4RmlsZVNpemUgL1xuICAgICAgICAgICAgMTAyNCAvXG4gICAgICAgICAgICAxMDI0XG4gICAgICAgICAgKS50b0ZpeGVkKDIpfU1CKWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgICAgIGZpbGVTaXplOiBidWZmZXIubGVuZ3RoLFxuICAgICAgICAgICAgbWF4U2l6ZTogdGhpcy5tYXhGaWxlU2l6ZSxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIFZhbGlkYXRlIGl0J3MgYWN0dWFsbHkgYW4gaW1hZ2VcbiAgICAgIGNvbnN0IHZhbGlkYXRpb24gPSB0aGlzLnZhbGlkYXRlSW1hZ2VEYXRhKGJ1ZmZlcik7XG4gICAgICBpZiAoIXZhbGlkYXRpb24uaXNWYWxpZCkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoYERvd25sb2FkZWQgZmlsZSBpcyBub3QgYSB2YWxpZCBpbWFnZTogJHtpbWFnZVVybH1gLCB7XG4gICAgICAgICAgdXJsOiBpbWFnZVVybCxcbiAgICAgICAgICBzdWdnZXN0aW9uOiAnTWFrZSBzdXJlIHRoZSBVUkwgcG9pbnRzIHRvIGFuIGFjdHVhbCBpbWFnZSBmaWxlJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNhdmUgdG8gZmlsZVxuICAgICAgd3JpdGVGaWxlU3luYyhsb2NhbFBhdGgsIGJ1ZmZlcik7XG5cbiAgICAgIGxvZ2dlci5kZWJ1ZyhgSW1hZ2UgZG93bmxvYWRlZCBzdWNjZXNzZnVsbHk6ICR7bG9jYWxQYXRofSAoJHtidWZmZXIubGVuZ3RofSBieXRlcylgKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3JpZ2luYWxVcmw6IGltYWdlVXJsLFxuICAgICAgICBsb2NhbFBhdGgsXG4gICAgICAgIGNhY2hlZDogZmFsc2UsXG4gICAgICAgIGZpbGVTaXplOiBidWZmZXIubGVuZ3RoLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSW52YWxpZEltYWdlRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSBhYm9ydCBlcnJvclxuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubmFtZSA9PT0gJ0Fib3J0RXJyb3InKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihcbiAgICAgICAgICBgSW1hZ2UgZG93bmxvYWQgdGltZW91dCBhZnRlciAke3RoaXMudGltZW91dH1tczogJHtpbWFnZVVybH1gLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVybDogaW1hZ2VVcmwsXG4gICAgICAgICAgICB0aW1lb3V0OiB0aGlzLnRpbWVvdXQsXG4gICAgICAgICAgICBzdWdnZXN0aW9uOiAnVGhlIGltYWdlIG1heSBiZSB0b28gbGFyZ2Ugb3IgdGhlIG5ldHdvcmsgaXMgc2xvdycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gZG93bmxvYWQgaW1hZ2U6ICR7aW1hZ2VVcmx9YCxcbiAgICAgICAge1xuICAgICAgICAgIHVybDogaW1hZ2VVcmwsXG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yIGFzIEVycm9yXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEb3dubG9hZCBtdWx0aXBsZSBpbWFnZXMgZnJvbSBVUkxzIChwYXJhbGxlbCBkb3dubG9hZCBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlKVxuICAgKi9cbiAgYXN5bmMgZG93bmxvYWRJbWFnZXMoaW1hZ2VVcmxzOiBzdHJpbmdbXSk6IFByb21pc2U8RG93bmxvYWRSZXN1bHRbXT4ge1xuICAgIC8vIERvd25sb2FkIGFsbCBpbWFnZXMgaW4gcGFyYWxsZWxcbiAgICBjb25zdCBkb3dubG9hZFByb21pc2VzID0gaW1hZ2VVcmxzLm1hcCgodXJsKSA9PlxuICAgICAgdGhpcy5kb3dubG9hZEltYWdlKHVybCkuY2F0Y2goKGVycm9yKSA9PiAoeyBlcnJvciwgdXJsIH0pKVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoZG93bmxvYWRQcm9taXNlcyk7XG5cbiAgICBjb25zdCBzdWNjZXNzUmVzdWx0czogRG93bmxvYWRSZXN1bHRbXSA9IFtdO1xuICAgIGNvbnN0IGVycm9yczogQXJyYXk8eyB1cmw6IHN0cmluZzsgZXJyb3I6IEVycm9yIH0+ID0gW107XG5cbiAgICByZXN1bHRzLmZvckVhY2goKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKCdlcnJvcicgaW4gcmVzdWx0KSB7XG4gICAgICAgIGVycm9ycy5wdXNoKHsgdXJsOiByZXN1bHQudXJsLCBlcnJvcjogcmVzdWx0LmVycm9yIGFzIEVycm9yIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3VsdHMucHVzaChyZXN1bHQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gSWYgYW55IGRvd25sb2FkcyBmYWlsZWQsIHRocm93IGFuIGVycm9yIHdpdGggZGV0YWlsc1xuICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlcyA9IGVycm9ycy5tYXAoKGUpID0+IGAke2UudXJsfTogJHtlLmVycm9yLm1lc3NhZ2V9YCkuam9pbignXFxuJyk7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gZG93bmxvYWQgJHtlcnJvcnMubGVuZ3RofSBvZiAke2ltYWdlVXJscy5sZW5ndGh9IGltYWdlczpcXG4ke2Vycm9yTWVzc2FnZXN9YCxcbiAgICAgICAge1xuICAgICAgICAgIHRvdGFsQ291bnQ6IGltYWdlVXJscy5sZW5ndGgsXG4gICAgICAgICAgZmFpbGVkQ291bnQ6IGVycm9ycy5sZW5ndGgsXG4gICAgICAgICAgc3VjY2Vzc0NvdW50OiBzdWNjZXNzUmVzdWx0cy5sZW5ndGgsXG4gICAgICAgICAgZmFpbGVkVXJsczogZXJyb3JzLm1hcCgoZSkgPT4gZS51cmwpLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBzdWNjZXNzUmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzIGEgbGlzdCBvZiBpbWFnZSBwYXRocyAtIGRvd25sb2FkIFVSTHMgYW5kIGtlZXAgbG9jYWwgcGF0aHMgYXMtaXNcbiAgICovXG4gIGFzeW5jIHByb2Nlc3NJbWFnZVBhdGhzKGltYWdlUGF0aHM6IHN0cmluZ1tdKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IGxvY2FsUGF0aHM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgdXJsc1RvRG93bmxvYWQ6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBTZXBhcmF0ZSBVUkxzIGZyb20gbG9jYWwgcGF0aHNcbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgaW1hZ2VQYXRocykge1xuICAgICAgaWYgKEltYWdlRG93bmxvYWRlci5pc0ltYWdlVXJsKHBhdGgpKSB7XG4gICAgICAgIHVybHNUb0Rvd25sb2FkLnB1c2gocGF0aCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBWYWxpZGF0ZSBsb2NhbCBwYXRoIGV4aXN0c1xuICAgICAgICBpZiAoIWV4aXN0c1N5bmMocGF0aCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoYExvY2FsIGltYWdlIGZpbGUgbm90IGZvdW5kOiAke3BhdGh9YCwge1xuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHN1Z2dlc3Rpb246ICdNYWtlIHN1cmUgdGhlIGZpbGUgcGF0aCBpcyBjb3JyZWN0IGFuZCB0aGUgZmlsZSBleGlzdHMnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGxvY2FsUGF0aHMucHVzaChwYXRoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBEb3dubG9hZCBVUkxzIGlmIGFueVxuICAgIGlmICh1cmxzVG9Eb3dubG9hZC5sZW5ndGggPiAwKSB7XG4gICAgICBsb2dnZXIuZGVidWcoYERvd25sb2FkaW5nICR7dXJsc1RvRG93bmxvYWQubGVuZ3RofSBpbWFnZXMgZnJvbSBVUkxzLi4uYCk7XG4gICAgICBjb25zdCBkb3dubG9hZFJlc3VsdHMgPSBhd2FpdCB0aGlzLmRvd25sb2FkSW1hZ2VzKHVybHNUb0Rvd25sb2FkKTtcbiAgICAgIGNvbnN0IGRvd25sb2FkZWRQYXRocyA9IGRvd25sb2FkUmVzdWx0cy5tYXAoKHIpID0+IHIubG9jYWxQYXRoKTtcbiAgICAgIGxvY2FsUGF0aHMucHVzaCguLi5kb3dubG9hZGVkUGF0aHMpO1xuXG4gICAgICAvLyBMb2cgZG93bmxvYWQgc3VtbWFyeVxuICAgICAgY29uc3QgY2FjaGVkQ291bnQgPSBkb3dubG9hZFJlc3VsdHMuZmlsdGVyKChyKSA9PiByLmNhY2hlZCkubGVuZ3RoO1xuICAgICAgY29uc3QgbmV3Q291bnQgPSBkb3dubG9hZFJlc3VsdHMuZmlsdGVyKChyKSA9PiAhci5jYWNoZWQpLmxlbmd0aDtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgRG93bmxvYWRlZCAke25ld0NvdW50fSBuZXcgaW1hZ2VzLCB1c2VkICR7Y2FjaGVkQ291bnR9IGNhY2hlZCBpbWFnZXNgKTtcbiAgICB9XG5cbiAgICBpZiAobG9jYWxQYXRocy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcignTm8gdmFsaWQgaW1hZ2VzIGZvdW5kJywge1xuICAgICAgICBwcm92aWRlZFBhdGhzOiBpbWFnZVBhdGhzLmxlbmd0aCxcbiAgICAgICAgc3VnZ2VzdGlvbjogJ1Byb3ZpZGUgYXQgbGVhc3Qgb25lIHZhbGlkIGltYWdlIFVSTCBvciBsb2NhbCBmaWxlIHBhdGgnLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxvY2FsUGF0aHM7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBzYXZlIGRpcmVjdG9yeSBwYXRoXG4gICAqL1xuICBnZXRTYXZlRGlyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2F2ZURpcjtcbiAgfVxufVxuXG4vLyBFeHBvcnQgYSBkZWZhdWx0IGluc3RhbmNlXG5sZXQgZGVmYXVsdERvd25sb2FkZXI6IEltYWdlRG93bmxvYWRlciB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW1hZ2VEb3dubG9hZGVyKHNhdmVEaXI/OiBzdHJpbmcpOiBJbWFnZURvd25sb2FkZXIge1xuICBpZiAoIWRlZmF1bHREb3dubG9hZGVyIHx8IChzYXZlRGlyICYmIGRlZmF1bHREb3dubG9hZGVyLmdldFNhdmVEaXIoKSAhPT0gc2F2ZURpcikpIHtcbiAgICBkZWZhdWx0RG93bmxvYWRlciA9IG5ldyBJbWFnZURvd25sb2FkZXIoc2F2ZURpcik7XG4gIH1cbiAgcmV0dXJuIGRlZmF1bHREb3dubG9hZGVyO1xufVxuIiwiLyoqXG4gKiBQdWJsaXNoaW5nIHNlcnZpY2UgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgUHVibGlzaEVycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBCYXNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQnJvd3Nlck1hbmFnZXIgfSBmcm9tICcuLi9icm93c2VyL2Jyb3dzZXIubWFuYWdlcic7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7IEltYWdlRG93bmxvYWRlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9pbWFnZS1kb3dubG9hZGVyJztcbmltcG9ydCB7IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLCBDT01NT05fVEVYVF9QQVRURVJOUywgQ09NTU9OX0ZJTEVfU0VMRUNUT1JTIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3NlbGVjdG9ycyc7XG5cbi8vIENvbnN0YW50cyBmb3IgdmlkZW8gcHVibGlzaGluZ1xuZXhwb3J0IGNvbnN0IFZJREVPX1RJTUVPVVRTID0ge1xuICBQQUdFX0xPQUQ6IDMwMDAsXG4gIFRBQl9TV0lUQ0g6IDIwMDAsXG4gIFZJREVPX1BST0NFU1NJTkc6IDEwMDAwLFxuICBDT05URU5UX1dBSVQ6IDEwMDAsXG4gIFVQTE9BRF9SRUFEWTogMTAwMCxcbiAgVVBMT0FEX1NUQVJUOiAzMDAwLFxuICBQUk9DRVNTSU5HX0NIRUNLOiAzMDAwLFxuICBDT01QTEVUSU9OX0NIRUNLOiAyMDAwLFxuICBQUk9DRVNTSU5HX1RJTUVPVVQ6IDEyMDAwMCwgLy8gMiBtaW51dGVzXG4gIENPTVBMRVRJT05fVElNRU9VVDogMzAwMDAwLCAvLyA1IG1pbnV0ZXNcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBTRUxFQ1RPUlMgPSB7XG4gIEZJTEVfSU5QVVQ6IENPTU1PTl9GSUxFX1NFTEVDVE9SUy5GSUxFX0lOUFVULFxuICBTVUNDRVNTX0lORElDQVRPUlM6IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLlNVQ0NFU1MsXG4gIEVSUk9SX0lORElDQVRPUlM6IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLkVSUk9SLFxuICBQUk9DRVNTSU5HX0lORElDQVRPUlM6IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLlBST0NFU1NJTkcsXG4gIENPTVBMRVRJT05fSU5ESUNBVE9SUzogW1xuICAgICcudXBsb2FkLWNvbXBsZXRlJyxcbiAgICAnLnByb2Nlc3NpbmctY29tcGxldGUnLFxuICAgICcudmlkZW8tcmVhZHknLFxuICAgICdbY2xhc3MqPVwiY29tcGxldGVcIl0nLFxuICAgICdbY2xhc3MqPVwicmVhZHlcIl0nLFxuICBdLFxuICBUT0FTVF9TRUxFQ1RPUlM6IENPTU1PTl9TVEFUVVNfU0VMRUNUT1JTLlRPQVNULFxuICBQVUJMSVNIX1BBR0VfSU5ESUNBVE9SUzogW1xuICAgICdkaXYudXBsb2FkLWNvbnRlbnQnLFxuICAgICdkaXYuc3VibWl0JyxcbiAgICAnLmNyZWF0b3ItZWRpdG9yJyxcbiAgICAnLnZpZGVvLXVwbG9hZC1jb250YWluZXInLFxuICAgICdpbnB1dFt0eXBlPVwiZmlsZVwiXScsXG4gIF0sXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgVEVYVF9QQVRURVJOUyA9IENPTU1PTl9URVhUX1BBVFRFUk5TO1xuXG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQdWJsaXNoQmFzZVNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIHByb3RlY3RlZCBpbWFnZURvd25sb2FkZXI6IEltYWdlRG93bmxvYWRlcjtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IENvbmZpZywgYnJvd3Nlck1hbmFnZXI/OiBCcm93c2VyTWFuYWdlcikge1xuICAgIHN1cGVyKGNvbmZpZywgYnJvd3Nlck1hbmFnZXIpO1xuICAgIHRoaXMuaW1hZ2VEb3dubG9hZGVyID0gbmV3IEltYWdlRG93bmxvYWRlcignLi90ZW1wX2ltYWdlcycpO1xuICB9XG5cbiAgLy8gSGVscGVyIG1ldGhvZHMgZm9yIGVsZW1lbnQgZGV0ZWN0aW9uIGFuZCB0ZXh0IG1hdGNoaW5nXG4gIHByb3RlY3RlZCBhc3luYyBmaW5kRWxlbWVudEJ5U2VsZWN0b3JzKFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgc2VsZWN0b3JzOiByZWFkb25seSBzdHJpbmdbXVxuICApOiBQcm9taXNlPGFueSB8IG51bGw+IHtcbiAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGVsZW1lbnQgd2l0aCBzZWxlY3RvcjogJHtzZWxlY3Rvcn1gKTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldEVsZW1lbnRUZXh0KGVsZW1lbnQ6IEVsZW1lbnQpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IChlbGVtZW50IGFzIGFueSkucGFnZSgpLmV2YWx1YXRlKChlbDogRWxlbWVudCkgPT4gZWwudGV4dENvbnRlbnQsIGVsZW1lbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGdldCBlbGVtZW50IHRleHQ6ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY2hlY2tUZXh0UGF0dGVybnMoXG4gICAgdGV4dDogc3RyaW5nIHwgbnVsbCxcbiAgICBwYXR0ZXJuczogcmVhZG9ubHkgc3RyaW5nW11cbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKCF0ZXh0KSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHBhdHRlcm5zLnNvbWUoKHBhdHRlcm4pID0+IHRleHQuaW5jbHVkZXMocGF0dGVybikpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgc2VsZWN0b3JzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgICBwYXR0ZXJuczogcmVhZG9ubHkgc3RyaW5nW11cbiAgKTogUHJvbWlzZTx7IGZvdW5kOiBib29sZWFuOyB0ZXh0Pzogc3RyaW5nOyBlbGVtZW50PzogYW55IH0+IHtcbiAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgdGhpcy5nZXRFbGVtZW50VGV4dChlbGVtZW50IGFzIHVua25vd24gYXMgRWxlbWVudCk7XG4gICAgICAgIGlmICh0ZXh0ICYmIChhd2FpdCB0aGlzLmNoZWNrVGV4dFBhdHRlcm5zKHRleHQsIHBhdHRlcm5zKSkpIHtcbiAgICAgICAgICByZXR1cm4geyBmb3VuZDogdHJ1ZSwgdGV4dCwgZWxlbWVudCB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGZvdW5kOiBmYWxzZSB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHdhaXRGb3JDb25kaXRpb24oXG4gICAgY29uZGl0aW9uOiAoKSA9PiBQcm9taXNlPGJvb2xlYW4+LFxuICAgIHRpbWVvdXQ6IG51bWJlcixcbiAgICBjaGVja0ludGVydmFsOiBudW1iZXIgPSAxMDAwLFxuICAgIGVycm9yTWVzc2FnZTogc3RyaW5nXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSA8IHRpbWVvdXQpIHtcbiAgICAgIGlmIChhd2FpdCBjb25kaXRpb24oKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBhd2FpdCBzbGVlcChjaGVja0ludGVydmFsKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGVycm9yTWVzc2FnZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmlsbFRpdGxlKHBhZ2U6IFBhZ2UsIHRpdGxlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBXYWl0IGZvciBhIGxpa2VseSB0aXRsZSBpbnB1dCB0byBhcHBlYXJcbiAgICB0cnkge1xuICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yU2VsZWN0b3IoXG4gICAgICAgICdpbnB1dC5jLWlucHV0X2lubmVyLCBpbnB1dC5jLWlucHV0LCBpbnB1dFtwbGFjZWhvbGRlcio9XCLmoIfpophcIl0sIC50aXRsZS1pbnB1dCBpbnB1dCwgaW5wdXRbY2xhc3MqPVwidGl0bGVcIl0nLFxuICAgICAgICB7IHRpbWVvdXQ6IDEwMDAwIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIENvbnRpbnVlIHdpdGhvdXQgd2FpdGluZyBpZiBub3QgZm91bmQgcHVyZWx5IGJ5IHNlbGVjdG9yXG4gICAgfVxuXG4gICAgY29uc3QgdGl0bGVTZWxlY3RvcnMgPSBbXG4gICAgICAnaW5wdXQuYy1pbnB1dF9pbm5lcicsIC8vIHNwZWNpZmljIGZvciByZWNlbnQgWGlhb2hvbmdzaHUgY3JlYXRvciBVSVxuICAgICAgJ2lucHV0LmMtaW5wdXQnLFxuICAgICAgJ2lucHV0W3BsYWNlaG9sZGVyKj1cIuagh+mimFwiXScsXG4gICAgICAnaW5wdXRbcGxhY2Vob2xkZXIqPVwi5aGr5YaZ5qCH6aKY5Lya5pyJ5pu05aSa6LWe5ZOmXCJdJyxcbiAgICAgICdpbnB1dFtwbGFjZWhvbGRlcio9XCJ0aXRsZVwiXScsXG4gICAgICAnaW5wdXRbZGF0YS1wbGFjZWhvbGRlcio9XCLmoIfpophcIl0nLFxuICAgICAgJy50aXRsZS1pbnB1dCBpbnB1dCcsXG4gICAgICAnaW5wdXRbcGxhY2Vob2xkZXIqPVwi6K+36L6T5YWl5qCH6aKYXCJdJyxcbiAgICAgICdpbnB1dFtuYW1lPVwidGl0bGVcIl0nLFxuICAgICAgJ2lucHV0W2lkKj1cInRpdGxlXCJdJyxcbiAgICAgICdpbnB1dFtjbGFzcyo9XCJ0aXRsZVwiXScsXG4gICAgICAnaW5wdXRbdHlwZT1cInRleHRcIl0nLCAvLyBGYWxsYmFja3NcbiAgICAgICdkaXZbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXScsXG4gICAgICAndGV4dGFyZWFbcGxhY2Vob2xkZXIqPVwi5qCH6aKYXCJdJyxcbiAgICAgICd0ZXh0YXJlYVtwbGFjZWhvbGRlcio9XCJ0aXRsZVwiXScsXG4gICAgXTtcblxuICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgdGl0bGVTZWxlY3RvcnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHRpdGxlSW5wdXQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAodGl0bGVJbnB1dCkge1xuICAgICAgICAgIC8vIFNjcm9sbCBpbnRvIHZpZXcganVzdCBpbiBjYXNlIGl0J3Mgb2ZmIHNjcmVlblxuICAgICAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgICBpZiAoZWwgJiYgdHlwZW9mIGVsLnNjcm9sbEludG9WaWV3ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIGVsLnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnLCBibG9jazogJ2NlbnRlcicgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgdGl0bGVJbnB1dCk7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcblxuICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IHRpdGxlSW5wdXQuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuXG4gICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgYXdhaXQgdGl0bGVJbnB1dC5jbGljaygpO1xuICAgICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTsgLy8gV2FpdCBmb3IgZm9jdXNcblxuICAgICAgICAgICAgLy8gY2xlYXIgZXhpc3RpbmcgaW5wdXQgaWYgYW55XG4gICAgICAgICAgICBhd2FpdCB0aXRsZUlucHV0LmNsaWNrKHsgY2xpY2tDb3VudDogMyB9KTtcbiAgICAgICAgICAgIGF3YWl0IHRpdGxlSW5wdXQucHJlc3MoJ0JhY2tzcGFjZScpO1xuXG4gICAgICAgICAgICBhd2FpdCB0aXRsZUlucHV0LnR5cGUodGl0bGUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBzZWxlY3RvclxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG5vIHNwZWNpZmljIGlucHV0IGZvdW5kLCB0cnkgdG8gZmluZCBhbnkgdmlzaWJsZSBpbnB1dCBvciB0ZXh0YXJlYSBvbiB0aGUgcGFnZVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBhbGxJbnB1dHMgPSBhd2FpdCBwYWdlLiQkKCdpbnB1dCwgdGV4dGFyZWEnKTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbGxJbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBhbGxJbnB1dHNbaV07XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC5nZXRBdHRyaWJ1dGUoJ3R5cGUnKSwgaW5wdXQpO1xuXG4gICAgICAgICAgLy8gYXZvaWQgZmlsZSBpbnB1dHMgb3IgaGlkZGVuIGlucHV0c1xuICAgICAgICAgIGlmICh0eXBlICE9PSAnZmlsZScgJiYgdHlwZSAhPT0gJ2hpZGRlbicpIHtcbiAgICAgICAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChlbCAmJiB0eXBlb2YgZWwuc2Nyb2xsSW50b1ZpZXcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBlbC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdjZW50ZXInIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCBpbnB1dCk7XG4gICAgICAgICAgICBhd2FpdCBzbGVlcCg1MDApO1xuXG4gICAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCBpbnB1dC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG5cbiAgICAgICAgICAgIGlmIChpc1Zpc2libGUpIHtcbiAgICAgICAgICAgICAgYXdhaXQgaW5wdXQuY2xpY2soKTtcbiAgICAgICAgICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcblxuICAgICAgICAgICAgICAvLyBjbGVhciBleGlzdGluZyBpbnB1dCBpZiBhbnlcbiAgICAgICAgICAgICAgYXdhaXQgaW5wdXQuY2xpY2soeyBjbGlja0NvdW50OiAzIH0pO1xuICAgICAgICAgICAgICBhd2FpdCBpbnB1dC5wcmVzcygnQmFja3NwYWNlJyk7XG5cbiAgICAgICAgICAgICAgYXdhaXQgaW5wdXQudHlwZSh0aXRsZSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBpbnB1dFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIEZhbGwgdGhyb3VnaCB0byBlcnJvclxuICAgIH1cblxuICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHRpdGxlIGlucHV0IGZpZWxkJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmluZENvbnRlbnRFbGVtZW50KHBhZ2U6IFBhZ2UpOiBQcm9taXNlPGFueSB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gU3RyYXRlZ3kgMTogVHJ5IGRpdltjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdIChzaW1wbGUgYW5kIGRpcmVjdClcbiAgICAgIGNvbnN0IGNvbnRlbnRFZGl0YWJsZSA9IGF3YWl0IHBhZ2UuJCgnZGl2W2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0nKTtcbiAgICAgIGlmIChjb250ZW50RWRpdGFibGUpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgY29udGVudEVkaXRhYmxlLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiBjb250ZW50RWRpdGFibGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgMjogVHJ5IGRpdi50aXB0YXAuUHJvc2VNaXJyb3IgKHByaW1hcnkgc2VsZWN0b3IgZm9yIGNyZWF0b3IgcGxhdGZvcm0pXG4gICAgICBjb25zdCB0aXB0YXBFZGl0b3IgPSBhd2FpdCBwYWdlLiQoJ2Rpdi50aXB0YXAuUHJvc2VNaXJyb3InKTtcbiAgICAgIGlmICh0aXB0YXBFZGl0b3IpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGlwdGFwRWRpdG9yLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiB0aXB0YXBFZGl0b3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgMzogVHJ5IGRpdltyb2xlPVwidGV4dGJveFwiXVtjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdIChzcGVjaWZpYyBzZWxlY3RvcilcbiAgICAgIGNvbnN0IHJvbGVUZXh0Ym94ID0gYXdhaXQgcGFnZS4kKCdkaXZbcm9sZT1cInRleHRib3hcIl1bY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXScpO1xuICAgICAgaWYgKHJvbGVUZXh0Ym94KSB7XG4gICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IHJvbGVUZXh0Ym94LmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgIHJldHVybiByb2xlVGV4dGJveDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSA0OiBUcnkgZGl2LnFsLWVkaXRvciAobGVnYWN5IHNlbGVjdG9yKVxuICAgICAgY29uc3QgcWxFZGl0b3IgPSBhd2FpdCBwYWdlLiQoJ2Rpdi5xbC1lZGl0b3InKTtcbiAgICAgIGlmIChxbEVkaXRvcikge1xuICAgICAgICByZXR1cm4gcWxFZGl0b3I7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDU6IFRyeSB0byBmaW5kIHRleHRhcmVhIG9yIGNvbnRlbnRlZGl0YWJsZVxuICAgICAgY29uc3QgY29udGVudFNlbGVjdG9ycyA9IFtcbiAgICAgICAgJy50aXB0YXAuUHJvc2VNaXJyb3InLFxuICAgICAgICAndGV4dGFyZWFbcGxhY2Vob2xkZXIqPVwi5q2j5paHXCJdJyxcbiAgICAgICAgJ3RleHRhcmVhW211bHRpbGluZV0nLFxuICAgICAgICAnZGl2W2RhdGEtcGxhY2Vob2xkZXIqPVwi5q2j5paHXCJdJyxcbiAgICAgICAgJy5jb250ZW50LWVkaXRvcicsXG4gICAgICAgICdkaXZbcm9sZT1cInRleHRib3hcIl0nLFxuICAgICAgICAndGV4dGJveFtyb2xlPVwidGV4dGJveFwiXScsXG4gICAgICAgICd0ZXh0Ym94W211bHRpbGluZV0nLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBjb250ZW50U2VsZWN0b3JzKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDY6IFRyeSB0byBmaW5kIGFueSBtdWx0aWxpbmUgdGV4dGJveCAoZmFsbGJhY2spXG4gICAgICBjb25zdCBtdWx0aWxpbmVUZXh0Ym94ZXMgPSBhd2FpdCBwYWdlLiQkKCd0ZXh0Ym94W211bHRpbGluZV0nKTtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBtdWx0aWxpbmVUZXh0Ym94ZXMpIHtcbiAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgZWxlbWVudC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG4gICAgICAgIGlmIChpc1Zpc2libGUpIHtcbiAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGZpbmRUZXh0Ym94QnlQbGFjZWhvbGRlcihwYWdlOiBQYWdlKTogUHJvbWlzZTxhbnkgfCBudWxsPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEZpbmQgYWxsIHAgZWxlbWVudHNcbiAgICAgIGNvbnN0IHBFbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoJ3AnKTtcblxuICAgICAgLy8gTG9vayBmb3IgZWxlbWVudCB3aXRoIGRhdGEtcGxhY2Vob2xkZXIgY29udGFpbmluZyBcIui+k+WFpeato+aWh+aPj+i/sFwiXG4gICAgICBmb3IgKGNvbnN0IHAgb2YgcEVsZW1lbnRzKSB7XG4gICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS1wbGFjZWhvbGRlcicpLCBwKTtcbiAgICAgICAgaWYgKHBsYWNlaG9sZGVyPy5pbmNsdWRlcygn6L6T5YWl5q2j5paH5o+P6L+wJykpIHtcbiAgICAgICAgICByZXR1cm4gcDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGZpbmRUZXh0Ym94UGFyZW50KHBhZ2U6IFBhZ2UsIGVsZW1lbnQ6IEVsZW1lbnQpOiBQcm9taXNlPGFueT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgcGFnZS5ldmFsdWF0ZUhhbmRsZSgoZWwpID0+IGVsLnBhcmVudEVsZW1lbnQsIGVsZW1lbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZmlsbENvbnRlbnQocGFnZTogUGFnZSwgY29udGVudDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gV2FpdCBmb3IgY29udGVudCBhcmVhIHRvIGFwcGVhclxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBwYWdlLndhaXRGb3JTZWxlY3RvcihcbiAgICAgICAgJ2Rpdltyb2xlPVwidGV4dGJveFwiXVtjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdLCAudGlwdGFwLlByb3NlTWlycm9yLCBkaXZbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSwgdGV4dGFyZWEsIFtyb2xlPVwidGV4dGJveFwiXSwgLnFsLWVkaXRvciwgdGV4dGJveFttdWx0aWxpbmVdJyxcbiAgICAgICAgeyB0aW1lb3V0OiAxMDAwMCB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBDb250aW51ZSB3aXRob3V0IHdhaXRpbmdcbiAgICB9XG5cbiAgICBsZXQgY29udGVudEVsZW1lbnQgPSBhd2FpdCB0aGlzLmZpbmRDb250ZW50RWxlbWVudChwYWdlKTtcblxuICAgIGlmICghY29udGVudEVsZW1lbnQpIHtcbiAgICAgIC8vIFRyeSBhbHRlcm5hdGl2ZSBhcHByb2FjaFxuICAgICAgY29uc3QgdGV4dGJveEVsZW1lbnQgPSBhd2FpdCB0aGlzLmZpbmRUZXh0Ym94QnlQbGFjZWhvbGRlcihwYWdlKTtcbiAgICAgIGlmICh0ZXh0Ym94RWxlbWVudCkge1xuICAgICAgICBjb250ZW50RWxlbWVudCA9IGF3YWl0IHRoaXMuZmluZFRleHRib3hQYXJlbnQocGFnZSwgdGV4dGJveEVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghY29udGVudEVsZW1lbnQpIHtcbiAgICAgIC8vIFRyeSB0byBmaW5kIGFueSBjb250ZW50ZWRpdGFibGUgb3IgdGV4dGFyZWEgZWxlbWVudFxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYWxsQ29udGVudEVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJChcbiAgICAgICAgICAnZGl2W3JvbGU9XCJ0ZXh0Ym94XCJdW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIC50aXB0YXAuUHJvc2VNaXJyb3IsIGRpdltjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdLCB0ZXh0YXJlYSwgW3JvbGU9XCJ0ZXh0Ym94XCJdLCAucWwtZWRpdG9yLCBwW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIHRleHRib3hbbXVsdGlsaW5lXSdcbiAgICAgICAgKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFsbENvbnRlbnRFbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhbGxDb250ZW50RWxlbWVudHNbaV07XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IGVsZW1lbnQuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpO1xuICAgICAgICAgICAgY29uc3QgdGFnTmFtZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiBlbC50YWdOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRFZGl0YWJsZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoXG4gICAgICAgICAgICAgIChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnKSxcbiAgICAgICAgICAgICAgZWxlbWVudFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHJvbGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdyb2xlJyksIGVsZW1lbnQpO1xuICAgICAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLmNsYXNzTmFtZSwgZWxlbWVudCk7XG4gICAgICAgICAgICBjb25zdCBtdWx0aWxpbmUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuZ2V0QXR0cmlidXRlKCdtdWx0aWxpbmUnKSwgZWxlbWVudCk7XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgaXNWaXNpYmxlICYmXG4gICAgICAgICAgICAgIChjb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyB8fFxuICAgICAgICAgICAgICAgIHRhZ05hbWUgPT09ICdURVhUQVJFQScgfHxcbiAgICAgICAgICAgICAgICByb2xlID09PSAndGV4dGJveCcgfHxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUuaW5jbHVkZXMoJ3FsLWVkaXRvcicpIHx8XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lLmluY2x1ZGVzKCd0aXB0YXAnKSB8fFxuICAgICAgICAgICAgICAgIG11bHRpbGluZSA9PT0gJycpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgY29udGVudEVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gQ29udGludWUgdG8gbmV4dCBlbGVtZW50XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBDb250aW51ZSB0byBuZXh0IHN0cmF0ZWd5XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjb250ZW50RWxlbWVudCkge1xuICAgICAgLy8gTGFzdCByZXNvcnQ6IHRyeSB0byBmaW5kIGFueSBlbGVtZW50IHRoYXQgbWlnaHQgYmUgZm9yIGNvbnRlbnRcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGFsbEVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJCgnKicpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTWF0aC5taW4oYWxsRWxlbWVudHMubGVuZ3RoLCA1MCk7IGkrKykge1xuICAgICAgICAgIC8vIExpbWl0IHRvIGZpcnN0IDUwIGVsZW1lbnRzXG4gICAgICAgICAgY29uc3QgZWxlbWVudCA9IGFsbEVsZW1lbnRzW2ldO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBpc1Zpc2libGUgPSBhd2FpdCBlbGVtZW50LmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgICAgIGNvbnN0IHRhZ05hbWUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwudGFnTmFtZSwgZWxlbWVudCk7XG4gICAgICAgICAgICBjb25zdCBjb250ZW50RWRpdGFibGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKFxuICAgICAgICAgICAgICAoZWwpID0+IGVsLmdldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJyksXG4gICAgICAgICAgICAgIGVsZW1lbnRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBjbGFzc05hbWUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4gZWwuY2xhc3NOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gYXdhaXQgcGFnZS5ldmFsdWF0ZShcbiAgICAgICAgICAgICAgKGVsKSA9PiBlbC5nZXRBdHRyaWJ1dGUoJ3BsYWNlaG9sZGVyJyksXG4gICAgICAgICAgICAgIGVsZW1lbnRcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgaXNWaXNpYmxlICYmXG4gICAgICAgICAgICAgIChjb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyB8fFxuICAgICAgICAgICAgICAgIHRhZ05hbWUgPT09ICdURVhUQVJFQScgfHxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUuaW5jbHVkZXMoJ2NvbnRlbnQnKSB8fFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZS5pbmNsdWRlcygnZWRpdG9yJykgfHxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj8uaW5jbHVkZXMoJ+WGheWuuScpIHx8XG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI/LmluY2x1ZGVzKCfmraPmlocnKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBjb250ZW50RWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzIGZvciBpbmRpdmlkdWFsIGVsZW1lbnRzXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBGYWxsIHRocm91Z2ggdG8gZXJyb3JcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWNvbnRlbnRFbGVtZW50KSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdDb3VsZCBub3QgZmluZCBjb250ZW50IGlucHV0IGZpZWxkJyk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNvbnRlbnRFbGVtZW50LmNsaWNrKCk7XG4gICAgICBhd2FpdCBzbGVlcCg1MDApOyAvLyBXYWl0IGZvciBmb2N1c1xuICAgICAgYXdhaXQgKGNvbnRlbnRFbGVtZW50IGFzIGFueSkudHlwZShjb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgRmFpbGVkIHRvIGZpbGwgY29udGVudDogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaW5wdXRUYWdzKHBhZ2U6IFBhZ2UsIGNvbnRlbnRFbGVtZW50OiBhbnksIHRhZ3M6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRhZ0xpc3QgPSB0YWdzXG4gICAgICAuc3BsaXQoJywnKVxuICAgICAgLm1hcCgodGFnKSA9PiB0YWcudHJpbSgpKVxuICAgICAgLmZpbHRlcigodGFnKSA9PiB0YWcubGVuZ3RoID4gMCk7XG5cbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdMaXN0KSB7XG4gICAgICBhd2FpdCB0aGlzLmlucHV0VGFnKHBhZ2UsIGNvbnRlbnRFbGVtZW50LCB0YWcpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBpbnB1dFRhZyhwYWdlOiBQYWdlLCBjb250ZW50RWxlbWVudDogYW55LCB0YWc6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBUeXBlIHRoZSB0YWdcbiAgICAgIGF3YWl0IGNvbnRlbnRFbGVtZW50LnR5cGUoYCMke3RhZ31gKTtcbiAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAvLyBUcnkgdG8gZmluZCB0b3BpYyBzdWdnZXN0aW9uIGNvbnRhaW5lclxuICAgICAgY29uc3QgdG9waWNDb250YWluZXIgPSBhd2FpdCBwYWdlLiQoJyNjcmVhdG9yLWVkaXRvci10b3BpYy1jb250YWluZXInKTtcblxuICAgICAgaWYgKHRvcGljQ29udGFpbmVyKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0SXRlbSA9IGF3YWl0IHRvcGljQ29udGFpbmVyLiQoJy5pdGVtJyk7XG4gICAgICAgIGlmIChmaXJzdEl0ZW0pIHtcbiAgICAgICAgICBhd2FpdCBmaXJzdEl0ZW0uY2xpY2soKTtcbiAgICAgICAgICBhd2FpdCBzbGVlcCg1MDApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBQcmVzcyBFbnRlciB0byBjb25maXJtIHRoZSB0YWdcbiAgICAgICAgYXdhaXQgY29udGVudEVsZW1lbnQucHJlc3MoJ0VudGVyJyk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDUwMCk7XG4gICAgICAgIC8vIFByZXNzIFNwYWNlIHRvIHNlcGFyYXRlIHRhZ3NcbiAgICAgICAgYXdhaXQgY29udGVudEVsZW1lbnQucHJlc3MoJ1NwYWNlJyk7XG4gICAgICAgIGF3YWl0IHNsZWVwKDIwMCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gYWRkIHRhZyAke3RhZ306ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGFkZFRhZ3MocGFnZTogUGFnZSwgdGFnczogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbnRlbnRFbGVtZW50ID0gYXdhaXQgdGhpcy5maW5kQ29udGVudEVsZW1lbnQocGFnZSk7XG4gICAgICBpZiAoY29udGVudEVsZW1lbnQpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbnB1dFRhZ3MocGFnZSwgY29udGVudEVsZW1lbnQsIHRhZ3MpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGFkZCB0YWdzOiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBzdWJtaXRQb3N0KHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgLy8gU3RyYXRlZ3kgMTogTG9vayBmb3IgdGhlIDx4aHMtcHVibGlzaC1idG4+IGN1c3RvbSBlbGVtZW50IChuZXcgWEhTIFVJKVxuICAgICAgbGV0IHN1Ym1pdEJ1dHRvbjogaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PiB8IG51bGwgPSBudWxsO1xuICAgICAgY29uc3QgY3VzdG9tQnRuID0gYXdhaXQgcGFnZS4kKCd4aHMtcHVibGlzaC1idG4nKTtcbiAgICAgIGlmIChjdXN0b21CdG4pIHtcbiAgICAgICAgLy8gVmVyaWZ5IGl0IGhhcyB0aGUgcmlnaHQgYXR0cmlidXRlcyAoaXMtcHVibGlzaD1cInRydWVcIiwgc3VibWl0LXRleHQ9XCLlj5HluINcIilcbiAgICAgICAgY29uc3QgYXR0cnMgPSBhd2FpdCBjdXN0b21CdG4uZXZhbHVhdGUoKGVsKSA9PiAoe1xuICAgICAgICAgIGlzUHVibGlzaDogZWwuZ2V0QXR0cmlidXRlKCdpcy1wdWJsaXNoJyksXG4gICAgICAgICAgc3VibWl0VGV4dDogZWwuZ2V0QXR0cmlidXRlKCdzdWJtaXQtdGV4dCcpLFxuICAgICAgICAgIHN1Ym1pdERpc2FibGVkOiBlbC5nZXRBdHRyaWJ1dGUoJ3N1Ym1pdC1kaXNhYmxlZCcpLFxuICAgICAgICB9KSk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgeGhzLXB1Ymxpc2gtYnRuIGN1c3RvbSBlbGVtZW50OiAke0pTT04uc3RyaW5naWZ5KGF0dHJzKX1gKTtcbiAgICAgICAgaWYgKGF0dHJzLmlzUHVibGlzaCA9PT0gJ3RydWUnIHx8IGF0dHJzLnN1Ym1pdFRleHQgPT09ICflj5HluIMnKSB7XG4gICAgICAgICAgc3VibWl0QnV0dG9uID0gY3VzdG9tQnRuIGFzIGltcG9ydCgncHVwcGV0ZWVyJykuRWxlbWVudEhhbmRsZTxIVE1MQnV0dG9uRWxlbWVudD47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgMjogTG9vayBmb3Igc3RhbmRhcmQgYnV0dG9uIGVsZW1lbnRzIGNvbnRhaW5pbmcgXCLlj5HluINcIlxuICAgICAgaWYgKCFzdWJtaXRCdXR0b24pIHtcbiAgICAgICAgY29uc3QgYnV0dG9ucyA9IGF3YWl0IHBhZ2UuJCQoJ2J1dHRvbicpO1xuICAgICAgICBmb3IgKGNvbnN0IGJ0biBvZiBidXR0b25zKSB7XG4gICAgICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IGJ0bi5ldmFsdWF0ZShlbCA9PiBlbC50ZXh0Q29udGVudD8udHJpbSgpKTtcbiAgICAgICAgICBpZiAodGV4dD8uaW5jbHVkZXMoJ+WPkeW4gycpKSB7XG4gICAgICAgICAgICBzdWJtaXRCdXR0b24gPSBidG4gYXMgaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIXN1Ym1pdEJ1dHRvbikge1xuICAgICAgICAvLyBTdHJhdGVneSAzOiBzZWFyY2ggYWxsIHZpc2libGUgZGl2L3NwYW4gZWxlbWVudHMgY29udGFpbmluZyBcIuWPkeW4g1wiIHRleHRcbiAgICAgICAgY29uc3QgdGV4dENhbmRpZGF0ZXMgPSBhd2FpdCBwYWdlLiQkKCdkaXYsIHNwYW4nKTtcbiAgICAgICAgZm9yIChjb25zdCBlbCBvZiB0ZXh0Q2FuZGlkYXRlcykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgZWwuZXZhbHVhdGUoZWwgPT4gZWwudGV4dENvbnRlbnQ/LnRyaW0oKSk7XG4gICAgICAgICAgICBpZiAodGV4dD8uaW5jbHVkZXMoJ+WPkeW4gycpICYmIHRleHQubGVuZ3RoIDwgMjApIHtcbiAgICAgICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgZWwuaXNJbnRlcnNlY3RpbmdWaWV3cG9ydCgpLmNhdGNoKCgpID0+IGZhbHNlKTtcbiAgICAgICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIHN1Ym1pdEJ1dHRvbiA9IGVsIGFzIGltcG9ydCgncHVwcGV0ZWVyJykuRWxlbWVudEhhbmRsZTxIVE1MQnV0dG9uRWxlbWVudD47XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIXN1Ym1pdEJ1dHRvbikge1xuICAgICAgICBjb25zdCBzdWJtaXRTZWxlY3RvciA9ICdkaXYuc3VibWl0LCAuc3VibWl0LWJ0biwgLnB1Ymxpc2gtYnRuLCBbY2xhc3MqPVwicHVibGlzaFwiXSwgW2NsYXNzKj1cImJ0bi1cIl0sIC5idG4tdGV4dCc7XG4gICAgICAgIHN1Ym1pdEJ1dHRvbiA9IGF3YWl0IHBhZ2UuJChzdWJtaXRTZWxlY3RvcikgYXMgaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PiB8IG51bGw7XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDU6IFhQYXRoIHRleHQgbWF0Y2hcbiAgICAgIGlmICghc3VibWl0QnV0dG9uKSB7XG4gICAgICAgIGNvbnN0IHB1Ymxpc2hUZXh0cyA9IFsn5Y+R5biD56yU6K6wJywgJ+WPkeW4gycsICflj5HooagnXTtcbiAgICAgICAgZm9yIChjb25zdCB0ZXh0IG9mIHB1Ymxpc2hUZXh0cykge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gYXdhaXQgKHBhZ2UgYXMgYW55KS4keChgLy8qW2NvbnRhaW5zKHRleHQoKSwgJyR7dGV4dH0nKV1gKTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGVsIG9mIGVsZW1lbnRzKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCByZWN0ID0gYXdhaXQgZWwuZXZhbHVhdGUoKGVsOiBFbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgciA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHc6IHIud2lkdGgsIGg6IHIuaGVpZ2h0IH07XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBpZiAocmVjdC53ID4gMCAmJiByZWN0LmggPiAwKSB7XG4gICAgICAgICAgICAgICAgc3VibWl0QnV0dG9uID0gZWwgYXMgaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc3VibWl0QnV0dG9uKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSA2OiBGaW5kIC5idG4tdGV4dCBzcGFuIGFuZCBjbGljayBwYXJlbnRcbiAgICAgIGlmICghc3VibWl0QnV0dG9uKSB7XG4gICAgICAgIGNvbnN0IGJ0blRleHRFbCA9IGF3YWl0IHBhZ2UuJCgnLmJ0bi10ZXh0Jyk7XG4gICAgICAgIGlmIChidG5UZXh0RWwpIHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgYnRuVGV4dEVsLmV2YWx1YXRlKGVsID0+IGVsLnRleHRDb250ZW50Py50cmltKCkpO1xuICAgICAgICAgIGlmICh0ZXh0Py5pbmNsdWRlcygn5Y+R5biDJykpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudCA9IGF3YWl0IGJ0blRleHRFbC5ldmFsdWF0ZUhhbmRsZShlbCA9PlxuICAgICAgICAgICAgICBlbC5jbG9zZXN0KCdbY2xhc3MqPVwicHVibGlzaFwiXSwgW2NsYXNzKj1cImJ0bi1cIl0nKSB8fCBlbC5wYXJlbnRFbGVtZW50XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgICAgICBzdWJtaXRCdXR0b24gPSBwYXJlbnQgYXMgaW1wb3J0KCdwdXBwZXRlZXInKS5FbGVtZW50SGFuZGxlPEhUTUxCdXR0b25FbGVtZW50PjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFzdWJtaXRCdXR0b24pIHtcbiAgICAgICAgLy8gRGVidWc6IGR1bXAga2V5IGluZm8gYWJvdXQgdGhlIHBhZ2Ugc3RhdGVcbiAgICAgICAgY29uc3QgZGVidWdJbmZvID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgICAgLy8gRmluZCBhbGwgZWxlbWVudHMgbWVudGlvbmluZyDlj5HluINcbiAgICAgICAgICBjb25zdCBwdWJsaXNoRWxlbWVudHM6IHt0YWc6IHN0cmluZzsgdGV4dDogc3RyaW5nOyBjbGFzczogc3RyaW5nOyB2aXNpYmxlOiBib29sZWFuOyByZWN0OiBzdHJpbmd9W10gPSBbXTtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcqJykuZm9yRWFjaChlbCA9PiB7XG4gICAgICAgICAgICBjb25zdCB0ZXh0ID0gZWwudGV4dENvbnRlbnQ/LnRyaW0oKTtcbiAgICAgICAgICAgIGlmICh0ZXh0Py5pbmNsdWRlcygn5Y+R5biDJykpIHtcbiAgICAgICAgICAgICAgY29uc3QgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgICBwdWJsaXNoRWxlbWVudHMucHVzaCh7XG4gICAgICAgICAgICAgICAgdGFnOiBlbC50YWdOYW1lLFxuICAgICAgICAgICAgICAgIHRleHQ6IHRleHQuc3Vic3RyaW5nKDAsIDMwKSxcbiAgICAgICAgICAgICAgICBjbGFzczogKGVsIGFzIEhUTUxFbGVtZW50KS5jbGFzc05hbWU/LnN1YnN0cmluZygwLCA4MCksXG4gICAgICAgICAgICAgICAgdmlzaWJsZTogcmVjdC53aWR0aCA+IDAgJiYgcmVjdC5oZWlnaHQgPiAwLFxuICAgICAgICAgICAgICAgIHJlY3Q6IGAke3JlY3Qud2lkdGgudG9GaXhlZCgwKX14JHtyZWN0LmhlaWdodC50b0ZpeGVkKDApfSBhdCAke3JlY3QudG9wLnRvRml4ZWQoMCl9LCR7cmVjdC5sZWZ0LnRvRml4ZWQoMCl9YCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHVybDogd2luZG93LmxvY2F0aW9uLmhyZWYsXG4gICAgICAgICAgICBib2R5SGVpZ2h0OiBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodCxcbiAgICAgICAgICAgIHZpZXdwb3J0SGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgICAgICAgICBwdWJsaXNoRWxlbWVudHM6IHB1Ymxpc2hFbGVtZW50cy5zbGljZSgwLCA0MCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBDb3VsZCBub3QgZmluZCBzdWJtaXQgYnV0dG9uLiBVUkw9JHtkZWJ1Z0luZm8udXJsfSwgYm9keT0ke2RlYnVnSW5mby5ib2R5SGVpZ2h0fSwgdnA9JHtkZWJ1Z0luZm8udmlld3BvcnRIZWlnaHR9LCBwdWJsaXNoRWxlbXM9JHtKU09OLnN0cmluZ2lmeShkZWJ1Z0luZm8ucHVibGlzaEVsZW1lbnRzKX1gKTtcbiAgICAgIH1cblxuICAgICAgLy8gUHJlLWNsaWNrIGNoZWNrczogZW5zdXJlIGJ1dHRvbiBpcyBlbmFibGVkIGFuZCBjbGlja2FibGVcbiAgICAgIGNvbnN0IGJ1dHRvblN0YXRlID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IHtcbiAgICAgICAgaWYgKCFlbCkgcmV0dXJuIHsgZXhpc3RzOiBmYWxzZSB9O1xuICAgICAgICBjb25zdCBodG1sRWwgPSBlbCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgY29uc3Qgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShodG1sRWwpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGV4aXN0czogdHJ1ZSxcbiAgICAgICAgICBkaXNhYmxlZDogaHRtbEVsLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSB8fCBodG1sRWwuZ2V0QXR0cmlidXRlKCdhcmlhLWRpc2FibGVkJykgPT09ICd0cnVlJyxcbiAgICAgICAgICBwb2ludGVyRXZlbnRzOiBzdHlsZS5wb2ludGVyRXZlbnRzLFxuICAgICAgICAgIG9wYWNpdHk6IHN0eWxlLm9wYWNpdHksXG4gICAgICAgICAgdmlzaWJpbGl0eTogc3R5bGUudmlzaWJpbGl0eSxcbiAgICAgICAgICBkaXNwbGF5OiBzdHlsZS5kaXNwbGF5LFxuICAgICAgICAgIHRhZ05hbWU6IGh0bWxFbC50YWdOYW1lLFxuICAgICAgICAgIGNsYXNzTmFtZTogaHRtbEVsLmNsYXNzTmFtZSxcbiAgICAgICAgICB0ZXh0OiBodG1sRWwudGV4dENvbnRlbnQ/LnRyaW0oKS5zdWJzdHJpbmcoMCwgMjApLFxuICAgICAgICB9O1xuICAgICAgfSwgc3VibWl0QnV0dG9uKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgU3VibWl0IGJ1dHRvbiBzdGF0ZTogJHtKU09OLnN0cmluZ2lmeShidXR0b25TdGF0ZSl9YCk7XG5cbiAgICAgIGlmIChidXR0b25TdGF0ZS5kaXNhYmxlZCkge1xuICAgICAgICBsb2dnZXIud2FybignU3VibWl0IGJ1dHRvbiBpcyBkaXNhYmxlZCAtIHB1Ymxpc2hpbmcgbWF5IGZhaWwnKTtcbiAgICAgIH1cblxuICAgICAgLy8gU2Nyb2xsIHRvIGJ1dHRvbiBiZWZvcmUgY2xpY2tpbmdcbiAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgIGlmIChlbCAmJiB0eXBlb2YgZWwuc2Nyb2xsSW50b1ZpZXcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBlbC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnaW5zdGFudCcsIGJsb2NrOiAnY2VudGVyJyB9KTtcbiAgICAgICAgfVxuICAgICAgfSwgc3VibWl0QnV0dG9uKTtcbiAgICAgIGF3YWl0IHNsZWVwKDUwMCk7XG5cbiAgICAgIC8vIEhlbHBlciB0byBjaGVjayBpZiBwdWJsaXNoIHdhcyB0cmlnZ2VyZWQgKHBhZ2UgbmF2aWdhdGluZyBhd2F5IG9yIHNob3dpbmcgc3VjY2VzcylcbiAgICAgIGNvbnN0IGlzUHVibGlzaFRyaWdnZXJlZCA9IGFzeW5jICgpOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50VXJsID0gcGFnZS51cmwoKTtcbiAgICAgICAgICBjb25zdCBib2R5VGV4dCA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gZG9jdW1lbnQuYm9keT8udGV4dENvbnRlbnQgfHwgJycpO1xuICAgICAgICAgIHJldHVybiAhY3VycmVudFVybC5pbmNsdWRlcygnL3B1Ymxpc2gvcHVibGlzaCcpIHx8XG4gICAgICAgICAgICBib2R5VGV4dC5pbmNsdWRlcygn5Y+R5biD5oiQ5YqfJykgfHxcbiAgICAgICAgICAgIGJvZHlUZXh0LmluY2x1ZGVzKCflrqHmoLjkuK0nKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBTdHJhdGVneSBBOiBGb3IgeGhzLXB1Ymxpc2gtYnRuIGN1c3RvbSBlbGVtZW50LCBkaXNwYXRjaCBhIEN1c3RvbUV2ZW50KCdwdWJsaXNoJylcbiAgICAgIGNvbnN0IGlzQ3VzdG9tRWxlbWVudCA9IGF3YWl0IHN1Ym1pdEJ1dHRvbi5ldmFsdWF0ZSgoZWwpID0+IGVsLnRhZ05hbWUgPT09ICdYSFMtUFVCTElTSC1CVE4nKTtcbiAgICAgIGlmIChpc0N1c3RvbUVsZW1lbnQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBwYWdlLmV2YWx1YXRlKChlbCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoJ3B1Ymxpc2gnLCB7IGJ1YmJsZXM6IHRydWUsIGNvbXBvc2VkOiB0cnVlIH0pKTtcbiAgICAgICAgICB9LCBzdWJtaXRCdXR0b24pO1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnRGlzcGF0Y2hlZCBDdXN0b21FdmVudChcInB1Ymxpc2hcIikgb24geGhzLXB1Ymxpc2gtYnRuJyk7XG4gICAgICAgIH0gY2F0Y2ggKGN1c3RvbUV2ZW50RXJyb3IpIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoYEN1c3RvbUV2ZW50IGRpc3BhdGNoIGZhaWxlZDogJHtjdXN0b21FdmVudEVycm9yfWApO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKDE1MDApO1xuICAgICAgICBpZiAoYXdhaXQgaXNQdWJsaXNoVHJpZ2dlcmVkKCkpIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgQjogRnVsbCBSZWFjdCBldmVudCBjaGFpbiB2aWEgZXZhbHVhdGUgKGZhbGxiYWNrIGZvciBzdGFuZGFyZCBlbGVtZW50cylcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgICAgICAgIGNvbnN0IGh0bWxFbCA9IGVsIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgIGNvbnN0IHJlY3QgPSBodG1sRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgY29uc3QgeCA9IHJlY3QubGVmdCArIHJlY3Qud2lkdGggLyAyO1xuICAgICAgICAgIGNvbnN0IHkgPSByZWN0LnRvcCArIHJlY3QuaGVpZ2h0IC8gMjtcbiAgICAgICAgICBjb25zdCBldmVudEluaXQgPSB7IGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibGU6IHRydWUsIGNvbXBvc2VkOiB0cnVlLCBjbGllbnRYOiB4LCBjbGllbnRZOiB5LCBzY3JlZW5YOiB4LCBzY3JlZW5ZOiB5IH07XG4gICAgICAgICAgY29uc3QgZXZlbnRzID0gW1xuICAgICAgICAgICAgbmV3IE1vdXNlRXZlbnQoJ21vdXNlZW50ZXInLCBldmVudEluaXQpLFxuICAgICAgICAgICAgbmV3IE1vdXNlRXZlbnQoJ21vdXNlb3ZlcicsIGV2ZW50SW5pdCksXG4gICAgICAgICAgICBuZXcgTW91c2VFdmVudCgnbW91c2Vtb3ZlJywgZXZlbnRJbml0KSxcbiAgICAgICAgICAgIG5ldyBNb3VzZUV2ZW50KCdtb3VzZWRvd24nLCB7IC4uLmV2ZW50SW5pdCwgYnV0dG9uOiAwLCBidXR0b25zOiAxIH0pLFxuICAgICAgICAgICAgbmV3IEZvY3VzRXZlbnQoJ2ZvY3VzJywgeyBidWJibGVzOiB0cnVlIH0pLFxuICAgICAgICAgICAgbmV3IE1vdXNlRXZlbnQoJ21vdXNldXAnLCB7IC4uLmV2ZW50SW5pdCwgYnV0dG9uOiAwLCBidXR0b25zOiAwIH0pLFxuICAgICAgICAgICAgbmV3IE1vdXNlRXZlbnQoJ2NsaWNrJywgeyAuLi5ldmVudEluaXQsIGJ1dHRvbjogMCwgYnV0dG9uczogMCB9KSxcbiAgICAgICAgICBdO1xuICAgICAgICAgIGV2ZW50cy5mb3JFYWNoKChldikgPT4gaHRtbEVsLmRpc3BhdGNoRXZlbnQoZXYpKTtcbiAgICAgICAgfSwgc3VibWl0QnV0dG9uKTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdEaXNwYXRjaGVkIGZ1bGwgUmVhY3QgZXZlbnQgY2hhaW4gb24gc3VibWl0IGJ1dHRvbicpO1xuICAgICAgfSBjYXRjaCAoY2hhaW5FcnJvcikge1xuICAgICAgICBsb2dnZXIuZGVidWcoYFJlYWN0IGV2ZW50IGNoYWluIGZhaWxlZDogJHtjaGFpbkVycm9yfWApO1xuICAgICAgfVxuICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG4gICAgICBpZiAoYXdhaXQgaXNQdWJsaXNoVHJpZ2dlcmVkKCkpIHJldHVybjtcblxuICAgICAgLy8gU3RyYXRlZ3kgQzogUHVwcGV0ZWVyIG5hdGl2ZSBjbGljayBhcyBmYWxsYmFja1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc3VibWl0QnV0dG9uLmNsaWNrKCk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnQ2xpY2tlZCBzdWJtaXQgYnV0dG9uIHZpYSBQdXBwZXRlZXIgbmF0aXZlIGNsaWNrJyk7XG4gICAgICB9IGNhdGNoIChjbGlja0Vycm9yKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgUHVwcGV0ZWVyIGNsaWNrIGZhaWxlZDogJHtjbGlja0Vycm9yfWApO1xuICAgICAgfVxuICAgICAgYXdhaXQgc2xlZXAoODAwKTtcbiAgICAgIGlmIChhd2FpdCBpc1B1Ymxpc2hUcmlnZ2VyZWQoKSkgcmV0dXJuO1xuXG4gICAgICAvLyBTdHJhdGVneSBEOiBKYXZhU2NyaXB0IGNsaWNrIHZpYSBldmFsdWF0ZVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IHsgaWYgKGVsKSAoZWwgYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7IH0sIHN1Ym1pdEJ1dHRvbik7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnQ2xpY2tlZCBzdWJtaXQgYnV0dG9uIHZpYSBKUyBldmFsdWF0ZSBjbGljaycpO1xuICAgICAgfSBjYXRjaCAoanNDbGlja0Vycm9yKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgSlMgZXZhbHVhdGUgY2xpY2sgZmFpbGVkOiAke2pzQ2xpY2tFcnJvcn1gKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHNsZWVwKDgwMCk7XG4gICAgICBpZiAoYXdhaXQgaXNQdWJsaXNoVHJpZ2dlcmVkKCkpIHJldHVybjtcblxuICAgICAgLy8gU3RyYXRlZ3kgRTogVHJ5IGNsaWNraW5nIHZpYSBwYWdlLm1vdXNlIGF0IGVsZW1lbnQgY2VudGVyIGNvb3JkaW5hdGVzXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBib3ggPSBhd2FpdCBzdWJtaXRCdXR0b24uYm91bmRpbmdCb3goKTtcbiAgICAgICAgaWYgKGJveCkge1xuICAgICAgICAgIGF3YWl0IHBhZ2UubW91c2UubW92ZShib3gueCArIGJveC53aWR0aCAvIDIsIGJveC55ICsgYm94LmhlaWdodCAvIDIpO1xuICAgICAgICAgIGF3YWl0IHBhZ2UubW91c2UuZG93bigpO1xuICAgICAgICAgIGF3YWl0IHNsZWVwKDUwKTtcbiAgICAgICAgICBhd2FpdCBwYWdlLm1vdXNlLnVwKCk7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdDbGlja2VkIHN1Ym1pdCBidXR0b24gdmlhIG1vdXNlIGNvb3JkaW5hdGVzJyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKG1vdXNlRXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBNb3VzZSBjbGljayBmYWlsZWQ6ICR7bW91c2VFcnJvcn1gKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHNsZWVwKDE1MDApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBGYWlsZWQgdG8gY2xpY2sgc3VibWl0IGJ1dHRvbjogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaXNFbGVtZW50VmlzaWJsZShlbGVtZW50OiBFbGVtZW50KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCAoZWxlbWVudCBhcyBhbnkpLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB3YWl0Rm9yUHVibGlzaENvbXBsZXRpb24ocGFnZTogUGFnZSk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGNvbnN0IG1heFdhaXRUaW1lID0gMzAwMDA7IC8vIDMwIHNlY29uZHMgKHJlZHVjZWQgZnJvbSA2MHMpXG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBwdWJsaXNoU3RhcnRVcmwgPSBwYWdlLnVybCgpO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCBtYXhXYWl0VGltZSkge1xuICAgICAgY29uc3QgY3VycmVudFVybCA9IHBhZ2UudXJsKCk7XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDE6IENoZWNrIGZvciBzdWNjZXNzIGluZGljYXRvcnMgdmlhIENTUyBzZWxlY3RvcnNcbiAgICAgIGNvbnN0IHN1Y2Nlc3NJbmRpY2F0b3JzID0gW1xuICAgICAgICAnLnN1Y2Nlc3MtbWVzc2FnZScsXG4gICAgICAgICcucHVibGlzaC1zdWNjZXNzJyxcbiAgICAgICAgJ1tkYXRhLXRlc3RpZD1cInB1Ymxpc2gtc3VjY2Vzc1wiXScsXG4gICAgICAgICcudG9hc3Qtc3VjY2VzcycsXG4gICAgICBdO1xuXG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHN1Y2Nlc3NJbmRpY2F0b3JzKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgc3VjY2VzcyBpbmRpY2F0b3I6ICR7c2VsZWN0b3J9YCk7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDI6IENoZWNrIGZvciBlcnJvciBpbmRpY2F0b3JzXG4gICAgICBjb25zdCBlcnJvckluZGljYXRvcnMgPSBbXG4gICAgICAgICcuZXJyb3ItbWVzc2FnZScsXG4gICAgICAgICcucHVibGlzaC1lcnJvcicsXG4gICAgICAgICdbZGF0YS10ZXN0aWQ9XCJwdWJsaXNoLWVycm9yXCJdJyxcbiAgICAgICAgJy50b2FzdC1lcnJvcicsXG4gICAgICAgICcuZXJyb3ItdG9hc3QnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBlcnJvckluZGljYXRvcnMpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JUZXh0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLnRleHRDb250ZW50LCBlbGVtZW50KTtcbiAgICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBQdWJsaXNoIGZhaWxlZCB3aXRoIGVycm9yOiAke2Vycm9yVGV4dH1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSAzOiBDaGVjayBpZiB3ZSdyZSBzdGlsbCBvbiB0aGUgcHVibGlzaCBwYWdlXG4gICAgICBjb25zdCBwdWJsaXNoUGFnZUluZGljYXRvcnMgPSBbJ2Rpdi51cGxvYWQtY29udGVudCcsICdkaXYuc3VibWl0JywgJy5jcmVhdG9yLWVkaXRvciddO1xuXG4gICAgICBsZXQgc3RpbGxPblB1Ymxpc2hQYWdlID0gZmFsc2U7XG4gICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHB1Ymxpc2hQYWdlSW5kaWNhdG9ycykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICBzdGlsbE9uUHVibGlzaFBhZ2UgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghc3RpbGxPblB1Ymxpc2hQYWdlKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnTGVmdCBwdWJsaXNoIHBhZ2UsIGFzc3VtaW5nIHN1Y2Nlc3MnKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSA0OiBDaGVjayBmb3IgdG9hc3QvcG9wdXAgbWVzc2FnZXMgd2l0aCB0ZXh0IGNvbnRlbnRcbiAgICAgIGNvbnN0IHRvYXN0U2VsZWN0b3JzID0gWycudG9hc3QnLCAnLm1lc3NhZ2UnLCAnLm5vdGlmaWNhdGlvbicsICdbcm9sZT1cImFsZXJ0XCJdJ107XG5cbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgdG9hc3RTZWxlY3RvcnMpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgY29uc3QgdG9hc3RUZXh0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLnRleHRDb250ZW50LCBlbGVtZW50KTtcbiAgICAgICAgICBpZiAodG9hc3RUZXh0KSB7XG4gICAgICAgICAgICBpZiAodG9hc3RUZXh0LmluY2x1ZGVzKCfmiJDlip8nKSB8fCB0b2FzdFRleHQuaW5jbHVkZXMoJ3N1Y2Nlc3MnKSkge1xuICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIHN1Y2Nlc3MgdG9hc3Q6ICR7dG9hc3RUZXh0fWApO1xuICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5leHRyYWN0Tm90ZUlkRnJvbVBhZ2UocGFnZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICB0b2FzdFRleHQuaW5jbHVkZXMoJ+Wksei0pScpIHx8XG4gICAgICAgICAgICAgIHRvYXN0VGV4dC5pbmNsdWRlcygnZXJyb3InKSB8fFxuICAgICAgICAgICAgICB0b2FzdFRleHQuaW5jbHVkZXMoJ+mUmeivrycpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgUHVibGlzaCBmYWlsZWQ6ICR7dG9hc3RUZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTdHJhdGVneSA1OiBCcm9hZCB0ZXh0LWJhc2VkIHN1Y2Nlc3MgZGV0ZWN0aW9uXG4gICAgICBjb25zdCB0ZXh0U3VjY2Vzc0VsZW1lbnRzID0gYXdhaXQgcGFnZS4kJCgnZGl2LCBzcGFuLCBwLCBoMSwgaDIsIGgzLCBidXR0b24nKTtcbiAgICAgIGZvciAoY29uc3QgZWwgb2YgdGV4dFN1Y2Nlc3NFbGVtZW50cykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCBlbC5ldmFsdWF0ZSgoZSkgPT4gZS50ZXh0Q29udGVudD8udHJpbSgpKTtcbiAgICAgICAgICBpZiAodGV4dCAmJiB0ZXh0Lmxlbmd0aCA8IDUwKSB7XG4gICAgICAgICAgICBpZiAodGV4dC5pbmNsdWRlcygn5Y+R5biD5oiQ5YqfJykgfHwgdGV4dC5pbmNsdWRlcygn5oqV56i/5oiQ5YqfJykgfHwgdGV4dC5pbmNsdWRlcygn5a6h5qC45LitJykpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCB0ZXh0IHN1Y2Nlc3MgaW5kaWNhdG9yOiAke3RleHR9YCk7XG4gICAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmV4dHJhY3ROb3RlSWRGcm9tUGFnZShwYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0ZXh0LmluY2x1ZGVzKCflj5HluIPlpLHotKUnKSB8fCB0ZXh0LmluY2x1ZGVzKCfmipXnqL/lpLHotKUnKSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBQdWJsaXNoIGZhaWxlZDogJHt0ZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU3RyYXRlZ3kgNjogVVJMIGNoYW5nZSBkZXRlY3Rpb24gKG5hdmlnYXRlZCBhd2F5IGZyb20gcHVibGlzaCBwYWdlKVxuICAgICAgaWYgKGN1cnJlbnRVcmwgIT09IHB1Ymxpc2hTdGFydFVybCkge1xuICAgICAgICBjb25zdCBpc1B1Ymxpc2hVcmwgPSBjdXJyZW50VXJsLmluY2x1ZGVzKCcvcHVibGlzaCcpIHx8IGN1cnJlbnRVcmwuaW5jbHVkZXMoJy9jcmVhdG9yJyk7XG4gICAgICAgIGlmICghaXNQdWJsaXNoVXJsKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBVUkwgY2hhbmdlZCBmcm9tIHB1Ymxpc2ggcGFnZSB0byAke2N1cnJlbnRVcmx9LCBhc3N1bWluZyBzdWNjZXNzYCk7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFN0cmF0ZWd5IDc6IENoZWNrIGZvciBsb2FkaW5nL3N1Y2Nlc3Mgb3ZlcmxheXNcbiAgICAgIGNvbnN0IG92ZXJsYXlTZWxlY3RvcnMgPSBbJy5tb2RhbCcsICcucG9wdXAnLCAnLmRpYWxvZycsICcub3ZlcmxheScsICdbY2xhc3MqPVwic3VjY2Vzc1wiXScsICdbY2xhc3MqPVwibW9kYWxcIl0nXTtcbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygb3ZlcmxheVNlbGVjdG9ycykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgZWxlbWVudC5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCkuY2F0Y2goKCkgPT4gZmFsc2UpO1xuICAgICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgZWxlbWVudC5ldmFsdWF0ZSgoZSkgPT4gZS50ZXh0Q29udGVudD8udHJpbSgpKTtcbiAgICAgICAgICAgICAgaWYgKHRleHQgJiYgKHRleHQuaW5jbHVkZXMoJ+aIkOWKnycpIHx8IHRleHQuaW5jbHVkZXMoJ+WPkeW4gycpKSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgb3ZlcmxheSB3aXRoIHN1Y2Nlc3MgdGV4dDogJHt0ZXh0LnN1YnN0cmluZygwLCA1MCl9YCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2UpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYXdhaXQgc2xlZXAoODAwKTsgLy8gV2FpdCBiZWZvcmUgbmV4dCBjaGVja1xuICAgIH1cblxuICAgIC8vIFRpbWVvdXQ6IGNvbGxlY3QgZGVidWcgaW5mb1xuICAgIGNvbnN0IGRlYnVnSW5mbyA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgY29uc3QgYWxsVGV4dHM6IHN0cmluZ1tdID0gW107XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdkaXYsIHNwYW4sIHAsIGgxLCBoMiwgaDMsIGJ1dHRvbicpLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBlbC50ZXh0Q29udGVudD8udHJpbSgpO1xuICAgICAgICBpZiAodGV4dCAmJiB0ZXh0Lmxlbmd0aCA+IDAgJiYgdGV4dC5sZW5ndGggPCAxMDApIHtcbiAgICAgICAgICBhbGxUZXh0cy5wdXNoKHRleHQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHVybDogd2luZG93LmxvY2F0aW9uLmhyZWYsXG4gICAgICAgIGJvZHlUZXh0OiBkb2N1bWVudC5ib2R5Py50ZXh0Q29udGVudD8uc3Vic3RyaW5nKDAsIDUwMCkgfHwgJycsXG4gICAgICAgIHZpc2libGVUZXh0czogYWxsVGV4dHMuZmlsdGVyKCh0LCBpLCBhcnIpID0+IGFyci5pbmRleE9mKHQpID09PSBpKS5zbGljZSgwLCAzMCksXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgbG9nZ2VyLmRlYnVnKGBQdWJsaXNoIHRpbWVvdXQgZGVidWcgLSBVUkw6ICR7ZGVidWdJbmZvLnVybH1gKTtcbiAgICBsb2dnZXIuZGVidWcoYFZpc2libGUgdGV4dHM6ICR7ZGVidWdJbmZvLnZpc2libGVUZXh0cy5qb2luKCcgfCAnKX1gKTtcblxuICAgIC8vIENoZWNrIGlmIHBhZ2UgbGVmdCBwdWJsaXNoIFVSTCAoZXZlbiBpZiBub3QgZGV0ZWN0ZWQgZWFybGllcikgLSBhc3N1bWUgc3VjY2Vzc1xuICAgIGNvbnN0IGlzU3RpbGxPblB1Ymxpc2hVcmwgPSBkZWJ1Z0luZm8udXJsLmluY2x1ZGVzKCcvcHVibGlzaCcpO1xuICAgIGNvbnN0IGhhc0Vycm9yVGV4dCA9IGRlYnVnSW5mby52aXNpYmxlVGV4dHMuc29tZShcbiAgICAgICh0KSA9PiB0LmluY2x1ZGVzKCflpLHotKUnKSB8fCB0LmluY2x1ZGVzKCfplJnor68nKSB8fCB0LmluY2x1ZGVzKCdlcnJvcicpIHx8IHQuaW5jbHVkZXMoJ+aXoOazlScpXG4gICAgKTtcblxuICAgIGlmICghaXNTdGlsbE9uUHVibGlzaFVybCB8fCAhaGFzRXJyb3JUZXh0KSB7XG4gICAgICBsb2dnZXIud2FybihgUHVibGlzaCBjb21wbGV0aW9uIHRpbWVkIG91dCBidXQgbm8gZXJyb3IgZGV0ZWN0ZWQuIEFzc3VtaW5nIHN1Y2Nlc3MuIFVSTD0ke2RlYnVnSW5mby51cmx9YCk7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5leHRyYWN0Tm90ZUlkRnJvbVBhZ2UocGFnZSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihcbiAgICAgIGBQdWJsaXNoIGNvbXBsZXRpb24gdGltZW91dCAtIGNvdWxkIG5vdCBkZXRlcm1pbmUgcmVzdWx0LiBVUkw9JHtkZWJ1Z0luZm8udXJsfSwgdGV4dHM9JHtkZWJ1Z0luZm8udmlzaWJsZVRleHRzLmpvaW4oJywgJykuc3Vic3RyaW5nKDAsIDIwMCl9YFxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZXh0cmFjdE5vdGVJZEZyb21QYWdlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gTWV0aG9kIDE6IFRyeSB0byBleHRyYWN0IGZyb20gVVJMIGlmIHJlZGlyZWN0ZWQgdG8gbm90ZSBwYWdlXG4gICAgICBjb25zdCBjdXJyZW50VXJsID0gcGFnZS51cmwoKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ3VycmVudCBVUkwgYWZ0ZXIgcHVibGlzaDogJHtjdXJyZW50VXJsfWApO1xuXG4gICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiBhIG5vdGUgcGFnZSAoVVJMIGNvbnRhaW5zIC9leHBsb3JlLyBvciAvZGlzY292ZXJ5LylcbiAgICAgIGNvbnN0IG5vdGVJZE1hdGNoID0gY3VycmVudFVybC5tYXRjaCgvXFwvZXhwbG9yZVxcLyhbYS1mMC05XSspL2kpIHx8XG4gICAgICAgIGN1cnJlbnRVcmwubWF0Y2goL1xcL2Rpc2NvdmVyeVxcLyhbYS1mMC05XSspL2kpO1xuXG4gICAgICBpZiAobm90ZUlkTWF0Y2ggJiYgbm90ZUlkTWF0Y2hbMV0pIHtcbiAgICAgICAgY29uc3Qgbm90ZUlkID0gbm90ZUlkTWF0Y2hbMV07XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgRXh0cmFjdGVkIG5vdGUgSUQgZnJvbSBVUkw6ICR7bm90ZUlkfWApO1xuICAgICAgICByZXR1cm4gbm90ZUlkO1xuICAgICAgfVxuXG4gICAgICAvLyBNZXRob2QgMjogVHJ5IHRvIGZpbmQgbm90ZSBJRCBpbiBwYWdlIGNvbnRlbnQgb3IgZGF0YSBhdHRyaWJ1dGVzXG4gICAgICBjb25zdCBub3RlSWRGcm9tUGFnZSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4ge1xuICAgICAgICAvLyBMb29rIGZvciBkYXRhIGF0dHJpYnV0ZXMgdGhhdCBtaWdodCBjb250YWluIG5vdGUgSURcbiAgICAgICAgY29uc3QgZWxlbWVudHNXaXRoRGF0YSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLW5vdGUtaWRdLCBbZGF0YS1pZF0sIFtkYXRhLWltcHJlc3Npb25dJyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHNXaXRoRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbGVtZW50c1dpdGhEYXRhW2ldO1xuICAgICAgICAgIGNvbnN0IG5vdGVJZCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLW5vdGUtaWQnKSB8fFxuICAgICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSB8fFxuICAgICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaW1wcmVzc2lvbicpO1xuICAgICAgICAgIGlmIChub3RlSWQgJiYgbm90ZUlkLmxlbmd0aCA+IDEwKSB7IC8vIE5vdGUgSURzIGFyZSB0eXBpY2FsbHkgbG9uZ1xuICAgICAgICAgICAgcmV0dXJuIG5vdGVJZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb29rIGZvciBsaW5rcyB0byBub3RlIHBhZ2VzXG4gICAgICAgIGNvbnN0IG5vdGVMaW5rcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2FbaHJlZio9XCIvZXhwbG9yZS9cIl0sIGFbaHJlZio9XCIvZGlzY292ZXJ5L1wiXScpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vdGVMaW5rcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGxpbmsgPSBub3RlTGlua3NbaV07XG4gICAgICAgICAgY29uc3QgaHJlZiA9IGxpbmsuZ2V0QXR0cmlidXRlKCdocmVmJyk7XG4gICAgICAgICAgaWYgKGhyZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gaHJlZi5tYXRjaCgvXFwvZXhwbG9yZVxcLyhbYS1mMC05XSspL2kpIHx8XG4gICAgICAgICAgICAgIGhyZWYubWF0Y2goL1xcL2Rpc2NvdmVyeVxcLyhbYS1mMC05XSspL2kpO1xuICAgICAgICAgICAgaWYgKG1hdGNoICYmIG1hdGNoWzFdKSB7XG4gICAgICAgICAgICAgIHJldHVybiBtYXRjaFsxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb29rIGZvciBhbnkgdGV4dCB0aGF0IGxvb2tzIGxpa2UgYSBub3RlIElEIChsb25nIGhleCBzdHJpbmcpXG4gICAgICAgIGNvbnN0IHRleHRDb250ZW50ID0gZG9jdW1lbnQuYm9keS50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgY29uc3Qgbm90ZUlkUGF0dGVybiA9IC9bYS1mMC05XXsyMCx9L2dpO1xuICAgICAgICBjb25zdCBtYXRjaGVzID0gdGV4dENvbnRlbnQubWF0Y2gobm90ZUlkUGF0dGVybik7XG4gICAgICAgIGlmIChtYXRjaGVzICYmIG1hdGNoZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIC8vIFJldHVybiB0aGUgZmlyc3QgbG9uZyBoZXggc3RyaW5nIGZvdW5kXG4gICAgICAgICAgcmV0dXJuIG1hdGNoZXNbMF07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAobm90ZUlkRnJvbVBhZ2UpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBFeHRyYWN0ZWQgbm90ZSBJRCBmcm9tIHBhZ2UgY29udGVudDogJHtub3RlSWRGcm9tUGFnZX1gKTtcbiAgICAgICAgcmV0dXJuIG5vdGVJZEZyb21QYWdlO1xuICAgICAgfVxuXG4gICAgICAvLyBNZXRob2QgMzogVHJ5IHRvIGdldCB0aGUgbGF0ZXN0IG5vdGUgSUQgdXNpbmcgTm90ZVNlcnZpY2UgKGZhbGxiYWNrKVxuICAgICAgbG9nZ2VyLmRlYnVnKCdDb3VsZCBub3QgZXh0cmFjdCBub3RlIElEIGZyb20gcGFnZSwgdHJ5aW5nIGZhbGxiYWNrIG1ldGhvZCcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gV2FpdCBhIGJpdCBmb3IgdGhlIG5vdGUgdG8gYmUgcHJvY2Vzc2VkXG4gICAgICAgIGF3YWl0IHNsZWVwKDUwMDApO1xuXG4gICAgICAgIC8vIFVzZSBOb3RlU2VydmljZSB0byBnZXQgdGhlIGxhdGVzdCBub3RlIElEXG4gICAgICAgIGNvbnN0IHsgTm90ZVNlcnZpY2UgfSA9IGF3YWl0IGltcG9ydCgnLi4vbm90ZXMvbm90ZS5zZXJ2aWNlJyk7XG4gICAgICAgIGNvbnN0IG5vdGVTZXJ2aWNlID0gbmV3IE5vdGVTZXJ2aWNlKHRoaXMuZ2V0Q29uZmlnKCkpO1xuICAgICAgICBjb25zdCB1c2VyTm90ZXMgPSBhd2FpdCBub3RlU2VydmljZS5nZXRVc2VyTm90ZXMoMSk7IC8vIEdldCBvbmx5IHRoZSBsYXRlc3Qgbm90ZVxuXG4gICAgICAgIGlmICh1c2VyTm90ZXMuc3VjY2VzcyAmJiB1c2VyTm90ZXMuZGF0YSAmJiB1c2VyTm90ZXMuZGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgbGF0ZXN0Tm90ZUlkID0gdXNlck5vdGVzLmRhdGFbMF0uaWQ7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBFeHRyYWN0ZWQgbm90ZSBJRCBmcm9tIE5vdGVTZXJ2aWNlOiAke2xhdGVzdE5vdGVJZH1gKTtcbiAgICAgICAgICByZXR1cm4gbGF0ZXN0Tm90ZUlkO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihgRmFsbGJhY2sgbm90ZSBJRCBleHRyYWN0aW9uIGZhaWxlZDogJHtlcnJvcn1gKTtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmRlYnVnKCdDb3VsZCBub3QgZXh0cmFjdCBub3RlIElEIGZyb20gYW55IG1ldGhvZCcpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gZXh0cmFjdCBub3RlIElEOiAke2Vycm9yfWApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG59IiwiaW1wb3J0IHsgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkLCBnZXRUaXRsZVdpZHRoIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3RpdGxlLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IFB1Ymxpc2hSZXN1bHQgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgUHVibGlzaEVycm9yLCBJbnZhbGlkSW1hZ2VFcnJvciB9IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCBzdGF0U3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IFB1Ymxpc2hCYXNlU2VydmljZSB9IGZyb20gJy4vcHVibGlzaC1iYXNlLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgSW1hZ2VQdWJsaXNoU2VydmljZSBleHRlbmRzIFB1Ymxpc2hCYXNlU2VydmljZSB7XG4gIGFzeW5jIHB1Ymxpc2hOb3RlKFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIGltYWdlUGF0aHM6IHN0cmluZ1tdLFxuICAgIHRhZ3M6IHN0cmluZyA9ICcnLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8UHVibGlzaFJlc3VsdD4ge1xuICAgIC8vIFZhbGlkYXRlIGlucHV0c1xuICAgIGlmICghdGl0bGU/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignTm90ZSB0aXRsZSBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSB0aXRsZSB3aWR0aCAoQ0pLIGNoYXJhY3RlcnMgY291bnQgYXMgMiB1bml0cywgQVNDSUkgYXMgMSlcbiAgICBhc3NlcnRUaXRsZVdpZHRoVmFsaWQodGl0bGUpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgVGl0bGUgd2lkdGggdmFsaWRhdGlvbiBwYXNzZWQ6IFwiJHt0aXRsZX1cIiAoJHtnZXRUaXRsZVdpZHRoKHRpdGxlKX0gdW5pdHMpYCk7XG5cbiAgICBpZiAoIWNvbnRlbnQ/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignTm90ZSBjb250ZW50IGNhbm5vdCBiZSBlbXB0eScpO1xuICAgIH1cblxuICAgIGlmICghaW1hZ2VQYXRocyB8fCBpbWFnZVBhdGhzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQXQgbGVhc3Qgb25lIGltYWdlIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgLy8gUHJvY2VzcyBpbWFnZSBwYXRocyAtIGRvd25sb2FkIFVSTHMgYW5kIHZhbGlkYXRlIGxvY2FsIHBhdGhzXG4gICAgY29uc3QgcmVzb2x2ZWRQYXRocyA9IGF3YWl0IHRoaXMudmFsaWRhdGVBbmRSZXNvbHZlSW1hZ2VQYXRocyhpbWFnZVBhdGhzKTtcblxuICAgIC8vIFdhaXQgZm9yIHVwbG9hZCBjb250YWluZXIgc2VsZWN0b3JcbiAgICBjb25zdCB1cGxvYWRTZWxlY3RvciA9ICdkaXYudXBsb2FkLWNvbnRlbnQnO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZShmYWxzZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICB0aGlzLmdldENvbmZpZygpLnhocy5jcmVhdG9yUHVibGlzaFVybFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHBhZ2UgdG8gbG9hZFxuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcblxuICAgICAgICAvLyBGaXJzdCwgdHJ5IHRvIHN3aXRjaCB0byB0aGUgaW1hZ2UvdGV4dCB1cGxvYWQgdGFiXG4gICAgICAgIGF3YWl0IHRoaXMuY2xpY2tVcGxvYWRUYWIocGFnZSk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgdGFiIHN3aXRjaCB0byBjb21wbGV0ZVxuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcblxuICAgICAgICBsZXQgaGFzVXBsb2FkQ29udGFpbmVyID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLnRyeVdhaXRGb3JTZWxlY3RvcihcbiAgICAgICAgICBwYWdlLFxuICAgICAgICAgIHVwbG9hZFNlbGVjdG9yLFxuICAgICAgICAgIDMwMDAwXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKCFoYXNVcGxvYWRDb250YWluZXIpIHtcbiAgICAgICAgICAvLyBUcnkgYWx0ZXJuYXRpdmUgc2VsZWN0b3JzIGZvciB1cGxvYWQgY29udGFpbmVyXG4gICAgICAgICAgY29uc3QgYWx0ZXJuYXRpdmVTZWxlY3RvcnMgPSBbXG4gICAgICAgICAgICAnZGl2LnVwbG9hZC1jb250ZW50JyxcbiAgICAgICAgICAgICcudXBsb2FkLWNvbnRlbnQnLFxuICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJ1cGxvYWRcIl0nLFxuICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJpbWFnZVwiXScsXG4gICAgICAgICAgICAnaW5wdXRbdHlwZT1cImZpbGVcIl0nLFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIGFsdGVybmF0aXZlU2VsZWN0b3JzKSB7XG4gICAgICAgICAgICBoYXNVcGxvYWRDb250YWluZXIgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkudHJ5V2FpdEZvclNlbGVjdG9yKFxuICAgICAgICAgICAgICBwYWdlLFxuICAgICAgICAgICAgICBzZWxlY3RvcixcbiAgICAgICAgICAgICAgMTAwMDBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoaGFzVXBsb2FkQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaGFzVXBsb2FkQ29udGFpbmVyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQ291bGQgbm90IGZpbmQgdXBsb2FkIGNvbnRhaW5lciBvbiBwdWJsaXNoIHBhZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwbG9hZCBpbWFnZXNcbiAgICAgICAgYXdhaXQgdGhpcy51cGxvYWRJbWFnZXMocGFnZSwgcmVzb2x2ZWRQYXRocyk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgaW1hZ2VzIHRvIGJlIHByb2Nlc3NlZCAobGFyZ2UgZmlsZXMgbmVlZCBtb3JlIHRpbWUgb24gWEhTKVxuICAgICAgICBsb2dnZXIuZGVidWcoJ1dhaXRpbmcgMTAgc2Vjb25kcyBmb3IgaW1hZ2VzIHRvIGJlIHVwbG9hZGVkIGFuZCBwcm9jZXNzZWQuLi4nKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMDApO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHBhZ2UgdG8gdHJhbnNpdGlvbiB0byBlZGl0IG1vZGUgKGNoZWNrIGZvciB0aXRsZSBvciBjb250ZW50IGlucHV0KVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclNlbGVjdG9yKFxuICAgICAgICAgICAgJ2lucHV0W3BsYWNlaG9sZGVyKj1cIuagh+mimFwiXSwgZGl2W2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0sIC50aXB0YXAuUHJvc2VNaXJyb3InLFxuICAgICAgICAgICAgeyB0aW1lb3V0OiAxNTAwMCB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAvLyBDb250aW51ZSB3aXRob3V0IHdhaXRpbmdcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdhaXQgYSBiaXQgZm9yIHRoZSBwYWdlIHRvIHNldHRsZSBhZnRlciBpbWFnZSB1cGxvYWRcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG5cbiAgICAgICAgLy8gRmlsbCBpbiB0aXRsZVxuICAgICAgICBhd2FpdCB0aGlzLmZpbGxUaXRsZShwYWdlLCB0aXRsZSk7XG5cbiAgICAgICAgLy8gV2FpdCBhIGJpdCBtb3JlIGZvciBjb250ZW50IGFyZWEgdG8gYXBwZWFyXG4gICAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAgIC8vIEZpbGwgaW4gY29udGVudFxuICAgICAgICBhd2FpdCB0aGlzLmZpbGxDb250ZW50KHBhZ2UsIGNvbnRlbnQpO1xuXG4gICAgICAgIC8vIEFkZCB0YWdzIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0YWdzKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGRUYWdzKHBhZ2UsIHRhZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3VibWl0IHRoZSBub3RlXG4gICAgICAgIGF3YWl0IHRoaXMuc3VibWl0UG9zdChwYWdlKTtcblxuICAgICAgICAvLyBXYWl0IGZvciBjb21wbGV0aW9uIGFuZCBjaGVjayByZXN1bHRcbiAgICAgICAgY29uc3Qgbm90ZUlkID0gYXdhaXQgdGhpcy53YWl0Rm9yUHVibGlzaENvbXBsZXRpb24ocGFnZSk7XG5cbiAgICAgICAgLy8gU2F2ZSBjb29raWVzXG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5zYXZlQ29va2llc0Zyb21QYWdlKHBhZ2UpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICBtZXNzYWdlOiAnTm90ZSBwdWJsaXNoZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICBjb250ZW50LFxuICAgICAgICAgIGltYWdlQ291bnQ6IHJlc29sdmVkUGF0aHMubGVuZ3RoLFxuICAgICAgICAgIHRhZ3MsXG4gICAgICAgICAgdXJsOiB0aGlzLmdldENvbmZpZygpLnhocy5jcmVhdG9yUHVibGlzaFVybCxcbiAgICAgICAgICBub3RlSWQ6IG5vdGVJZCB8fCB1bmRlZmluZWQsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgUHVibGlzaCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzIGltYWdlIHBhdGhzIC0gZG93bmxvYWQgVVJMcyBhbmQgdmFsaWRhdGUgbG9jYWwgcGF0aHNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgdmFsaWRhdGVBbmRSZXNvbHZlSW1hZ2VQYXRocyhpbWFnZVBhdGhzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAvLyBVc2UgSW1hZ2VEb3dubG9hZGVyIHRvIHByb2Nlc3MgcGF0aHMgKGRvd25sb2FkcyBVUkxzLCB2YWxpZGF0ZXMgbG9jYWwgcGF0aHMpXG4gICAgY29uc3QgcmVzb2x2ZWRQYXRocyA9IGF3YWl0IHRoaXMuaW1hZ2VEb3dubG9hZGVyLnByb2Nlc3NJbWFnZVBhdGhzKGltYWdlUGF0aHMpO1xuXG4gICAgLy8gVmFsaWRhdGUgcmVzb2x2ZWQgcGF0aHNcbiAgICBmb3IgKGNvbnN0IHJlc29sdmVkUGF0aCBvZiByZXNvbHZlZFBhdGhzKSB7XG4gICAgICAvLyBGb3IgbG9jYWwgcGF0aHMgdGhhdCBhcmVuJ3QgYWJzb2x1dGUsIHJlc29sdmUgdGhlbVxuICAgICAgY29uc3QgZnVsbFBhdGggPVxuICAgICAgICByZXNvbHZlZFBhdGguc3RhcnRzV2l0aCgnLycpIHx8IHJlc29sdmVkUGF0aC5tYXRjaCgvXlthLXpBLVpdOi8pXG4gICAgICAgICAgPyByZXNvbHZlZFBhdGhcbiAgICAgICAgICA6IGpvaW4ocHJvY2Vzcy5jd2QoKSwgcmVzb2x2ZWRQYXRoKTtcblxuICAgICAgaWYgKCFleGlzdHNTeW5jKGZ1bGxQYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEltYWdlRXJyb3IoYEltYWdlIGZpbGUgbm90IGZvdW5kOiAke3Jlc29sdmVkUGF0aH1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhmdWxsUGF0aCk7XG4gICAgICBpZiAoIXN0YXRzLmlzRmlsZSgpKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW1hZ2VFcnJvcihgUGF0aCBpcyBub3QgYSBmaWxlOiAke3Jlc29sdmVkUGF0aH1gKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgZmlsZSBleHRlbnNpb25cbiAgICAgIGNvbnN0IGV4dCA9IHJlc29sdmVkUGF0aC50b0xvd2VyQ2FzZSgpLnNwbGl0KCcuJykucG9wKCk7XG4gICAgICBjb25zdCBhbGxvd2VkRXh0ZW5zaW9ucyA9IFsnanBnJywgJ2pwZWcnLCAncG5nJywgJ2dpZicsICd3ZWJwJywgJ2JtcCddO1xuICAgICAgaWYgKCFleHQgfHwgIWFsbG93ZWRFeHRlbnNpb25zLmluY2x1ZGVzKGV4dCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRJbWFnZUVycm9yKFxuICAgICAgICAgIGBVbnN1cHBvcnRlZCBpbWFnZSBmb3JtYXQ6ICR7cmVzb2x2ZWRQYXRofS4gU3VwcG9ydGVkOiAke2FsbG93ZWRFeHRlbnNpb25zLmpvaW4oJywgJyl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZXNvbHZlZFBhdGhzLmxlbmd0aCA+IDE4KSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdNYXhpbXVtIDE4IGltYWdlcyBhbGxvd2VkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc29sdmVkUGF0aHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNsaWNrVXBsb2FkVGFiKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdBdHRlbXB0aW5nIHRvIHN3aXRjaCB0byBcIuS4iuS8oOWbvuaWh1wiIHRhYicpO1xuXG4gICAgICAvLyBTdHJhdGVneSAxOiBOYXZpZ2F0ZSBkaXJlY3RseSB0byBpbWFnZSBwdWJsaXNoIFVSTFxuICAgICAgY29uc3QgaW1hZ2VQdWJsaXNoVXJsID0gJ2h0dHBzOi8vY3JlYXRvci54aWFvaG9uZ3NodS5jb20vcHVibGlzaC9wdWJsaXNoP3NvdXJjZT1vZmZpY2lhbCZmcm9tPW1lbnUmdGFyZ2V0PWltYWdlJztcbiAgICAgIGF3YWl0IHBhZ2UuZ290byhpbWFnZVB1Ymxpc2hVcmwsIHsgd2FpdFVudGlsOiAnbmV0d29ya2lkbGUyJywgdGltZW91dDogMzAwMDAgfSk7XG4gICAgICBsb2dnZXIuZGVidWcoYE5hdmlnYXRlZCBkaXJlY3RseSB0byBpbWFnZSBwdWJsaXNoIFVSTDogJHtpbWFnZVB1Ymxpc2hVcmx9YCk7XG4gICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcblxuICAgICAgLy8gVmVyaWZ5IHdlJ3JlIG9uIHRoZSBpbWFnZSB0YWIgYnkgY2hlY2tpbmcgcGFnZSBjb250ZW50XG4gICAgICBjb25zdCBwYWdlU3RhdGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHtcbiAgICAgICAgY29uc3QgYm9keVRleHQgPSBkb2N1bWVudC5ib2R5Py50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBoYXNJbWFnZVVwbG9hZDogYm9keVRleHQuaW5jbHVkZXMoJ+S4iuS8oOWbvuaWhycpIHx8IGJvZHlUZXh0LmluY2x1ZGVzKCfmi5bmi73lm77niYcnKSxcbiAgICAgICAgICBoYXNWaWRlb1VwbG9hZDogYm9keVRleHQuaW5jbHVkZXMoJ+S4iuS8oOinhumikScpIHx8IGJvZHlUZXh0LmluY2x1ZGVzKCfmi5bmi73op4bpopEnKSxcbiAgICAgICAgICB1cmw6IHdpbmRvdy5sb2NhdGlvbi5ocmVmLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICBsb2dnZXIuZGVidWcoYFBhZ2Ugc3RhdGUgYWZ0ZXIgbmF2aWdhdGlvbjogJHtKU09OLnN0cmluZ2lmeShwYWdlU3RhdGUpfWApO1xuXG4gICAgICBpZiAoIXBhZ2VTdGF0ZS5oYXNJbWFnZVVwbG9hZCAmJiBwYWdlU3RhdGUuaGFzVmlkZW9VcGxvYWQpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1N0aWxsIG9uIHZpZGVvIHVwbG9hZCBwYWdlIGFmdGVyIG5hdmlnYXRpb24uIFRyeWluZyB0YWIgY2xpY2suLi4nKTtcblxuICAgICAgICAvLyBTdHJhdGVneSAyOiBDbGljayB0aGUgaW1hZ2UgdGFiIGV4cGxpY2l0bHlcbiAgICAgICAgY29uc3QgdGFicyA9IGF3YWl0IHBhZ2UuJCQoJ2RpdltjbGFzcyo9XCJ0YWJcIl0sIC5jcmVhdG9yLXRhYiwgW3JvbGU9XCJ0YWJcIl0nKTtcbiAgICAgICAgZm9yIChjb25zdCB0YWIgb2YgdGFicykge1xuICAgICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCB0YWIuZXZhbHVhdGUoZWwgPT4gZWwudGV4dENvbnRlbnQ/LnRyaW0oKSk7XG4gICAgICAgICAgaWYgKHRleHQgJiYgKHRleHQuaW5jbHVkZXMoJ+S4iuS8oOWbvuaWhycpIHx8IHRleHQuaW5jbHVkZXMoJ+WbvuaWhycpKSkge1xuICAgICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGFiLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKS5jYXRjaCgoKSA9PiBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoIWlzVmlzaWJsZSkgY29udGludWU7XG5cbiAgICAgICAgICAgIC8vIEZ1bGwgZXZlbnQgY2hhaW4gZm9yIFJlYWN0XG4gICAgICAgICAgICBhd2FpdCB0YWIuZXZhbHVhdGUoKGVsKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGh0bWxFbCA9IGVsIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgICAgICBjb25zdCBldmVudHMgPSBbJ21vdXNlZW50ZXInLCAnbW91c2VvdmVyJywgJ21vdXNlZG93bicsICdtb3VzZXVwJywgJ2NsaWNrJ107XG4gICAgICAgICAgICAgIGV2ZW50cy5mb3JFYWNoKGV2ID0+IHtcbiAgICAgICAgICAgICAgICBodG1sRWwuZGlzcGF0Y2hFdmVudChuZXcgTW91c2VFdmVudChldiwgeyBidWJibGVzOiB0cnVlLCBjYW5jZWxhYmxlOiB0cnVlIH0pKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGF3YWl0IHNsZWVwKDUwMCk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRhYi5jbGljaygpO1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdDbGlja2VkIGltYWdlIHRhYiB2aWEgUHVwcGV0ZWVyJyk7XG4gICAgICAgICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBzd2l0Y2ggdG8gaW1hZ2UgdGFiOiAke2Vycm9yfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBsb2FkSW1hZ2VzKHBhZ2U6IFBhZ2UsIGltYWdlUGF0aHM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnVXBsb2FkaW5nIGltYWdlcyB1c2luZyBkaXJlY3QgaW5wdXQgZWxlbWVudCB0YXJnZXRpbmcnKTtcblxuICAgICAgY29uc3QgZmlsZUlucHV0ID0gYXdhaXQgcGFnZS4kKCdpbnB1dFt0eXBlPVwiZmlsZVwiXScpO1xuICAgICAgaWYgKCFmaWxlSW5wdXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignQ291bGQgbm90IGZpbmQgZmlsZSB1cGxvYWQgaW5wdXQgb24gcGFnZScpO1xuICAgICAgfVxuXG4gICAgICAvLyBFbnN1cmUgdGhlIGlucHV0IGFjY2VwdHMgbXVsdGlwbGUgZmlsZXMgYW5kIGFueSB0eXBlIHRvIGF2b2lkIGZyb250ZW5kIGJsb2Nrc1xuICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWw6IEVsZW1lbnQgfCBudWxsKSA9PiB7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnbXVsdGlwbGUnLCAnbXVsdGlwbGUnKTtcbiAgICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2FjY2VwdCcpO1xuICAgICAgICB9XG4gICAgICB9LCBmaWxlSW5wdXQpO1xuXG4gICAgICBsb2dnZXIuZGVidWcoYFN1Ym1pdHRpbmcgJHtpbWFnZVBhdGhzLmxlbmd0aH0gaW1hZ2UgcGF0aHMgdG8gZmlsZSBpbnB1dCBlbGVtZW50YCk7XG4gICAgICBhd2FpdCBmaWxlSW5wdXQudXBsb2FkRmlsZSguLi5pbWFnZVBhdGhzKTtcblxuICAgICAgLy8gRGlzcGF0Y2ggYSBjaGFuZ2UgZXZlbnQgbWFudWFsbHkgaW4gY2FzZSB0aGUgZnJhbWV3b3JrIG1pc3NlZCBpdFxuICAgICAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWw6IEVsZW1lbnQgfCBudWxsKSA9PiB7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdjaGFuZ2UnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgICAgICB9XG4gICAgICB9LCBmaWxlSW5wdXQpO1xuXG4gICAgICBhd2FpdCBzbGVlcCg4MDAwKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgRmFpbGVkIHRvIHVwbG9hZCBpbWFnZXM6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbn1cbiIsImltcG9ydCB7IFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkLCBnZXRUaXRsZVdpZHRoIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3RpdGxlLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBTRUxFQ1RPUlMsIFRFWFRfUEFUVEVSTlMsIFZJREVPX1RJTUVPVVRTIH0gZnJvbSAnLi9wdWJsaXNoLWJhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBQdWJsaXNoUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IFB1Ymxpc2hFcnJvciB9IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBleGlzdHNTeW5jLCBzdGF0U3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IFB1Ymxpc2hCYXNlU2VydmljZSB9IGZyb20gJy4vcHVibGlzaC1iYXNlLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgVmlkZW9QdWJsaXNoU2VydmljZSBleHRlbmRzIFB1Ymxpc2hCYXNlU2VydmljZSB7XG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvclZpZGVvUHVibGlzaENvbXBsZXRpb24ocGFnZTogUGFnZSk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnV2FpdGluZyBmb3IgdmlkZW8gcHVibGlzaCBjb21wbGV0aW9uLi4uJyk7XG5cbiAgICBsZXQgaXNQcm9jZXNzaW5nID0gZmFsc2U7XG5cbiAgICBhd2FpdCB0aGlzLndhaXRGb3JDb25kaXRpb24oXG4gICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIENoZWNrIGZvciBzdWNjZXNzIGluZGljYXRvcnNcbiAgICAgICAgY29uc3Qgc3VjY2Vzc1Jlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuU1VDQ0VTU19JTkRJQ0FUT1JTLFxuICAgICAgICAgIFRFWFRfUEFUVEVSTlMuU1VDQ0VTU1xuICAgICAgICApO1xuXG4gICAgICAgIGlmIChzdWNjZXNzUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCBzdWNjZXNzIGluZGljYXRvcjogJHtzdWNjZXNzUmVzdWx0LnRleHR9YCk7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoVklERU9fVElNRU9VVFMuQ09NUExFVElPTl9DSEVDSyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBmb3IgZXJyb3IgaW5kaWNhdG9yc1xuICAgICAgICBjb25zdCBlcnJvclJlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuRVJST1JfSU5ESUNBVE9SUyxcbiAgICAgICAgICBURVhUX1BBVFRFUk5TLkVSUk9SXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGVycm9yUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgVmlkZW8gcHVibGlzaCBmYWlsZWQgd2l0aCBlcnJvcjogJHtlcnJvclJlc3VsdC50ZXh0fWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UndmUgbGVmdCB0aGUgcHVibGlzaCBwYWdlIChsaWtlbHkgc3VjY2VzcylcbiAgICAgICAgY29uc3Qgc3RpbGxPblBhZ2UgPSBhd2FpdCB0aGlzLmZpbmRFbGVtZW50QnlTZWxlY3RvcnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuUFVCTElTSF9QQUdFX0lORElDQVRPUlNcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFzdGlsbE9uUGFnZSkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnTGVmdCBwdWJsaXNoIHBhZ2UsIGFzc3VtaW5nIHZpZGVvIHB1Ymxpc2ggc3VjY2VzcycpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIHByb2Nlc3Npbmcgc3RhdHVzXG4gICAgICAgIGNvbnN0IHByb2Nlc3NpbmdSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgU0VMRUNUT1JTLlBST0NFU1NJTkdfSU5ESUNBVE9SUyxcbiAgICAgICAgICBURVhUX1BBVFRFUk5TLlBST0NFU1NJTkdcbiAgICAgICAgKTtcblxuICAgICAgICBpc1Byb2Nlc3NpbmcgPSBwcm9jZXNzaW5nUmVzdWx0LmZvdW5kO1xuICAgICAgICBpZiAoaXNQcm9jZXNzaW5nKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKGBWaWRlbyBzdGlsbCBwcm9jZXNzaW5nOiAke3Byb2Nlc3NpbmdSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGZvciB0b2FzdCBtZXNzYWdlc1xuICAgICAgICBjb25zdCB0b2FzdFJlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuVE9BU1RfU0VMRUNUT1JTLFxuICAgICAgICAgIFRFWFRfUEFUVEVSTlMuU1VDQ0VTU1xuICAgICAgICApO1xuXG4gICAgICAgIGlmICh0b2FzdFJlc3VsdC5mb3VuZCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgc3VjY2VzcyB0b2FzdDogJHt0b2FzdFJlc3VsdC50ZXh0fWApO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZXJyb3JUb2FzdFJlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tFbGVtZW50Rm9yUGF0dGVybnMoXG4gICAgICAgICAgcGFnZSxcbiAgICAgICAgICBTRUxFQ1RPUlMuVE9BU1RfU0VMRUNUT1JTLFxuICAgICAgICAgIFRFWFRfUEFUVEVSTlMuRVJST1JcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoZXJyb3JUb2FzdFJlc3VsdC5mb3VuZCkge1xuICAgICAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYFZpZGVvIHB1Ymxpc2ggZmFpbGVkOiAke2Vycm9yVG9hc3RSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0sXG4gICAgICBWSURFT19USU1FT1VUUy5DT01QTEVUSU9OX1RJTUVPVVQsXG4gICAgICBpc1Byb2Nlc3NpbmcgPyA1MDAwIDogVklERU9fVElNRU9VVFMuQ09NUExFVElPTl9DSEVDSyxcbiAgICAgICdWaWRlbyBwdWJsaXNoIGNvbXBsZXRpb24gdGltZW91dCAtIGNvdWxkIG5vdCBkZXRlcm1pbmUgcmVzdWx0IGFmdGVyIDUgbWludXRlcydcbiAgICApO1xuXG4gICAgLy8gRXh0cmFjdCBub3RlIElEIGFmdGVyIHN1Y2Nlc3NmdWwgY29tcGxldGlvblxuICAgIHJldHVybiBhd2FpdCB0aGlzLmV4dHJhY3ROb3RlSWRGcm9tUGFnZShwYWdlKTtcbiAgfVxuXG4gIGFzeW5jIHB1Ymxpc2hWaWRlbyhcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICB2aWRlb1BhdGg6IHN0cmluZyxcbiAgICB0YWdzOiBzdHJpbmcgPSAnJyxcbiAgICBicm93c2VyUGF0aD86IHN0cmluZ1xuICApOiBQcm9taXNlPFB1Ymxpc2hSZXN1bHQ+IHtcbiAgICAvLyBWYWxpZGF0ZSBpbnB1dHNcbiAgICB0aGlzLnZhbGlkYXRlVmlkZW9JbnB1dHModGl0bGUsIGNvbnRlbnQsIHZpZGVvUGF0aCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcmVzb2x2ZSB2aWRlbyBwYXRoXG4gICAgY29uc3QgcmVzb2x2ZWRWaWRlb1BhdGggPSB0aGlzLnZhbGlkYXRlQW5kUmVzb2x2ZVZpZGVvUGF0aCh2aWRlb1BhdGgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZShmYWxzZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBub3RlSWQgPSBhd2FpdCB0aGlzLmV4ZWN1dGVWaWRlb1B1Ymxpc2hXb3JrZmxvdyhwYWdlLCB0aXRsZSwgY29udGVudCwgcmVzb2x2ZWRWaWRlb1BhdGgsIHRhZ3MpO1xuXG4gICAgICAgIC8vIFNhdmUgY29va2llc1xuICAgICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuc2F2ZUNvb2tpZXNGcm9tUGFnZShwYWdlKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgbWVzc2FnZTogJ1ZpZGVvIHB1Ymxpc2hlZCBzdWNjZXNzZnVsbHknLFxuICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgIGNvbnRlbnQsXG4gICAgICAgICAgaW1hZ2VDb3VudDogMCwgLy8gVmlkZW9zIGRvbid0IGhhdmUgaW1hZ2UgY291bnRcbiAgICAgICAgICB0YWdzLFxuICAgICAgICAgIHVybDogdGhpcy5nZXRDb25maWcoKS54aHMuY3JlYXRvclZpZGVvUHVibGlzaFVybCxcbiAgICAgICAgICBub3RlSWQ6IG5vdGVJZCB8fCB1bmRlZmluZWQsXG4gICAgICAgIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgVmlkZW8gcHVibGlzaCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVWaWRlb0lucHV0cyh0aXRsZTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcsIHZpZGVvUGF0aDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aXRsZT8udHJpbSgpKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdWaWRlbyB0aXRsZSBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSB0aXRsZSB3aWR0aCBmb3IgdmlkZW8gcG9zdHMgdG9vXG4gICAgYXNzZXJ0VGl0bGVXaWR0aFZhbGlkKHRpdGxlKTtcbiAgICBsb2dnZXIuZGVidWcoYFZpZGVvIHRpdGxlIHdpZHRoIHZhbGlkYXRpb24gcGFzc2VkOiBcIiR7dGl0bGV9XCIgKCR7Z2V0VGl0bGVXaWR0aCh0aXRsZSl9IHVuaXRzKWApO1xuXG4gICAgaWYgKCFjb250ZW50Py50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoJ1ZpZGVvIGNvbnRlbnQgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuXG4gICAgaWYgKCF2aWRlb1BhdGg/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcignVmlkZW8gcGF0aCBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZXhlY3V0ZVZpZGVvUHVibGlzaFdvcmtmbG93KFxuICAgIHBhZ2U6IFBhZ2UsXG4gICAgdGl0bGU6IHN0cmluZyxcbiAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgdmlkZW9QYXRoOiBzdHJpbmcsXG4gICAgdGFnczogc3RyaW5nXG4gICk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIC8vIE5hdmlnYXRlIHRvIHZpZGVvIHVwbG9hZCBwYWdlXG4gICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KFxuICAgICAgcGFnZSxcbiAgICAgIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmNyZWF0b3JWaWRlb1B1Ymxpc2hVcmxcbiAgICApO1xuXG4gICAgLy8gV2FpdCBmb3IgcGFnZSB0byBsb2FkXG4gICAgYXdhaXQgc2xlZXAoVklERU9fVElNRU9VVFMuUEFHRV9MT0FEKTtcblxuICAgIC8vIFN3aXRjaCB0byB2aWRlbyB1cGxvYWQgdGFiIGlmIG5lZWRlZFxuICAgIGF3YWl0IHRoaXMuY2xpY2tWaWRlb1VwbG9hZFRhYihwYWdlKTtcblxuICAgIC8vIFdhaXQgZm9yIHRhYiBzd2l0Y2ggdG8gY29tcGxldGVcbiAgICBhd2FpdCBzbGVlcChWSURFT19USU1FT1VUUy5UQUJfU1dJVENIKTtcblxuICAgIC8vIFVwbG9hZCB2aWRlb1xuICAgIGF3YWl0IHRoaXMudXBsb2FkVmlkZW8ocGFnZSwgdmlkZW9QYXRoKTtcblxuICAgIC8vIFdhaXQgZm9yIHZpZGVvIHRvIGJlIHByb2Nlc3NlZCAodmlkZW9zIHRha2UgbG9uZ2VyIHRoYW4gaW1hZ2VzKVxuICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlZJREVPX1BST0NFU1NJTkcpO1xuXG4gICAgLy8gRmlsbCBpbiB0aXRsZVxuICAgIGF3YWl0IHRoaXMuZmlsbFRpdGxlKHBhZ2UsIHRpdGxlKTtcblxuICAgIC8vIFdhaXQgYSBiaXQgZm9yIGNvbnRlbnQgYXJlYSB0byBhcHBlYXJcbiAgICBhd2FpdCBzbGVlcChWSURFT19USU1FT1VUUy5DT05URU5UX1dBSVQpO1xuXG4gICAgLy8gRmlsbCBpbiBjb250ZW50XG4gICAgYXdhaXQgdGhpcy5maWxsQ29udGVudChwYWdlLCBjb250ZW50KTtcblxuICAgIC8vIEFkZCB0YWdzIGlmIHByb3ZpZGVkXG4gICAgaWYgKHRhZ3MpIHtcbiAgICAgIGF3YWl0IHRoaXMuYWRkVGFncyhwYWdlLCB0YWdzKTtcbiAgICB9XG5cbiAgICAvLyBTdWJtaXQgdGhlIHZpZGVvXG4gICAgYXdhaXQgdGhpcy5zdWJtaXRQb3N0KHBhZ2UpO1xuXG4gICAgLy8gV2FpdCBmb3IgY29tcGxldGlvbiBhbmQgY2hlY2sgcmVzdWx0ICh2aWRlb3MgbmVlZCBsb25nZXIgdGltZW91dClcbiAgICByZXR1cm4gYXdhaXQgdGhpcy53YWl0Rm9yVmlkZW9QdWJsaXNoQ29tcGxldGlvbihwYWdlKTtcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVBbmRSZXNvbHZlVmlkZW9QYXRoKHZpZGVvUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCByZXNvbHZlZFBhdGggPVxuICAgICAgdmlkZW9QYXRoLnN0YXJ0c1dpdGgoJy8nKSB8fCB2aWRlb1BhdGgubWF0Y2goL15bYS16QS1aXTovKVxuICAgICAgICA/IHZpZGVvUGF0aFxuICAgICAgICA6IGpvaW4ocHJvY2Vzcy5jd2QoKSwgdmlkZW9QYXRoKTtcblxuICAgIGlmICghZXhpc3RzU3luYyhyZXNvbHZlZFBhdGgpKSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKGBWaWRlbyBmaWxlIG5vdCBmb3VuZDogJHt2aWRlb1BhdGh9YCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhyZXNvbHZlZFBhdGgpO1xuICAgIGlmICghc3RhdHMuaXNGaWxlKCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoYFBhdGggaXMgbm90IGEgZmlsZTogJHt2aWRlb1BhdGh9YCk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZmlsZSBleHRlbnNpb25cbiAgICBjb25zdCBleHQgPSB2aWRlb1BhdGgudG9Mb3dlckNhc2UoKS5zcGxpdCgnLicpLnBvcCgpO1xuICAgIGNvbnN0IGFsbG93ZWRFeHRlbnNpb25zID0gWydtcDQnLCAnbW92JywgJ2F2aScsICdta3YnLCAnd2VibScsICdmbHYnLCAnd212J107XG4gICAgaWYgKCFleHQgfHwgIWFsbG93ZWRFeHRlbnNpb25zLmluY2x1ZGVzKGV4dCkpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoXG4gICAgICAgIGBVbnN1cHBvcnRlZCB2aWRlbyBmb3JtYXQ6ICR7dmlkZW9QYXRofS4gU3VwcG9ydGVkOiAke2FsbG93ZWRFeHRlbnNpb25zLmpvaW4oJywgJyl9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmaWxlIHNpemUgKFhIUyB0eXBpY2FsbHkgaGFzIGxpbWl0cylcbiAgICBjb25zdCBtYXhTaXplSW5NQiA9IDUwMDsgLy8gNTAwTUIgbGltaXRcbiAgICBjb25zdCBmaWxlU2l6ZUluTUIgPSBzdGF0cy5zaXplIC8gKDEwMjQgKiAxMDI0KTtcbiAgICBpZiAoZmlsZVNpemVJbk1CID4gbWF4U2l6ZUluTUIpIHtcbiAgICAgIHRocm93IG5ldyBQdWJsaXNoRXJyb3IoXG4gICAgICAgIGBWaWRlbyBmaWxlIHRvbyBsYXJnZTogJHtmaWxlU2l6ZUluTUIudG9GaXhlZCgyKX1NQi4gTWF4aW11bSBhbGxvd2VkOiAke21heFNpemVJbk1CfU1CYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZWRQYXRoO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjbGlja1ZpZGVvVXBsb2FkVGFiKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgLy8gVHJ5IG11bHRpcGxlIHNlbGVjdG9ycyBmb3IgdmlkZW8gdGFiXG4gICAgICBjb25zdCB2aWRlb1RhYlNlbGVjdG9ycyA9IFtcbiAgICAgICAgJ2Rpdi5jcmVhdG9yLXRhYicsXG4gICAgICAgICcuY3JlYXRvci10YWInLFxuICAgICAgICAnW3JvbGU9XCJ0YWJcIl0nLFxuICAgICAgICAnLnRhYicsXG4gICAgICAgICdkaXZbY2xhc3MqPVwidGFiXCJdJyxcbiAgICAgIF07XG5cbiAgICAgIGxldCB0YWJzOiBhbnlbXSA9IFtdO1xuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiB2aWRlb1RhYlNlbGVjdG9ycykge1xuICAgICAgICBjb25zdCBmb3VuZFRhYnMgPSBhd2FpdCBwYWdlLiQkKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGZvdW5kVGFicy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGFicyA9IGZvdW5kVGFicztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGFicy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ05vIHRhYnMgZm91bmQgZm9yIHZpZGVvIHVwbG9hZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIExvb2sgZm9yIHRoZSB2aWRlbyB1cGxvYWQgdGFiIHNwZWNpZmljYWxseVxuICAgICAgbGV0IHZpZGVvVGFiOiBhbnkgPSBudWxsO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHRhYiA9IHRhYnNbaV07XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgaXNWaXNpYmxlID0gYXdhaXQgdGFiLmlzSW50ZXJzZWN0aW5nVmlld3BvcnQoKTtcbiAgICAgICAgICBpZiAoIWlzVmlzaWJsZSkgY29udGludWU7XG5cbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoZWwpID0+IGVsLnRleHRDb250ZW50LCB0YWIpO1xuXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyB0aGUgdmlkZW8gdXBsb2FkIHRhYlxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRleHQgJiZcbiAgICAgICAgICAgICh0ZXh0LmluY2x1ZGVzKCfkuIrkvKDop4bpopEnKSB8fCB0ZXh0LmluY2x1ZGVzKCfop4bpopEnKSB8fCB0ZXh0LmluY2x1ZGVzKCd2aWRlbycpKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdmlkZW9UYWIgPSB0YWI7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgLy8gSWdub3JlIGluZGl2aWR1YWwgdGFiIGVycm9yc1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh2aWRlb1RhYikge1xuICAgICAgICBhd2FpdCB2aWRlb1RhYi5jbGljaygpO1xuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTsgLy8gV2FpdCBmb3IgdGFiIHN3aXRjaFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRmFsbGJhY2s6IGNsaWNrIHRoZSBmaXJzdCB0YWIgKHVzdWFsbHkgdmlkZW8gdXBsb2FkKVxuICAgICAgICBjb25zdCB2aXNpYmxlVGFiczogYW55W10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCB0YWIgb2YgdGFicykge1xuICAgICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGF3YWl0IHRhYi5pc0ludGVyc2VjdGluZ1ZpZXdwb3J0KCk7XG4gICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgdmlzaWJsZVRhYnMucHVzaCh0YWIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2aXNpYmxlVGFicy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgYXdhaXQgdmlzaWJsZVRhYnNbMF0uY2xpY2soKTsgLy8gVXN1YWxseSB0aGUgZmlyc3QgdGFiIGlzIHZpZGVvIHVwbG9hZFxuICAgICAgICAgIGF3YWl0IHNsZWVwKDIwMDApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gY2xpY2sgdmlkZW8gdXBsb2FkIHRhYjogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwbG9hZFZpZGVvKHBhZ2U6IFBhZ2UsIHZpZGVvUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nZ2VyLmRlYnVnKGBVcGxvYWRpbmcgdmlkZW86ICR7dmlkZW9QYXRofWApO1xuXG4gICAgLy8gRmluZCBmaWxlIGlucHV0IGVsZW1lbnRcbiAgICBjb25zdCBmaWxlSW5wdXQgPSBhd2FpdCB0aGlzLmZpbmRFbGVtZW50QnlTZWxlY3RvcnMocGFnZSwgU0VMRUNUT1JTLkZJTEVfSU5QVVQpO1xuICAgIGlmICghZmlsZUlucHV0KSB7XG4gICAgICB0aHJvdyBuZXcgUHVibGlzaEVycm9yKCdDb3VsZCBub3QgZmluZCBmaWxlIHVwbG9hZCBpbnB1dCBvbiB2aWRlbyB1cGxvYWQgcGFnZScpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBXYWl0IGZvciB0aGUgaW5wdXQgdG8gYmUgcmVhZHlcbiAgICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlVQTE9BRF9SRUFEWSk7XG5cbiAgICAgIC8vIFVwbG9hZCB0aGUgdmlkZW8gZmlsZVxuICAgICAgYXdhaXQgZmlsZUlucHV0LnVwbG9hZEZpbGUodmlkZW9QYXRoKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnVmlkZW8gZmlsZSB1cGxvYWRlZCwgd2FpdGluZyBmb3IgcHJvY2Vzc2luZy4uLicpO1xuXG4gICAgICAvLyBXYWl0IGZvciB1cGxvYWQgdG8gc3RhcnQgYW5kIHNob3cgcHJvZ3Jlc3NcbiAgICAgIGF3YWl0IHNsZWVwKFZJREVPX1RJTUVPVVRTLlVQTE9BRF9TVEFSVCk7XG5cbiAgICAgIC8vIFdhaXQgZm9yIHZpZGVvIHByb2Nlc3NpbmcgdG8gY29tcGxldGUgKHRoaXMgY2FuIHRha2UgYSB3aGlsZSlcbiAgICAgIGF3YWl0IHRoaXMud2FpdEZvclZpZGVvUHJvY2Vzc2luZyhwYWdlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFB1Ymxpc2hFcnJvcihgRmFpbGVkIHRvIHVwbG9hZCB2aWRlbyAke3ZpZGVvUGF0aH06ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yVmlkZW9Qcm9jZXNzaW5nKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2dnZXIuZGVidWcoJ1dhaXRpbmcgZm9yIHZpZGVvIHByb2Nlc3NpbmcgdG8gY29tcGxldGUuLi4nKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JDb25kaXRpb24oXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAvLyBDaGVjayBpZiBwcm9jZXNzaW5nIGlzIGNvbXBsZXRlXG4gICAgICAgICAgY29uc3QgY29tcGxldGVSZXN1bHQgPSBhd2FpdCB0aGlzLmNoZWNrRWxlbWVudEZvclBhdHRlcm5zKFxuICAgICAgICAgICAgcGFnZSxcbiAgICAgICAgICAgIFNFTEVDVE9SUy5DT01QTEVUSU9OX0lORElDQVRPUlMsXG4gICAgICAgICAgICBURVhUX1BBVFRFUk5TLlNVQ0NFU1NcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKGNvbXBsZXRlUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYFZpZGVvIHByb2Nlc3NpbmcgY29tcGxldGU6ICR7Y29tcGxldGVSZXN1bHQudGV4dH1gKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIENoZWNrIGlmIHN0aWxsIHByb2Nlc3NpbmdcbiAgICAgICAgICBjb25zdCBwcm9jZXNzaW5nUmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0VsZW1lbnRGb3JQYXR0ZXJucyhcbiAgICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgICBTRUxFQ1RPUlMuUFJPQ0VTU0lOR19JTkRJQ0FUT1JTLFxuICAgICAgICAgICAgVEVYVF9QQVRURVJOUy5QUk9DRVNTSU5HXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChwcm9jZXNzaW5nUmVzdWx0LmZvdW5kKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYFZpZGVvIHByb2Nlc3Npbmc6ICR7cHJvY2Vzc2luZ1Jlc3VsdC50ZXh0fWApO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBTdGlsbCBwcm9jZXNzaW5nLCBjb250aW51ZSB3YWl0aW5nXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gSWYgbm90IHByb2Nlc3NpbmcgYW5kIG5vIGNvbXBsZXRpb24gaW5kaWNhdG9yLCBhc3N1bWUgaXQncyBkb25lXG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdObyBwcm9jZXNzaW5nIGluZGljYXRvcnMgZm91bmQsIGFzc3VtaW5nIHZpZGVvIHByb2Nlc3NpbmcgY29tcGxldGUnKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgVklERU9fVElNRU9VVFMuUFJPQ0VTU0lOR19USU1FT1VULFxuICAgICAgICBWSURFT19USU1FT1VUUy5QUk9DRVNTSU5HX0NIRUNLLFxuICAgICAgICAnVmlkZW8gcHJvY2Vzc2luZyB0aW1lb3V0J1xuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oJ1ZpZGVvIHByb2Nlc3NpbmcgdGltZW91dCwgY29udGludWluZyBhbnl3YXkuLi4nKTtcbiAgICB9XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgQ29uZmlnLCBQdWJsaXNoUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBCcm93c2VyTWFuYWdlciB9IGZyb20gJy4uL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyJztcbmltcG9ydCB7IEltYWdlUHVibGlzaFNlcnZpY2UgfSBmcm9tICcuL3B1Ymxpc2gtaW1hZ2Uuc2VydmljZSc7XG5pbXBvcnQgeyBWaWRlb1B1Ymxpc2hTZXJ2aWNlIH0gZnJvbSAnLi9wdWJsaXNoLXZpZGVvLnNlcnZpY2UnO1xuXG5leHBvcnQgY2xhc3MgUHVibGlzaFNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIHByaXZhdGUgaW1hZ2VTZXJ2aWNlOiBJbWFnZVB1Ymxpc2hTZXJ2aWNlO1xuICBwcml2YXRlIHZpZGVvU2VydmljZTogVmlkZW9QdWJsaXNoU2VydmljZTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IENvbmZpZywgYnJvd3Nlck1hbmFnZXI/OiBCcm93c2VyTWFuYWdlcikge1xuICAgIHN1cGVyKGNvbmZpZywgYnJvd3Nlck1hbmFnZXIpO1xuICAgIHRoaXMuaW1hZ2VTZXJ2aWNlID0gbmV3IEltYWdlUHVibGlzaFNlcnZpY2UoY29uZmlnLCB0aGlzLmJyb3dzZXJNYW5hZ2VyKTtcbiAgICB0aGlzLnZpZGVvU2VydmljZSA9IG5ldyBWaWRlb1B1Ymxpc2hTZXJ2aWNlKGNvbmZpZywgdGhpcy5icm93c2VyTWFuYWdlcik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcHVibGlzaE5vdGUoXG4gICAgdGl0bGU6IHN0cmluZyxcbiAgICBjb250ZW50OiBzdHJpbmcsXG4gICAgaW1hZ2VQYXRoczogc3RyaW5nW10sXG4gICAgdGFnczogc3RyaW5nID0gJycsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxQdWJsaXNoUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VTZXJ2aWNlLnB1Ymxpc2hOb3RlKHRpdGxlLCBjb250ZW50LCBpbWFnZVBhdGhzLCB0YWdzLCBicm93c2VyUGF0aCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcHVibGlzaFZpZGVvKFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIHZpZGVvUGF0aDogc3RyaW5nLFxuICAgIHRhZ3M6IHN0cmluZyA9ICcnLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8UHVibGlzaFJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnZpZGVvU2VydmljZS5wdWJsaXNoVmlkZW8odGl0bGUsIGNvbnRlbnQsIHZpZGVvUGF0aCwgdGFncywgYnJvd3NlclBhdGgpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHB1Ymxpc2hDb250ZW50KFxuICAgIHR5cGU6ICdpbWFnZScgfCAndmlkZW8nLFxuICAgIHRpdGxlOiBzdHJpbmcsXG4gICAgY29udGVudDogc3RyaW5nLFxuICAgIG1lZGlhUGF0aHM6IHN0cmluZ1tdLFxuICAgIHRhZ3M6IHN0cmluZyA9ICcnLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8UHVibGlzaFJlc3VsdD4ge1xuICAgIGlmICh0eXBlID09PSAnaW1hZ2UnKSB7XG4gICAgICByZXR1cm4gdGhpcy5wdWJsaXNoTm90ZSh0aXRsZSwgY29udGVudCwgbWVkaWFQYXRocywgdGFncywgYnJvd3NlclBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5wdWJsaXNoVmlkZW8odGl0bGUsIGNvbnRlbnQsIG1lZGlhUGF0aHNbMF0sIHRhZ3MsIGJyb3dzZXJQYXRoKTtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogVG9vbCByZXF1ZXN0IGhhbmRsZXJzIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9hdXRoL2F1dGguc2VydmljZSc7XG5pbXBvcnQgeyBGZWVkU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvZmVlZHMvZmVlZC5zZXJ2aWNlJztcbmltcG9ydCB7IFB1Ymxpc2hTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9wdWJsaXNoaW5nL3B1Ymxpc2guc2VydmljZSc7XG5pbXBvcnQgeyBOb3RlU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvbm90ZXMvbm90ZS5zZXJ2aWNlJztcbmltcG9ydCB7IEJyb3dzZXJNYW5hZ2VyIH0gZnJvbSAnLi4vLi4vY29yZS9icm93c2VyL2Jyb3dzZXIubWFuYWdlcic7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IFhIU0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQge1xuICB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zLFxuICBzYWZlRXJyb3JIYW5kbGVyLFxuICBjcmVhdGVNY3BUb29sUmVzcG9uc2UsXG4gIGNyZWF0ZU1jcEVycm9yUmVzcG9uc2UsXG59IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvbG9nZ2VyJztcbmltcG9ydCB7IGFzc2VydFRpdGxlV2lkdGhWYWxpZCB9IGZyb20gJy4uLy4uL3NoYXJlZC90aXRsZS12YWxpZGF0b3InO1xuXG4vKipcbiAqIFRvb2wgcmVxdWVzdCBhcmd1bWVudHMgaW50ZXJmYWNlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9vbFJlcXVlc3RBcmdzIHtcbiAgYnJvd3Nlcl9wYXRoPzogc3RyaW5nO1xuICBrZXl3b3JkPzogc3RyaW5nO1xuICBmZWVkX2lkPzogc3RyaW5nO1xuICB4c2VjX3Rva2VuPzogc3RyaW5nO1xuICBub3RlPzogc3RyaW5nO1xuICB0eXBlPzogc3RyaW5nO1xuICB0aXRsZT86IHN0cmluZztcbiAgY29udGVudD86IHN0cmluZztcbiAgbWVkaWFfcGF0aHM/OiBzdHJpbmdbXTtcbiAgdGFncz86IHN0cmluZztcbiAgbGltaXQ/OiBudW1iZXI7XG4gIGN1cnNvcj86IHN0cmluZztcbiAgbm90ZV9pZD86IHN0cmluZztcbiAgbGFzdF9wdWJsaXNoZWQ/OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgVG9vbEhhbmRsZXJzIHtcbiAgcHJpdmF0ZSBhdXRoU2VydmljZTogQXV0aFNlcnZpY2U7XG4gIHByaXZhdGUgZmVlZFNlcnZpY2U6IEZlZWRTZXJ2aWNlO1xuICBwcml2YXRlIHB1Ymxpc2hTZXJ2aWNlOiBQdWJsaXNoU2VydmljZTtcbiAgcHJpdmF0ZSBub3RlU2VydmljZTogTm90ZVNlcnZpY2U7XG4gIHByaXZhdGUgYnJvd3Nlck1hbmFnZXI6IEJyb3dzZXJNYW5hZ2VyO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgIHRoaXMuYnJvd3Nlck1hbmFnZXIgPSBuZXcgQnJvd3Nlck1hbmFnZXIoY29uZmlnKTtcbiAgICB0aGlzLmF1dGhTZXJ2aWNlID0gbmV3IEF1dGhTZXJ2aWNlKGNvbmZpZywgdGhpcy5icm93c2VyTWFuYWdlcik7XG4gICAgdGhpcy5mZWVkU2VydmljZSA9IG5ldyBGZWVkU2VydmljZShjb25maWcsIHRoaXMuYnJvd3Nlck1hbmFnZXIpO1xuICAgIHRoaXMucHVibGlzaFNlcnZpY2UgPSBuZXcgUHVibGlzaFNlcnZpY2UoY29uZmlnLCB0aGlzLmJyb3dzZXJNYW5hZ2VyKTtcbiAgICB0aGlzLm5vdGVTZXJ2aWNlID0gbmV3IE5vdGVTZXJ2aWNlKGNvbmZpZywgdGhpcy5icm93c2VyTWFuYWdlcik7XG4gIH1cblxuICBhc3luYyBoYW5kbGVBdXRoTG9naW4oXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIC8vIFN0YXJ0IGxvZ2luIHByb2Nlc3MgaW4gYmFja2dyb3VuZCBhbmQgcmV0dXJuIGltbWVkaWF0ZWx5XG4gICAgLy8gVGhpcyBmb2xsb3dzIHRoZSBcImluc3RhbnQgcmVzcG9uc2VcIiBwYXR0ZXJuIGRlc2NyaWJlZCBpbiBSRUFETUVcbiAgICB0aGlzLmF1dGhTZXJ2aWNlLmxvZ2luKGJyb3dzZXJQYXRoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIHNhZmVFcnJvckhhbmRsZXIoZXJyb3IsICdCYWNrZ3JvdW5kIGxvZ2luIGVycm9yJywgbG9nZ2VyKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgdGV4dDogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgICAgICAgJ0xvZ2luIHByb2Nlc3Mgc3RhcnRlZC4gQSBicm93c2VyIHdpbmRvdyB3aWxsIG9wZW4gZm9yIHlvdSB0byBjb21wbGV0ZSB0aGUgbG9naW4uJyxcbiAgICAgICAgICAgICAgc3RhdHVzOiAnbG9naW5fc3RhcnRlZCcsXG4gICAgICAgICAgICAgIGFjdGlvbjogJ2Jyb3dzZXJfb3BlbmVkJyxcbiAgICAgICAgICAgICAgaW5zdHJ1Y3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgJzEuIENvbXBsZXRlIHRoZSBsb2dpbiBwcm9jZXNzIGluIHRoZSBvcGVuZWQgYnJvd3NlciB3aW5kb3cnLFxuICAgICAgICAgICAgICAgICcyLiBTY2FuIFFSIGNvZGUgb3IgZW50ZXIgeW91ciBjcmVkZW50aWFscycsXG4gICAgICAgICAgICAgICAgJzMuIExvZ2luIHdpbGwgYmUgYXV0b21hdGljYWxseSB2ZXJpZmllZCBhbmQgY29va2llcyBzYXZlZCcsXG4gICAgICAgICAgICAgICAgJzQuIFVzZSB4aHNfYXV0aF9zdGF0dXMgdG8gY2hlY2sgaWYgbG9naW4gY29tcGxldGVkJyxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgbm90ZTogJ1RoZSBsb2dpbiBwcm9jZXNzIHJ1bnMgaW4gdGhlIGJhY2tncm91bmQuIFlvdSBjYW4gY29udGludWUgdXNpbmcgb3RoZXIgdG9vbHMgd2hpbGUgbG9naW4gY29tcGxldGVzLicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIDJcbiAgICAgICAgICApLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQXV0aExvZ291dCgpOiBQcm9taXNlPHsgY29udGVudDogQXJyYXk8eyB0eXBlOiBzdHJpbmc7IHRleHQ6IHN0cmluZyB9PiB9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5sb2dvdXQoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVBdXRoU3RhdHVzKFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmF1dGhTZXJ2aWNlLmNoZWNrU3RhdHVzKGJyb3dzZXJQYXRoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVEaXNjb3ZlckZlZWRzKFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZlZWRTZXJ2aWNlLmdldEZlZWRMaXN0KGJyb3dzZXJQYXRoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVTZWFyY2hOb3RlKFxuICAgIGtleXdvcmQ/OiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIHZhbGlkYXRlUmVxdWlyZWRQYXJhbXMoeyBrZXl3b3JkIH0sIFsna2V5d29yZCddKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZlZWRTZXJ2aWNlLnNlYXJjaEZlZWRzKGtleXdvcmQhLCBicm93c2VyUGF0aCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlR2V0Tm90ZURldGFpbChcbiAgICBmZWVkSWQ/OiBzdHJpbmcsXG4gICAgeHNlY1Rva2VuPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICB2YWxpZGF0ZVJlcXVpcmVkUGFyYW1zKHsgZmVlZElkLCB4c2VjVG9rZW4gfSwgWydmZWVkSWQnLCAneHNlY1Rva2VuJ10pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZmVlZFNlcnZpY2UuZ2V0RmVlZERldGFpbChmZWVkSWQhLCB4c2VjVG9rZW4hLCBicm93c2VyUGF0aCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQ29tbWVudE9uTm90ZShcbiAgICBmZWVkSWQ/OiBzdHJpbmcsXG4gICAgeHNlY1Rva2VuPzogc3RyaW5nLFxuICAgIG5vdGU/OiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIHZhbGlkYXRlUmVxdWlyZWRQYXJhbXMoeyBmZWVkSWQsIHhzZWNUb2tlbiwgbm90ZSB9LCBbJ2ZlZWRJZCcsICd4c2VjVG9rZW4nLCAnbm90ZSddKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZlZWRTZXJ2aWNlLmNvbW1lbnRPbkZlZWQoZmVlZElkISwgeHNlY1Rva2VuISwgbm90ZSEsIGJyb3dzZXJQYXRoKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVQdWJsaXNoQ29udGVudChcbiAgICB0eXBlPzogc3RyaW5nLFxuICAgIHRpdGxlPzogc3RyaW5nLFxuICAgIGNvbnRlbnQ/OiBzdHJpbmcsXG4gICAgbWVkaWFQYXRocz86IHN0cmluZ1tdLFxuICAgIHRhZ3M/OiBzdHJpbmcsXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIHZhbGlkYXRlUmVxdWlyZWRQYXJhbXMoeyB0eXBlLCB0aXRsZSwgY29udGVudCwgbWVkaWFQYXRocyB9LCBbXG4gICAgICAndHlwZScsXG4gICAgICAndGl0bGUnLFxuICAgICAgJ2NvbnRlbnQnLFxuICAgICAgJ21lZGlhUGF0aHMnLFxuICAgIF0pO1xuXG4gICAgLy8gVmFsaWRhdGUgY29udGVudCB0eXBlXG4gICAgaWYgKHR5cGUgIT09ICdpbWFnZScgJiYgdHlwZSAhPT0gJ3ZpZGVvJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb250ZW50IHR5cGUgbXVzdCBiZSBcImltYWdlXCIgb3IgXCJ2aWRlb1wiJyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgcGFyYW1ldGVyIGNvbnN0cmFpbnRzIHVzaW5nIHdpZHRoLWF3YXJlIHRpdGxlIHZhbGlkYXRpb25cbiAgICBhc3NlcnRUaXRsZVdpZHRoVmFsaWQodGl0bGUhKTtcbiAgICBpZiAoY29udGVudCEubGVuZ3RoID4gMTAwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb250ZW50IG11c3QgYmUgMTAwMCBjaGFyYWN0ZXJzIG9yIGxlc3MnKTtcbiAgICB9XG5cbiAgICAvLyBFeGVjdXRlIHVuaWZpZWQgcHVibGlzaGluZyBwcm9jZXNzXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5wdWJsaXNoU2VydmljZS5wdWJsaXNoQ29udGVudChcbiAgICAgIHR5cGUgYXMgJ2ltYWdlJyB8ICd2aWRlbycsXG4gICAgICB0aXRsZSEsXG4gICAgICBjb250ZW50ISxcbiAgICAgIG1lZGlhUGF0aHMhLFxuICAgICAgdGFncyxcbiAgICAgIGJyb3dzZXJQYXRoXG4gICAgKTtcbiAgICByZXR1cm4gY3JlYXRlTWNwVG9vbFJlc3BvbnNlKHJlc3VsdCk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVHZXRVc2VyTm90ZXMoXG4gICAgbGltaXQ/OiBudW1iZXIsXG4gICAgY3Vyc29yPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm5vdGVTZXJ2aWNlLmdldFVzZXJOb3RlcyhsaW1pdCwgY3Vyc29yLCBicm93c2VyUGF0aCk7XG4gICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlRGVsZXRlTm90ZShcbiAgICBub3RlSWQ/OiBzdHJpbmcsXG4gICAgbGFzdFB1Ymxpc2hlZD86IGJvb2xlYW4sXG4gICAgYnJvd3NlclBhdGg/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IEFycmF5PHsgdHlwZTogc3RyaW5nOyB0ZXh0OiBzdHJpbmcgfT4gfT4ge1xuICAgIGlmIChsYXN0UHVibGlzaGVkKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm5vdGVTZXJ2aWNlLmRlbGV0ZUxhc3RQdWJsaXNoZWROb3RlKGJyb3dzZXJQYXRoKTtcbiAgICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UocmVzdWx0KTtcbiAgICB9IGVsc2UgaWYgKG5vdGVJZCkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ub3RlU2VydmljZS5kZWxldGVOb3RlKG5vdGVJZCwgYnJvd3NlclBhdGgpO1xuICAgICAgcmV0dXJuIGNyZWF0ZU1jcFRvb2xSZXNwb25zZShyZXN1bHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciBub3RlX2lkIG9yIGxhc3RfcHVibGlzaGVkIG11c3QgYmUgc3BlY2lmaWVkJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgaGFuZGxlVG9vbFJlcXVlc3QoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGFyZ3M6IFRvb2xSZXF1ZXN0QXJncyA9IHt9XG4gICk6IFByb21pc2U8eyBjb250ZW50OiBBcnJheTx7IHR5cGU6IHN0cmluZzsgdGV4dDogc3RyaW5nIH0+IH0+IHtcbiAgICB0cnkge1xuICAgICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICAgIGNhc2UgJ3hoc19hdXRoX2xvZ2luJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVBdXRoTG9naW4oYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZyk7XG5cbiAgICAgICAgY2FzZSAneGhzX2F1dGhfbG9nb3V0JzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVBdXRoTG9nb3V0KCk7XG5cbiAgICAgICAgY2FzZSAneGhzX2F1dGhfc3RhdHVzJzpcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5oYW5kbGVBdXRoU3RhdHVzKGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmcpO1xuXG4gICAgICAgIGNhc2UgJ3hoc19kaXNjb3Zlcl9mZWVkcyc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlRGlzY292ZXJGZWVkcyhhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nKTtcblxuICAgICAgICBjYXNlICd4aHNfc2VhcmNoX25vdGUnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZVNlYXJjaE5vdGUoYXJncz8ua2V5d29yZCBhcyBzdHJpbmcsIGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmcpO1xuXG4gICAgICAgIGNhc2UgJ3hoc19nZXRfbm90ZV9kZXRhaWwnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZUdldE5vdGVEZXRhaWwoXG4gICAgICAgICAgICBhcmdzPy5mZWVkX2lkIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LnhzZWNfdG9rZW4gYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8uYnJvd3Nlcl9wYXRoIGFzIHN0cmluZ1xuICAgICAgICAgICk7XG5cbiAgICAgICAgY2FzZSAneGhzX2NvbW1lbnRfb25fbm90ZSc6XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaGFuZGxlQ29tbWVudE9uTm90ZShcbiAgICAgICAgICAgIGFyZ3M/LmZlZWRfaWQgYXMgc3RyaW5nLFxuICAgICAgICAgICAgYXJncz8ueHNlY190b2tlbiBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5ub3RlIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/LmJyb3dzZXJfcGF0aCBhcyBzdHJpbmdcbiAgICAgICAgICApO1xuXG4gICAgICAgIGNhc2UgJ3hoc19wdWJsaXNoX2NvbnRlbnQnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZVB1Ymxpc2hDb250ZW50KFxuICAgICAgICAgICAgYXJncz8udHlwZSBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy50aXRsZSBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5jb250ZW50IGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/Lm1lZGlhX3BhdGhzIGFzIHN0cmluZ1tdLFxuICAgICAgICAgICAgYXJncz8udGFncyBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nXG4gICAgICAgICAgKTtcblxuICAgICAgICBjYXNlICd4aHNfZ2V0X3VzZXJfbm90ZXMnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZUdldFVzZXJOb3RlcyhcbiAgICAgICAgICAgIGFyZ3M/LmxpbWl0IGFzIG51bWJlcixcbiAgICAgICAgICAgIGFyZ3M/LmN1cnNvciBhcyBzdHJpbmcsXG4gICAgICAgICAgICBhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nXG4gICAgICAgICAgKTtcblxuICAgICAgICBjYXNlICd4aHNfZGVsZXRlX25vdGUnOlxuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZURlbGV0ZU5vdGUoXG4gICAgICAgICAgICBhcmdzPy5ub3RlX2lkIGFzIHN0cmluZyxcbiAgICAgICAgICAgIGFyZ3M/Lmxhc3RfcHVibGlzaGVkIGFzIGJvb2xlYW4sXG4gICAgICAgICAgICBhcmdzPy5icm93c2VyX3BhdGggYXMgc3RyaW5nXG4gICAgICAgICAgKTtcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB0b29sOiAke25hbWV9YCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFhIU0Vycm9yKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVNY3BUb29sUmVzcG9uc2UoZXJyb3IudG9KU09OKCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZU1jcEVycm9yUmVzcG9uc2UoZXJyb3IpO1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBTaGFyZWQgdXRpbGl0aWVzLCB0eXBlcywgYW5kIHNlcnZpY2VzIGZvciBYSFMgTUNQIFNlcnZlclxuICovXG5cbi8vIENvbmZpZ3VyYXRpb24gYW5kIHR5cGVzXG5leHBvcnQgKiBmcm9tICcuL2NvbmZpZyc7XG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuLy8gVXRpbGl0aWVzXG5leHBvcnQgKiBmcm9tICcuL3V0aWxzJztcbmV4cG9ydCAqIGZyb20gJy4veGhzLnV0aWxzJztcbmV4cG9ydCAqIGZyb20gJy4vY29va2llcyc7XG5leHBvcnQgKiBmcm9tICcuL2ltYWdlLWRvd25sb2FkZXInO1xuZXhwb3J0ICogZnJvbSAnLi90aXRsZS12YWxpZGF0b3InO1xuXG4vLyBFcnJvciBoYW5kbGluZyBhbmQgbG9nZ2luZ1xuZXhwb3J0ICogZnJvbSAnLi9lcnJvcnMnO1xuZXhwb3J0ICogZnJvbSAnLi9sb2dnZXInO1xuXG4vLyBCYXNlIHNlcnZpY2VcbmV4cG9ydCAqIGZyb20gJy4vYmFzZS5zZXJ2aWNlJztcbiIsIi8qKlxuICogUmVzb3VyY2UgcmVxdWVzdCBoYW5kbGVycyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5pbXBvcnQgeyBBdXRoU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvYXV0aC9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgZ2V0Q29uZmlnLCBnZXRDb29raWVzSW5mbyB9IGZyb20gJy4uLy4uL3NoYXJlZC9pbmRleCc7XG5cbmV4cG9ydCBjbGFzcyBSZXNvdXJjZUhhbmRsZXJzIHtcbiAgcHJpdmF0ZSBhdXRoU2VydmljZTogQXV0aFNlcnZpY2U7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy5hdXRoU2VydmljZSA9IG5ldyBBdXRoU2VydmljZShjb25maWcpO1xuICB9XG5cbiAgYXN5bmMgZ2V0Q29va2llc1Jlc291cmNlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvb2tpZXNJbmZvID0gZ2V0Q29va2llc0luZm8oKTtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShjb29raWVzSW5mbywgbnVsbCwgMik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7IGVycm9yOiBTdHJpbmcoZXJyb3IpIH0sIG51bGwsIDIpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldENvbmZpZ1Jlc291cmNlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbmZpZ0RpY3QgPSBnZXRDb25maWcoKTtcbiAgICAgIGNvbnN0IGNvbmZpZ1dpdGhGcmFtZXdvcmsgPSB7XG4gICAgICAgIC4uLmNvbmZpZ0RpY3QsXG4gICAgICAgIGZyYW1ld29yazogJ01DUCBUeXBlU2NyaXB0JyxcbiAgICAgICAgdmVyc2lvbjogY29uZmlnRGljdC5zZXJ2ZXIudmVyc2lvbixcbiAgICAgIH07XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoY29uZmlnV2l0aEZyYW1ld29yaywgbnVsbCwgMik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7IGVycm9yOiBTdHJpbmcoZXJyb3IpIH0sIG51bGwsIDIpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldFN0YXR1c1Jlc291cmNlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFF1aWNrIHN0YXR1cyBjaGVjayAoYnV0IGRvbid0IGZhaWwgaWYgaXQgZXJyb3JzKVxuICAgICAgbGV0IGF1dGhTdGF0dXM6IGFueSA9IHsgc3RhdHVzOiAndW5rbm93bicsIGVycm9yOiAnU3RhdHVzIGNoZWNrIG5vdCBwZXJmb3JtZWQnIH07XG4gICAgICB0cnkge1xuICAgICAgICBhdXRoU3RhdHVzID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5jaGVja1N0YXR1cygpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXV0aFN0YXR1cyA9IHsgc3RhdHVzOiAnZXJyb3InLCBlcnJvcjogU3RyaW5nKGVycm9yKSB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjb29raWVzSW5mbyA9IGdldENvb2tpZXNJbmZvKCk7XG4gICAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcblxuICAgICAgY29uc3Qgc3RhdHVzRGF0YSA9IHtcbiAgICAgICAgc2VydmVyOiB7XG4gICAgICAgICAgc3RhdHVzOiAncnVubmluZycsXG4gICAgICAgICAgbmFtZTogY29uZmlnLnNlcnZlci5uYW1lLFxuICAgICAgICAgIHZlcnNpb246IGNvbmZpZy5zZXJ2ZXIudmVyc2lvbixcbiAgICAgICAgICBmcmFtZXdvcms6ICdNQ1AgVHlwZVNjcmlwdCcsXG4gICAgICAgIH0sXG4gICAgICAgIGF1dGhlbnRpY2F0aW9uOiBhdXRoU3RhdHVzLFxuICAgICAgICBjb29raWVzOiB7XG4gICAgICAgICAgZmlsZUV4aXN0czogY29va2llc0luZm8uZmlsZUV4aXN0cyxcbiAgICAgICAgICBjb29raWVDb3VudDogY29va2llc0luZm8uY29va2llQ291bnQsXG4gICAgICAgIH0sXG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIHRvb2xzQXZhaWxhYmxlOiA4LFxuICAgICAgICAgIHByb21wdHNBdmFpbGFibGU6IDAsXG4gICAgICAgICAgcmVzb3VyY2VzQXZhaWxhYmxlOiAzLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHN0YXR1c0RhdGEsIG51bGwsIDIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHtcbiAgICAgICAgICBzZXJ2ZXI6IHsgc3RhdHVzOiAnZXJyb3InLCBlcnJvcjogU3RyaW5nKGVycm9yKSB9LFxuICAgICAgICAgIGZyYW1ld29yazogJ01DUCBUeXBlU2NyaXB0JyxcbiAgICAgICAgfSxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgMlxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYW5kbGVSZXNvdXJjZVJlcXVlc3QodXJpOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGNvbnRlbnQ6IHN0cmluZztcblxuICAgICAgc3dpdGNoICh1cmkpIHtcbiAgICAgICAgY2FzZSAneGhzOi8vY29va2llcyc6XG4gICAgICAgICAgY29udGVudCA9IGF3YWl0IHRoaXMuZ2V0Q29va2llc1Jlc291cmNlKCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAneGhzOi8vY29uZmlnJzpcbiAgICAgICAgICBjb250ZW50ID0gYXdhaXQgdGhpcy5nZXRDb25maWdSZXNvdXJjZSgpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ3hoczovL3N0YXR1cyc6XG4gICAgICAgICAgY29udGVudCA9IGF3YWl0IHRoaXMuZ2V0U3RhdHVzUmVzb3VyY2UoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biByZXNvdXJjZTogJHt1cml9YCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgIHRleHQ6IGNvbnRlbnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgIHRleHQ6IEpTT04uc3RyaW5naWZ5KHsgZXJyb3I6IFN0cmluZyhlcnJvcikgfSwgbnVsbCwgMiksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIFRvb2wgc2NoZW1hcyBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqL1xuXG5leHBvcnQgaW50ZXJmYWNlIFRvb2xTY2hlbWEge1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGlucHV0U2NoZW1hOiB7XG4gICAgdHlwZTogJ29iamVjdCc7XG4gICAgcHJvcGVydGllczogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICByZXF1aXJlZD86IHN0cmluZ1tdO1xuICB9O1xufVxuXG5leHBvcnQgY29uc3QgWEhTX1RPT0xfU0NIRU1BUzogVG9vbFNjaGVtYVtdID0gW1xuICB7XG4gICAgbmFtZTogJ3hoc19hdXRoX2xvZ2luJyxcbiAgICBkZXNjcmlwdGlvbjogJ1N0YXJ0IFhpYW9Ib25nU2h1IGxvZ2luIHByb2Nlc3MuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19hdXRoX2xvZ291dCcsXG4gICAgZGVzY3JpcHRpb246ICdMb2dvdXQgZnJvbSBYaWFvSG9uZ1NodSAoY2xlYXJzIHNhdmVkIGNvb2tpZXMpLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge30sXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd4aHNfYXV0aF9zdGF0dXMnLFxuICAgIGRlc2NyaXB0aW9uOiAnQ2hlY2sgWGlhb0hvbmdTaHUgbG9naW4gc3RhdHVzIChmYXN0IGNoZWNrIHdpdGggYnJvd3NlcikuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19kaXNjb3Zlcl9mZWVkcycsXG4gICAgZGVzY3JpcHRpb246ICdHZXQgaG9tZSBwYWdlIGZlZWQgbGlzdC4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYnJvd3Nlcl9wYXRoOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPcHRpb25hbCBjdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX3NlYXJjaF9ub3RlJyxcbiAgICBkZXNjcmlwdGlvbjogJ1NlYXJjaCBmb3Igbm90ZXMgYnkga2V5d29yZC4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAga2V5d29yZDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU2VhcmNoIGtleXdvcmQgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ2tleXdvcmQnXSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19nZXRfbm90ZV9kZXRhaWwnLFxuICAgIGRlc2NyaXB0aW9uOiAnR2V0IGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IGEgc3BlY2lmaWMgbm90ZS4nLFxuICAgIGlucHV0U2NoZW1hOiB7XG4gICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgZmVlZF9pZDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRmVlZCBJRCAocmVxdWlyZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgeHNlY190b2tlbjoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU2VjdXJpdHkgdG9rZW4gZm9yIHRoZSBmZWVkIChyZXF1aXJlZCknLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWydmZWVkX2lkJywgJ3hzZWNfdG9rZW4nXSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19jb21tZW50X29uX25vdGUnLFxuICAgIGRlc2NyaXB0aW9uOiAnQ29tbWVudCBvbiBhIG5vdGUuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGZlZWRfaWQ6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0ZlZWQgSUQgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIHhzZWNfdG9rZW46IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1NlY3VyaXR5IHRva2VuIGZvciB0aGUgZmVlZCAocmVxdWlyZWQpJyxcbiAgICAgICAgfSxcbiAgICAgICAgbm90ZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQ29tbWVudCBub3RlIChyZXF1aXJlZCknLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWydmZWVkX2lkJywgJ3hzZWNfdG9rZW4nLCAnbm90ZSddLFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAneGhzX3B1Ymxpc2hfY29udGVudCcsXG4gICAgZGVzY3JpcHRpb246ICdQdWJsaXNoIGNvbnRlbnQgdG8gWGlhb0hvbmdTaHUgKHN1cHBvcnRzIGJvdGggaW1hZ2VzIGFuZCB2aWRlb3MpLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICB0eXBlOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZW51bTogWydpbWFnZScsICd2aWRlbyddLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQ29udGVudCB0eXBlOiBcImltYWdlXCIgZm9yIGltYWdlcywgXCJ2aWRlb1wiIGZvciB2aWRlb3MgKHJlcXVpcmVkKScsXG4gICAgICAgIH0sXG4gICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdDb250ZW50IHRpdGxlIChyZXF1aXJlZCwgbWF4IDIwIGNoYXJhY3RlcnMpJyxcbiAgICAgICAgICBtYXhMZW5ndGg6IDIwLFxuICAgICAgICB9LFxuICAgICAgICBjb250ZW50OiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdDb250ZW50IGRlc2NyaXB0aW9uIChyZXF1aXJlZCwgbWF4IDEwMDAgY2hhcmFjdGVycyknLFxuICAgICAgICAgIG1heExlbmd0aDogMTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVkaWFfcGF0aHM6IHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICAnTGlzdCBvZiBtZWRpYSBmaWxlIHBhdGhzIChyZXF1aXJlZCwgbm9uLWVtcHR5KS4gRm9yIGltYWdlczogMS0xOCBpbWFnZSBmaWxlcy4gRm9yIHZpZGVvczogZXhhY3RseSAxIHZpZGVvIGZpbGUuJyxcbiAgICAgICAgICBtYXhJdGVtczogMTgsXG4gICAgICAgIH0sXG4gICAgICAgIHRhZ3M6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0NvbW1hLXNlcGFyYXRlZCB0YWdzIChvcHRpb25hbCknLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWyd0eXBlJywgJ3RpdGxlJywgJ2NvbnRlbnQnLCAnbWVkaWFfcGF0aHMnXSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19nZXRfdXNlcl9ub3RlcycsXG4gICAgZGVzY3JpcHRpb246ICdHZXQgY3VycmVudCB1c2VyIG5vdGVzIGxpc3QuJyxcbiAgICBpbnB1dFNjaGVtYToge1xuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGxpbWl0OiB7XG4gICAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdOdW1iZXIgb2Ygbm90ZXMgdG8gZmV0Y2ggKGRlZmF1bHQ6IDIwKScsXG4gICAgICAgIH0sXG4gICAgICAgIGN1cnNvcjoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUGFnaW5hdGlvbiBjdXJzb3IgZm9yIG5leHQgcGFnZScsXG4gICAgICAgIH0sXG4gICAgICAgIGJyb3dzZXJfcGF0aDoge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAgbmFtZTogJ3hoc19kZWxldGVfbm90ZScsXG4gICAgZGVzY3JpcHRpb246ICdEZWxldGUgYSB1c2VyIG5vdGUgYnkgSUQgb3IgZGVsZXRlIHRoZSBsYXN0IHB1Ymxpc2hlZCBub3RlLicsXG4gICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBub3RlX2lkOiB7XG4gICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdTcGVjaWZpYyBub3RlIElEIHRvIGRlbGV0ZSAob3B0aW9uYWwgaWYgbGFzdF9wdWJsaXNoZWQgaXMgdHJ1ZSknLFxuICAgICAgICB9LFxuICAgICAgICBsYXN0X3B1Ymxpc2hlZDoge1xuICAgICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0RlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZSAob3B0aW9uYWwgaWYgbm90ZV9pZCBpcyBwcm92aWRlZCknLFxuICAgICAgICB9LFxuICAgICAgICBicm93c2VyX3BhdGg6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09wdGlvbmFsIGN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbl07XG5cbmV4cG9ydCBjb25zdCBYSFNfUkVTT1VSQ0VfU0NIRU1BUyA9IFtcbiAge1xuICAgIHVyaTogJ3hoczovL2Nvb2tpZXMnLFxuICAgIG5hbWU6ICdYSFMgQXV0aGVudGljYXRpb24gQ29va2llcycsXG4gICAgZGVzY3JpcHRpb246ICdDdXJyZW50IFhpYW9Ib25nU2h1IGF1dGhlbnRpY2F0aW9uIGNvb2tpZXMgYW5kIGluZm8nLFxuICAgIG1pbWVUeXBlOiAnYXBwbGljYXRpb24vanNvbicsXG4gIH0sXG4gIHtcbiAgICB1cmk6ICd4aHM6Ly9jb25maWcnLFxuICAgIG5hbWU6ICdYSFMgU2VydmVyIENvbmZpZ3VyYXRpb24nLFxuICAgIGRlc2NyaXB0aW9uOiAnWEhTIE1DUCBzZXJ2ZXIgY29uZmlndXJhdGlvbicsXG4gICAgbWltZVR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgfSxcbiAge1xuICAgIHVyaTogJ3hoczovL3N0YXR1cycsXG4gICAgbmFtZTogJ1hIUyBTZXJ2ZXIgU3RhdHVzJyxcbiAgICBkZXNjcmlwdGlvbjogJ0N1cnJlbnQgc2VydmVyIGFuZCBhdXRoZW50aWNhdGlvbiBzdGF0dXMnLFxuICAgIG1pbWVUeXBlOiAnYXBwbGljYXRpb24vanNvbicsXG4gIH0sXG5dO1xuIiwiLyoqXG4gKiBNQ1AgU2VydmVyIGZvciBYaWFvSG9uZ1NodSBPcGVyYXRpb25zXG4gKi9cblxuaW1wb3J0IHsgU2VydmVyIH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay9zZXJ2ZXIvaW5kZXguanMnO1xuaW1wb3J0IHsgU3RkaW9TZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9zdGRpby5qcyc7XG5pbXBvcnQge1xuICBDYWxsVG9vbFJlcXVlc3RTY2hlbWEsXG4gIExpc3RUb29sc1JlcXVlc3RTY2hlbWEsXG4gIExpc3RSZXNvdXJjZXNSZXF1ZXN0U2NoZW1hLFxuICBSZWFkUmVzb3VyY2VSZXF1ZXN0U2NoZW1hLFxufSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3R5cGVzLmpzJztcbmltcG9ydCB7IGdldENvbmZpZyB9IGZyb20gJy4uL3NoYXJlZC9jb25maWcnO1xuaW1wb3J0IHsgVG9vbEhhbmRsZXJzIH0gZnJvbSAnLi9oYW5kbGVycy90b29sLmhhbmRsZXJzJztcbmltcG9ydCB7IFJlc291cmNlSGFuZGxlcnMgfSBmcm9tICcuL2hhbmRsZXJzL3Jlc291cmNlLmhhbmRsZXJzJztcbmltcG9ydCB7IFhIU19UT09MX1NDSEVNQVMsIFhIU19SRVNPVVJDRV9TQ0hFTUFTIH0gZnJvbSAnLi9zY2hlbWFzL3Rvb2wuc2NoZW1hcyc7XG5cbmV4cG9ydCBjbGFzcyBYSFNNQ1BTZXJ2ZXIge1xuICBwcml2YXRlIHNlcnZlcjogU2VydmVyO1xuICBwcml2YXRlIHRvb2xIYW5kbGVyczogVG9vbEhhbmRsZXJzO1xuICBwcml2YXRlIHJlc291cmNlSGFuZGxlcnM6IFJlc291cmNlSGFuZGxlcnM7XG4gIHByaXZhdGUgY29uZmlnOiBSZXR1cm5UeXBlPHR5cGVvZiBnZXRDb25maWc+O1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy50b29sSGFuZGxlcnMgPSBuZXcgVG9vbEhhbmRsZXJzKCk7XG4gICAgdGhpcy5yZXNvdXJjZUhhbmRsZXJzID0gbmV3IFJlc291cmNlSGFuZGxlcnMoKTtcbiAgICB0aGlzLnNlcnZlciA9IG5ldyBTZXJ2ZXIoXG4gICAgICB7XG4gICAgICAgIG5hbWU6IHRoaXMuY29uZmlnLnNlcnZlci5uYW1lLFxuICAgICAgICB2ZXJzaW9uOiB0aGlzLmNvbmZpZy5zZXJ2ZXIudmVyc2lvbixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIHRvb2xzOiB7fSxcbiAgICAgICAgICByZXNvdXJjZXM6IHt9LFxuICAgICAgICB9LFxuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnNldHVwVG9vbEhhbmRsZXJzKCk7XG4gICAgdGhpcy5zZXR1cFJlc291cmNlSGFuZGxlcnMoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBUb29sSGFuZGxlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoQ2FsbFRvb2xSZXF1ZXN0U2NoZW1hLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgY29uc3QgeyBuYW1lLCBhcmd1bWVudHM6IGFyZ3MgfSA9IHJlcXVlc3QucGFyYW1zO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMudG9vbEhhbmRsZXJzLmhhbmRsZVRvb2xSZXF1ZXN0KG5hbWUsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoTGlzdFRvb2xzUmVxdWVzdFNjaGVtYSwgYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9vbHM6IFhIU19UT09MX1NDSEVNQVMsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cFJlc291cmNlSGFuZGxlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5zZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoTGlzdFJlc291cmNlc1JlcXVlc3RTY2hlbWEsIGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc291cmNlczogWEhTX1JFU09VUkNFX1NDSEVNQVMsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgdGhpcy5zZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoUmVhZFJlc291cmNlUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgIGNvbnN0IHsgdXJpIH0gPSByZXF1ZXN0LnBhcmFtcztcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlc291cmNlSGFuZGxlcnMuaGFuZGxlUmVzb3VyY2VSZXF1ZXN0KHVyaSk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0cmFuc3BvcnQgPSBuZXcgU3RkaW9TZXJ2ZXJUcmFuc3BvcnQoKTtcbiAgICBhd2FpdCB0aGlzLnNlcnZlci5jb25uZWN0KHRyYW5zcG9ydCk7XG4gICAgLy8gRG9uJ3QgbG9nIHRvIHN0ZGVyciBpbiBzdGRpbyBtb2RlIHRvIGF2b2lkIGludGVyZmVyaW5nIHdpdGggTUNQIHByb3RvY29sXG4gIH1cbn1cbiIsImNvbnN0IF9fV0VCUEFDS19OQU1FU1BBQ0VfT0JKRUNUX18gPSByZXF1aXJlKFwiZXhwcmVzc1wiKTsiLCJjb25zdCBfX1dFQlBBQ0tfTkFNRVNQQUNFX09CSkVDVF9fID0gcmVxdWlyZShcImNvcnNcIik7IiwiLyoqXG4gKiBIVFRQIFNlcnZlciB3aXRoIFNTRSBhbmQgU3RyZWFtYWJsZSBIVFRQIFRyYW5zcG9ydCBTdXBwb3J0XG4gKi9cblxuaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgY29ycyBmcm9tICdjb3JzJztcbmltcG9ydCB7IHJhbmRvbVVVSUQgfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgeyBTZXJ2ZXIgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9pbmRleC5qcyc7XG5pbXBvcnQgeyBTU0VTZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9zc2UuanMnO1xuaW1wb3J0IHsgU3RyZWFtYWJsZUhUVFBTZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3NlcnZlci9zdHJlYW1hYmxlSHR0cC5qcyc7XG5pbXBvcnQgeyBpc0luaXRpYWxpemVSZXF1ZXN0IH0gZnJvbSAnQG1vZGVsY29udGV4dHByb3RvY29sL3Nkay90eXBlcy5qcyc7XG5pbXBvcnQgeyBnZXRDb25maWcgfSBmcm9tICcuLi9zaGFyZWQvY29uZmlnJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgVG9vbEhhbmRsZXJzIH0gZnJvbSAnLi9oYW5kbGVycy90b29sLmhhbmRsZXJzJztcbmltcG9ydCB7IFJlc291cmNlSGFuZGxlcnMgfSBmcm9tICcuL2hhbmRsZXJzL3Jlc291cmNlLmhhbmRsZXJzJztcbmltcG9ydCB7IFhIU19UT09MX1NDSEVNQVMsIFhIU19SRVNPVVJDRV9TQ0hFTUFTIH0gZnJvbSAnLi9zY2hlbWFzL3Rvb2wuc2NoZW1hcyc7XG5pbXBvcnQge1xuICBDYWxsVG9vbFJlcXVlc3RTY2hlbWEsXG4gIExpc3RUb29sc1JlcXVlc3RTY2hlbWEsXG4gIExpc3RSZXNvdXJjZXNSZXF1ZXN0U2NoZW1hLFxuICBSZWFkUmVzb3VyY2VSZXF1ZXN0U2NoZW1hLFxufSBmcm9tICdAbW9kZWxjb250ZXh0cHJvdG9jb2wvc2RrL3R5cGVzLmpzJztcblxuZXhwb3J0IGNsYXNzIFhIU0hUVFBNQ1BTZXJ2ZXIge1xuICBwcml2YXRlIGFwcDogZXhwcmVzcy5BcHBsaWNhdGlvbjtcbiAgcHJpdmF0ZSBjb25maWc6IFJldHVyblR5cGU8dHlwZW9mIGdldENvbmZpZz47XG4gIHByaXZhdGUgdG9vbEhhbmRsZXJzOiBUb29sSGFuZGxlcnM7XG4gIHByaXZhdGUgcmVzb3VyY2VIYW5kbGVyczogUmVzb3VyY2VIYW5kbGVycztcbiAgcHJpdmF0ZSB0cmFuc3BvcnRzOiBNYXA8c3RyaW5nLCBTU0VTZXJ2ZXJUcmFuc3BvcnQgfCBTdHJlYW1hYmxlSFRUUFNlcnZlclRyYW5zcG9ydD4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgcG9ydDogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHBvcnQ6IG51bWJlciA9IDMwMDApIHtcbiAgICB0aGlzLnBvcnQgPSBwb3J0O1xuICAgIHRoaXMuY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgdGhpcy50b29sSGFuZGxlcnMgPSBuZXcgVG9vbEhhbmRsZXJzKCk7XG4gICAgdGhpcy5yZXNvdXJjZUhhbmRsZXJzID0gbmV3IFJlc291cmNlSGFuZGxlcnMoKTtcbiAgICB0aGlzLmFwcCA9IGV4cHJlc3MoKTtcblxuICAgIHRoaXMuc2V0dXBNaWRkbGV3YXJlKCk7XG4gICAgdGhpcy5zZXR1cFJvdXRlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cE1pZGRsZXdhcmUoKTogdm9pZCB7XG4gICAgLy8gUGFyc2UgSlNPTiBib2RpZXNcbiAgICB0aGlzLmFwcC51c2UoZXhwcmVzcy5qc29uKCkpO1xuXG4gICAgLy8gQ29uZmlndXJlIENPUlMgdG8gZXhwb3NlIE1jcC1TZXNzaW9uLUlkIGhlYWRlciBmb3IgYnJvd3Nlci1iYXNlZCBjbGllbnRzXG4gICAgdGhpcy5hcHAudXNlKFxuICAgICAgY29ycyh7XG4gICAgICAgIG9yaWdpbjogJyonLCAvLyBBbGxvdyBhbGwgb3JpZ2lucyAtIGFkanVzdCBhcyBuZWVkZWQgZm9yIHByb2R1Y3Rpb25cbiAgICAgICAgZXhwb3NlZEhlYWRlcnM6IFsnTWNwLVNlc3Npb24tSWQnXSxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBSb3V0ZXMoKTogdm9pZCB7XG4gICAgLy8gU3RyZWFtYWJsZSBIVFRQIFRyYW5zcG9ydCAoUHJvdG9jb2wgdmVyc2lvbiAyMDI1LTAzLTI2KVxuICAgIHRoaXMuYXBwLmFsbCgnL21jcCcsIHRoaXMuaGFuZGxlU3RyZWFtYWJsZUhUVFAuYmluZCh0aGlzKSk7XG5cbiAgICAvLyBEZXByZWNhdGVkIEhUVFArU1NFIFRyYW5zcG9ydCAoUHJvdG9jb2wgdmVyc2lvbiAyMDI0LTExLTA1KVxuICAgIHRoaXMuYXBwLmdldCgnL3NzZScsIHRoaXMuaGFuZGxlU1NFQ29ubmVjdGlvbi5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLmFwcC5wb3N0KCcvbWVzc2FnZXMnLCB0aGlzLmhhbmRsZVNTRU1lc3NhZ2UuYmluZCh0aGlzKSk7XG5cbiAgICAvLyBIZWFsdGggY2hlY2sgZW5kcG9pbnRcbiAgICB0aGlzLmFwcC5nZXQoJy9oZWFsdGgnLCAocmVxLCByZXMpID0+IHtcbiAgICAgIHJlcy5qc29uKHtcbiAgICAgICAgc3RhdHVzOiAnaGVhbHRoeScsXG4gICAgICAgIHNlcnZlcjogdGhpcy5jb25maWcuc2VydmVyLm5hbWUsXG4gICAgICAgIHZlcnNpb246IHRoaXMuY29uZmlnLnNlcnZlci52ZXJzaW9uLFxuICAgICAgICB0cmFuc3BvcnRzOiBbJ3N0cmVhbWFibGUtaHR0cCcsICdzc2UnXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVTdHJlYW1hYmxlSFRUUChyZXE6IGV4cHJlc3MuUmVxdWVzdCwgcmVzOiBleHByZXNzLlJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nZ2VyLmluZm8oYFJlY2VpdmVkICR7cmVxLm1ldGhvZH0gcmVxdWVzdCB0byAvbWNwYCk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gQ2hlY2sgZm9yIGV4aXN0aW5nIHNlc3Npb24gSURcbiAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHJlcS5oZWFkZXJzWydtY3Atc2Vzc2lvbi1pZCddIGFzIHN0cmluZztcbiAgICAgIGxldCB0cmFuc3BvcnQ6IFN0cmVhbWFibGVIVFRQU2VydmVyVHJhbnNwb3J0IHwgdW5kZWZpbmVkO1xuXG4gICAgICBpZiAoc2Vzc2lvbklkICYmIHRoaXMudHJhbnNwb3J0cy5oYXMoc2Vzc2lvbklkKSkge1xuICAgICAgICBjb25zdCBleGlzdGluZ1RyYW5zcG9ydCA9IHRoaXMudHJhbnNwb3J0cy5nZXQoc2Vzc2lvbklkKTtcbiAgICAgICAgaWYgKGV4aXN0aW5nVHJhbnNwb3J0IGluc3RhbmNlb2YgU3RyZWFtYWJsZUhUVFBTZXJ2ZXJUcmFuc3BvcnQpIHtcbiAgICAgICAgICB0cmFuc3BvcnQgPSBleGlzdGluZ1RyYW5zcG9ydDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMuc3RhdHVzKDQwMCkuanNvbih7XG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICAgIGNvZGU6IC0zMjAwMCxcbiAgICAgICAgICAgICAgbWVzc2FnZTogJ0JhZCBSZXF1ZXN0OiBTZXNzaW9uIGV4aXN0cyBidXQgdXNlcyBhIGRpZmZlcmVudCB0cmFuc3BvcnQgcHJvdG9jb2wnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghc2Vzc2lvbklkICYmIHJlcS5tZXRob2QgPT09ICdQT1NUJyAmJiBpc0luaXRpYWxpemVSZXF1ZXN0KHJlcS5ib2R5KSkge1xuICAgICAgICAvLyBDcmVhdGUgbmV3IFN0cmVhbWFibGUgSFRUUCB0cmFuc3BvcnRcbiAgICAgICAgdHJhbnNwb3J0ID0gbmV3IFN0cmVhbWFibGVIVFRQU2VydmVyVHJhbnNwb3J0KHtcbiAgICAgICAgICBzZXNzaW9uSWRHZW5lcmF0b3I6ICgpOiBzdHJpbmcgPT4gcmFuZG9tVVVJRCgpLFxuICAgICAgICAgIG9uc2Vzc2lvbmluaXRpYWxpemVkOiAoc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBTdHJlYW1hYmxlSFRUUCBzZXNzaW9uIGluaXRpYWxpemVkIHdpdGggSUQ6ICR7c2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgdGhpcy50cmFuc3BvcnRzLnNldChzZXNzaW9uSWQsIHRyYW5zcG9ydCEpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgb25zZXNzaW9uY2xvc2VkOiAoc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBTdHJlYW1hYmxlSFRUUCBzZXNzaW9uIGNsb3NlZDogJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICB0aGlzLnRyYW5zcG9ydHMuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIG9uY2xvc2UgaGFuZGxlciB0byBjbGVhbiB1cCB0cmFuc3BvcnQgd2hlbiBjbG9zZWRcbiAgICAgICAgdHJhbnNwb3J0Lm9uY2xvc2UgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgY29uc3Qgc2lkID0gdHJhbnNwb3J0IS5zZXNzaW9uSWQ7XG4gICAgICAgICAgaWYgKHNpZCAmJiB0aGlzLnRyYW5zcG9ydHMuaGFzKHNpZCkpIHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBUcmFuc3BvcnQgY2xvc2VkIGZvciBzZXNzaW9uICR7c2lkfSwgcmVtb3ZpbmcgZnJvbSB0cmFuc3BvcnRzIG1hcGApO1xuICAgICAgICAgICAgdGhpcy50cmFuc3BvcnRzLmRlbGV0ZShzaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBDb25uZWN0IHRoZSB0cmFuc3BvcnQgdG8gdGhlIE1DUCBzZXJ2ZXJcbiAgICAgICAgY29uc3Qgc2VydmVyID0gdGhpcy5jcmVhdGVNQ1BTZXJ2ZXIoKTtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEludmFsaWQgcmVxdWVzdCAtIG5vIHNlc3Npb24gSUQgb3Igbm90IGluaXRpYWxpemF0aW9uIHJlcXVlc3RcbiAgICAgICAgcmVzLnN0YXR1cyg0MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzIwMDAsXG4gICAgICAgICAgICBtZXNzYWdlOiAnQmFkIFJlcXVlc3Q6IE5vIHZhbGlkIHNlc3Npb24gSUQgcHJvdmlkZWQnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSB0aGUgcmVxdWVzdCB3aXRoIHRoZSB0cmFuc3BvcnRcbiAgICAgIGF3YWl0IHRyYW5zcG9ydC5oYW5kbGVSZXF1ZXN0KHJlcSwgcmVzLCByZXEuYm9keSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgaGFuZGxpbmcgU3RyZWFtYWJsZSBIVFRQIHJlcXVlc3Q6JywgZXJyb3IpO1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzI2MDMsXG4gICAgICAgICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVNTRUNvbm5lY3Rpb24ocmVxOiBleHByZXNzLlJlcXVlc3QsIHJlczogZXhwcmVzcy5SZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZ2dlci5pbmZvKCdSZWNlaXZlZCBHRVQgcmVxdWVzdCB0byAvc3NlIChkZXByZWNhdGVkIFNTRSB0cmFuc3BvcnQpJyk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFNTRVNlcnZlclRyYW5zcG9ydCgnL21lc3NhZ2VzJywgcmVzKTtcbiAgICAgIHRoaXMudHJhbnNwb3J0cy5zZXQodHJhbnNwb3J0LnNlc3Npb25JZCwgdHJhbnNwb3J0KTtcblxuICAgICAgcmVzLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgdGhpcy50cmFuc3BvcnRzLmRlbGV0ZSh0cmFuc3BvcnQuc2Vzc2lvbklkKTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzZXJ2ZXIgPSB0aGlzLmNyZWF0ZU1DUFNlcnZlcigpO1xuICAgICAgYXdhaXQgc2VydmVyLmNvbm5lY3QodHJhbnNwb3J0KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBoYW5kbGluZyBTU0UgY29ubmVjdGlvbjonLCBlcnJvcik7XG4gICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCkge1xuICAgICAgICByZXMuc3RhdHVzKDUwMCkuanNvbih7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgIGNvZGU6IC0zMjYwMyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBzZXJ2ZXIgZXJyb3InLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlU1NFTWVzc2FnZShyZXE6IGV4cHJlc3MuUmVxdWVzdCwgcmVzOiBleHByZXNzLlJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc2Vzc2lvbklkID0gcmVxLnF1ZXJ5LnNlc3Npb25JZCBhcyBzdHJpbmc7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzLmdldChzZXNzaW9uSWQpO1xuXG4gICAgICBpZiAoIXRyYW5zcG9ydCB8fCAhKHRyYW5zcG9ydCBpbnN0YW5jZW9mIFNTRVNlcnZlclRyYW5zcG9ydCkpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg0MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzIwMDAsXG4gICAgICAgICAgICBtZXNzYWdlOiAnQmFkIFJlcXVlc3Q6IFNlc3Npb24gZXhpc3RzIGJ1dCB1c2VzIGEgZGlmZmVyZW50IHRyYW5zcG9ydCBwcm90b2NvbCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpZDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdHJhbnNwb3J0LmhhbmRsZVBvc3RNZXNzYWdlKHJlcSwgcmVzLCByZXEuYm9keSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgaGFuZGxpbmcgU1NFIG1lc3NhZ2U6JywgZXJyb3IpO1xuICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgcmVzLnN0YXR1cyg1MDApLmpzb24oe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICBjb2RlOiAtMzI2MDMsXG4gICAgICAgICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlkOiBudWxsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU1DUFNlcnZlcigpOiBTZXJ2ZXIge1xuICAgIGNvbnN0IHNlcnZlciA9IG5ldyBTZXJ2ZXIoXG4gICAgICB7XG4gICAgICAgIG5hbWU6IHRoaXMuY29uZmlnLnNlcnZlci5uYW1lLFxuICAgICAgICB2ZXJzaW9uOiB0aGlzLmNvbmZpZy5zZXJ2ZXIudmVyc2lvbixcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICAgIHRvb2xzOiB7fSxcbiAgICAgICAgICByZXNvdXJjZXM6IHt9LFxuICAgICAgICB9LFxuICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBTZXR1cCB0b29sIGhhbmRsZXJzXG4gICAgc2VydmVyLnNldFJlcXVlc3RIYW5kbGVyKENhbGxUb29sUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgIGNvbnN0IHsgbmFtZSwgYXJndW1lbnRzOiBhcmdzIH0gPSByZXF1ZXN0LnBhcmFtcztcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnRvb2xIYW5kbGVycy5oYW5kbGVUb29sUmVxdWVzdChuYW1lLCBhcmdzKTtcbiAgICB9KTtcblxuICAgIHNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihMaXN0VG9vbHNSZXF1ZXN0U2NoZW1hLCBhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0b29sczogWEhTX1RPT0xfU0NIRU1BUyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBTZXR1cCByZXNvdXJjZSBoYW5kbGVyc1xuICAgIHNlcnZlci5zZXRSZXF1ZXN0SGFuZGxlcihMaXN0UmVzb3VyY2VzUmVxdWVzdFNjaGVtYSwgYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVzb3VyY2VzOiBYSFNfUkVTT1VSQ0VfU0NIRU1BUyxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBzZXJ2ZXIuc2V0UmVxdWVzdEhhbmRsZXIoUmVhZFJlc291cmNlUmVxdWVzdFNjaGVtYSwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgIGNvbnN0IHsgdXJpIH0gPSByZXF1ZXN0LnBhcmFtcztcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlc291cmNlSGFuZGxlcnMuaGFuZGxlUmVzb3VyY2VSZXF1ZXN0KHVyaSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2VydmVyO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHNlcnZlciA9IHRoaXMuYXBwLmxpc3Rlbih0aGlzLnBvcnQsIChlcnJvcj86IEVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignRmFpbGVkIHRvIHN0YXJ0IEhUVFAgc2VydmVyOicsIGVycm9yKTtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGBYSFMgTUNQIEhUVFAgU2VydmVyIGxpc3RlbmluZyBvbiBwb3J0ICR7dGhpcy5wb3J0fWApO1xuICAgICAgICBjb25zb2xlLmxvZyhgXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5TVVBQT1JURUQgVFJBTlNQT1JUIE9QVElPTlM6XG5cbjEuIFN0cmVhbWFibGUgSFRUUCAoUHJvdG9jb2wgdmVyc2lvbjogMjAyNS0wMy0yNilcbiAgIEVuZHBvaW50OiAvbWNwXG4gICBNZXRob2RzOiBHRVQsIFBPU1QsIERFTEVURVxuICAgVXNhZ2U6XG4gICAgIC0gSW5pdGlhbGl6ZSB3aXRoIFBPU1QgdG8gL21jcFxuICAgICAtIEVzdGFibGlzaCBTU0Ugc3RyZWFtIHdpdGggR0VUIHRvIC9tY3BcbiAgICAgLSBTZW5kIHJlcXVlc3RzIHdpdGggUE9TVCB0byAvbWNwXG4gICAgIC0gVGVybWluYXRlIHNlc3Npb24gd2l0aCBERUxFVEUgdG8gL21jcFxuXG4yLiBIVFRQICsgU1NFIChQcm90b2NvbCB2ZXJzaW9uOiAyMDI0LTExLTA1KVxuICAgRW5kcG9pbnRzOiAvc3NlIChHRVQpIGFuZCAvbWVzc2FnZXMgKFBPU1QpXG4gICBVc2FnZTpcbiAgICAgLSBFc3RhYmxpc2ggU1NFIHN0cmVhbSB3aXRoIEdFVCB0byAvc3NlXG4gICAgIC0gU2VuZCByZXF1ZXN0cyB3aXRoIFBPU1QgdG8gL21lc3NhZ2VzP3Nlc3Npb25JZD08aWQ+XG5cbjMuIEhlYWx0aCBDaGVja1xuICAgRW5kcG9pbnQ6IC9oZWFsdGhcbiAgIE1ldGhvZDogR0VUXG4gICBVc2FnZTogQ2hlY2sgc2VydmVyIHN0YXR1cyBhbmQgc3VwcG9ydGVkIHRyYW5zcG9ydHNcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmApO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gSGFuZGxlIHNlcnZlciBzaHV0ZG93blxuICAgICAgcHJvY2Vzcy5vbignU0lHSU5UJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBsb2dnZXIuaW5mbygnU2h1dHRpbmcgZG93biBIVFRQIHNlcnZlci4uLicpO1xuXG4gICAgICAgIGZvciAoY29uc3QgW3Nlc3Npb25JZCwgdHJhbnNwb3J0XSBvZiB0aGlzLnRyYW5zcG9ydHMpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYENsb3NpbmcgdHJhbnNwb3J0IGZvciBzZXNzaW9uICR7c2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgYXdhaXQgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgRXJyb3IgY2xvc2luZyB0cmFuc3BvcnQgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9OmAsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRyYW5zcG9ydHMuY2xlYXIoKTtcbiAgICAgICAgc2VydmVyLmNsb3NlKCgpID0+IHtcbiAgICAgICAgICBsb2dnZXIuaW5mbygnSFRUUCBzZXJ2ZXIgc2h1dGRvd24gY29tcGxldGUnKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHByb2Nlc3Mub24oJ1NJR1RFUk0nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdTaHV0dGluZyBkb3duIEhUVFAgc2VydmVyLi4uJyk7XG5cbiAgICAgICAgZm9yIChjb25zdCBbc2Vzc2lvbklkLCB0cmFuc3BvcnRdIG9mIHRoaXMudHJhbnNwb3J0cykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhgQ2xvc2luZyB0cmFuc3BvcnQgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICBhd2FpdCB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBjbG9zaW5nIHRyYW5zcG9ydCBmb3Igc2Vzc2lvbiAke3Nlc3Npb25JZH06YCwgZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudHJhbnNwb3J0cy5jbGVhcigpO1xuICAgICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4ge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKCdIVFRQIHNlcnZlciBzaHV0ZG93biBjb21wbGV0ZScpO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQ2xvc2UgYWxsIGFjdGl2ZSB0cmFuc3BvcnRzXG4gICAgZm9yIChjb25zdCBbc2Vzc2lvbklkLCB0cmFuc3BvcnRdIG9mIHRoaXMudHJhbnNwb3J0cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYEVycm9yIGNsb3NpbmcgdHJhbnNwb3J0IGZvciBzZXNzaW9uICR7c2Vzc2lvbklkfTpgLCBlcnJvcik7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudHJhbnNwb3J0cy5jbGVhcigpO1xuICB9XG59XG4iLCIvKipcbiAqIFJlcXVlc3QgaGFuZGxlcnMgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi90b29sLmhhbmRsZXJzJztcbmV4cG9ydCAqIGZyb20gJy4vcmVzb3VyY2UuaGFuZGxlcnMnO1xuIiwiLyoqXG4gKiBTZXJ2ZXIgaW1wbGVtZW50YXRpb24gZm9yIFhIUyBNQ1AgU2VydmVyXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9tY3Auc2VydmVyJztcbmV4cG9ydCAqIGZyb20gJy4vaHR0cC5zZXJ2ZXInO1xuZXhwb3J0ICogZnJvbSAnLi9oYW5kbGVycy9pbmRleCc7XG4iLCIjIS91c3IvYmluL2VudiBub2RlXG5cbi8qKlxuICogVW5pZmllZCBDTEkgZm9yIFhpYW9Ib25nU2h1IG9wZXJhdGlvbnNcbiAqL1xuXG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCB7IGdldENvbmZpZyB9IGZyb20gJy4uL3NoYXJlZC9jb25maWcnO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLi9jb3JlL2F1dGgvYXV0aC5zZXJ2aWNlJztcbmltcG9ydCBwdXBwZXRlZXIgZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IHNwYXduU3luYyB9IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgeyBYSFNNQ1BTZXJ2ZXIsIFhIU0hUVFBNQ1BTZXJ2ZXIgfSBmcm9tICcuLi9zZXJ2ZXIvaW5kZXgnO1xuaW1wb3J0IHsgWEhTX1RPT0xfU0NIRU1BUyB9IGZyb20gJy4uL3NlcnZlci9zY2hlbWFzL3Rvb2wuc2NoZW1hcyc7XG5pbXBvcnQgeyBGZWVkU2VydmljZSB9IGZyb20gJy4uL2NvcmUvZmVlZHMvZmVlZC5zZXJ2aWNlJztcbmltcG9ydCB7IFB1Ymxpc2hTZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9wdWJsaXNoaW5nL3B1Ymxpc2guc2VydmljZSc7XG5pbXBvcnQgeyBOb3RlU2VydmljZSB9IGZyb20gJy4uL2NvcmUvbm90ZXMvbm90ZS5zZXJ2aWNlJztcblxuLyoqXG4gKiBDTEkgdXRpbGl0eSBmdW5jdGlvbnNcbiAqL1xuY2xhc3MgQ0xJVXRpbHMge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHByb2dyYW06IENvbW1hbmQpIHt9XG5cbiAgZm9ybWF0RXJyb3JNZXNzYWdlKGVycm9yOiB1bmtub3duKTogc3RyaW5nIHtcbiAgICBjb25zdCByYXcgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gKGVycm9yLnN0YWNrID8/IGVycm9yLm1lc3NhZ2UpIDogU3RyaW5nKGVycm9yKTtcblxuICAgIC8vIEhhbmRsZSBzcGVjaWZpYyBlcnJvciBwYXR0ZXJuc1xuICAgIGlmICgvRXhlY3V0YWJsZSBkb2Vzbid0IGV4aXN0fHB1cHBldGVlciBicm93c2VycyBpbnN0YWxsL2kudGVzdChyYXcpKSB7XG4gICAgICByZXR1cm4gJ0Nocm9taXVtIGlzIG5vdCBpbnN0YWxsZWQuIFJ1bjogbnB4IHB1cHBldGVlciBicm93c2VycyBpbnN0YWxsIGNocm9tZSBvciB4aHMtbWNwIGJyb3dzZXInO1xuICAgIH1cblxuICAgIC8vIEZvciB1c2VyLWZhY2luZyBlcnJvcnMsIGp1c3QgcmV0dXJuIHRoZSBtZXNzYWdlIHdpdGhvdXQgc3RhY2sgdHJhY2VcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIGtub3duIGVycm9yIHR5cGUgdGhhdCBzaG91bGQgc2hvdyBqdXN0IHRoZSBtZXNzYWdlXG4gICAgICBpZiAoXG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ0VpdGhlciAtLW5vdGUtaWQgb3IgLS1sYXN0LXB1Ymxpc2hlZCBtdXN0IGJlIHNwZWNpZmllZCcpIHx8XG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ1BsZWFzZSBzcGVjaWZ5IGVpdGhlcicpIHx8XG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ1VzZXIgbm90IGxvZ2dlZCBpbicpIHx8XG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ05vdGUgbm90IGZvdW5kJykgfHxcbiAgICAgICAgZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnRGVsZXRlIGJ1dHRvbiBub3QgZm91bmQnKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBlcnJvci5tZXNzYWdlO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3Igb3RoZXIgZXJyb3JzLCBzaG93IGEgY2xlYW5lciB2ZXJzaW9uXG4gICAgICBjb25zdCBjb25kZW5zZWQgPSByYXdcbiAgICAgICAgLnJlcGxhY2UoXG4gICAgICAgICAgL1tcXHNcXFNdKj9Mb29rcyBsaWtlIFB1cHBldGVlcltcXHNcXFNdKj9QbGVhc2UgcnVuIHRoZSBmb2xsb3dpbmcgY29tbWFuZCB0byBkb3dubG9hZCBuZXcgYnJvd3NlcnM6W1xcc1xcU10qP25weCBwdXBwZXRlZXIgYnJvd3NlcnMgaW5zdGFsbFtcXHNcXFNdKj8oUHVwcGV0ZWVyIFRlYW1bXFxzXFxTXSo/KSo/L20sXG4gICAgICAgICAgJydcbiAgICAgICAgKVxuICAgICAgICAucmVwbGFjZSgvW1xcdTI1MDAtXFx1MjU3Rl0rL2csICcnKSAvLyBib3gtZHJhd2luZyBjaGFyYWN0ZXJzXG4gICAgICAgIC5yZXBsYWNlKC9cXHMrYXRcXHMrLiokL2dtLCAnJykgLy8gUmVtb3ZlIHN0YWNrIHRyYWNlIGxpbmVzXG4gICAgICAgIC50cmltKCk7XG5cbiAgICAgIHJldHVybiBjb25kZW5zZWQgfHwgZXJyb3IubWVzc2FnZTtcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nKGVycm9yKTtcbiAgfVxuXG4gIHdyaXRlSnNvbihvdXRwdXQ6IHVua25vd24sIGV4aXRDb2RlID0gMCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbXBhY3QgPSB0aGlzLnByb2dyYW0uZ2V0T3B0aW9uVmFsdWU/LignY29tcGFjdCcpID09PSB0cnVlO1xuICAgIGNvbnN0IGpzb24gPSBjb21wYWN0ID8gSlNPTi5zdHJpbmdpZnkob3V0cHV0KSA6IEpTT04uc3RyaW5naWZ5KG91dHB1dCwgbnVsbCwgMik7XG4gICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoYCR7anNvbn1cXG5gKTtcbiAgICAvLyBGbHVzaCBzdGRvdXQgYmVmb3JlIGV4aXRpbmcgdG8gZW5zdXJlIG91dHB1dCBpcyB2aXNpYmxlXG4gICAgaWYgKHByb2Nlc3Muc3Rkb3V0LndyaXRhYmxlKSB7XG4gICAgICBwcm9jZXNzLnN0ZG91dC5lbmQoKTtcbiAgICB9XG4gICAgcHJvY2Vzcy5leGl0KGV4aXRDb2RlKTtcbiAgfVxuXG4gIHByaW50U3VjY2VzcyhyZXN1bHQ6IHVua25vd24sIG1lc3NhZ2U/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyBJZiByZXN1bHQgYWxyZWFkeSBoYXMgc3VjY2VzcyBmaWVsZCwgcHJpbnQgaXQgZGlyZWN0bHlcbiAgICBpZiAocmVzdWx0ICYmIHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnICYmICdzdWNjZXNzJyBpbiByZXN1bHQpIHtcbiAgICAgIHRoaXMud3JpdGVKc29uKHJlc3VsdCwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE90aGVyd2lzZSwgd3JhcCBpdFxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSA/PyAocmVzdWx0IGFzIHsgbWVzc2FnZT86IHN0cmluZyB9KT8ubWVzc2FnZSA/PyB1bmRlZmluZWQsXG4gICAgICAgIGRhdGE6IHJlc3VsdCxcbiAgICAgIH07XG4gICAgICB0aGlzLndyaXRlSnNvbihwYXlsb2FkLCAwKTtcbiAgICB9XG4gIH1cblxuICBwcmludEVycm9yKGVycm9yOiB1bmtub3duLCBjb2RlPzogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZSA9IHRoaXMuZm9ybWF0RXJyb3JNZXNzYWdlKGVycm9yKTtcbiAgICBjb25zdCBwYXlsb2FkID0geyBzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZSwgY29kZTogY29kZSA/PyB1bmRlZmluZWQsIHN0YXR1czogJ2Vycm9yJyB9IGFzIGNvbnN0O1xuICAgIHRoaXMud3JpdGVKc29uKHBheWxvYWQsIDEpO1xuICB9XG5cbiAgcHJpbnRVc2FnZUVycm9yKGNvbW1hbmQ6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIHN0YXR1czogJ2Vycm9yJyxcbiAgICAgIHVzYWdlOiBgVXNlICd4aHMtbWNwICR7Y29tbWFuZH0gLS1oZWxwJyBmb3IgbW9yZSBpbmZvcm1hdGlvbmAsXG4gICAgfSBhcyBjb25zdDtcbiAgICB0aGlzLndyaXRlSnNvbihwYXlsb2FkLCAxKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBtYWluKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcbiAgY29uc3QgcHJvZ3JhbSA9IG5ldyBDb21tYW5kKCk7XG4gIGNvbnN0IHV0aWxzID0gbmV3IENMSVV0aWxzKHByb2dyYW0pO1xuXG4gIHByb2dyYW1cbiAgICAubmFtZSgneGhzLW1jcCcpXG4gICAgLmRlc2NyaXB0aW9uKCdYaWFvSG9uZ1NodSBDTEkgd2l0aCBzdWJjb21tYW5kcycpXG4gICAgLm9wdGlvbignLS1jb21wYWN0JywgJ091dHB1dCBjb21wYWN0IG9uZS1saW5lIEpTT04gKG5vIHByZXR0eSBwcmludCknKVxuICAgIC5zaG93SGVscEFmdGVyRXJyb3IoKTtcblxuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ2xvZ2luJylcbiAgICAuZGVzY3JpcHRpb24oJ1N0YXJ0IFhpYW9Ib25nU2h1IGxvZ2luIGZsb3cgKG9wZW5zIGJyb3dzZXIsIHNhdmVzIGNvb2tpZXMpJylcbiAgICAub3B0aW9uKCctdCwgLS10aW1lb3V0IDxzZWNvbmRzPicsICdMb2dpbiB0aW1lb3V0IGluIHNlY29uZHMnLCBgJHtjb25maWcuYnJvd3Nlci5sb2dpblRpbWVvdXR9YClcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7IHRpbWVvdXQ/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgY29uc3QgYnJvd3NlclBhdGggPSB1bmRlZmluZWQ7XG4gICAgICBjb25zdCB0aW1lb3V0U2VjID0gb3B0cy50aW1lb3V0ID8gcGFyc2VJbnQob3B0cy50aW1lb3V0LCAxMCkgOiBjb25maWcuYnJvd3Nlci5sb2dpblRpbWVvdXQ7XG4gICAgICBjb25zdCBhdXRoU2VydmljZSA9IG5ldyBBdXRoU2VydmljZShjb25maWcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXV0aFNlcnZpY2UubG9naW4oYnJvd3NlclBhdGgsIHRpbWVvdXRTZWMpO1xuICAgICAgICB1dGlscy5wcmludFN1Y2Nlc3MocmVzdWx0KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHV0aWxzLnByaW50RXJyb3IoZXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnbG9nb3V0JylcbiAgICAuZGVzY3JpcHRpb24oJ0xvZ291dCBmcm9tIFhpYW9Ib25nU2h1IGFuZCBjbGVhciBzYXZlZCBjb29raWVzJylcbiAgICAuYWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGF1dGhTZXJ2aWNlID0gbmV3IEF1dGhTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhdXRoU2VydmljZS5sb2dvdXQoKTtcbiAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ3N0YXR1cycpXG4gICAgLmRlc2NyaXB0aW9uKCdDaGVjayBjdXJyZW50IFhpYW9Ib25nU2h1IGxvZ2luIHN0YXR1cycpXG4gICAgLmFjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBicm93c2VyUGF0aCA9IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IGF1dGhTZXJ2aWNlID0gbmV3IEF1dGhTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhdXRoU2VydmljZS5jaGVja1N0YXR1cyhicm93c2VyUGF0aCk7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhyZXN1bHQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCdicm93c2VyJylcbiAgICAuZGVzY3JpcHRpb24oJ0Vuc3VyZSBQdXBwZXRlZXIgQ2hyb21pdW0gaXMgaW5zdGFsbGVkIGFuZCBsYXVuY2hhYmxlOyBpbnN0YWxscyBpZiBtaXNzaW5nJylcbiAgICAub3B0aW9uKCctLXdpdGgtZGVwcycsICdJbnN0YWxsIE9TLWxldmVsIGRlcGVuZGVuY2llcyBhcyB3ZWxsIChtYXkgcmVxdWlyZSBzdWRvKScpXG4gICAgLmFjdGlvbihhc3luYyAob3B0czogeyB3aXRoRGVwcz86IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgYXN5bmMgZnVuY3Rpb24gY2FuTGF1bmNoQ2hyb21pdW0oKTogUHJvbWlzZTx7IGNhbkxhdW5jaDogYm9vbGVhbjsgZXhlY3V0YWJsZVBhdGg/OiBzdHJpbmcgfT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIEdldCB0aGUgZXhlY3V0YWJsZSBwYXRoIGJlZm9yZSBsYXVuY2hpbmdcbiAgICAgICAgICBjb25zdCBleGVjdXRhYmxlUGF0aCA9IHB1cHBldGVlci5leGVjdXRhYmxlUGF0aCgpO1xuXG4gICAgICAgICAgY29uc3QgYnJvd3NlciA9IGF3YWl0IHB1cHBldGVlci5sYXVuY2goeyBoZWFkbGVzczogdHJ1ZSB9KTtcbiAgICAgICAgICBhd2FpdCBicm93c2VyLmNsb3NlKCk7XG5cbiAgICAgICAgICByZXR1cm4geyBjYW5MYXVuY2g6IHRydWUsIGV4ZWN1dGFibGVQYXRoIH07XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJldHVybiB7IGNhbkxhdW5jaDogZmFsc2UgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBicm93c2VySW5mbyA9IGF3YWl0IGNhbkxhdW5jaENocm9taXVtKCk7XG4gICAgICBpZiAoYnJvd3NlckluZm8uY2FuTGF1bmNoKSB7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpbnN0YWxsZWQ6IHRydWUsXG4gICAgICAgICAgICBleGVjdXRhYmxlUGF0aDogYnJvd3NlckluZm8uZXhlY3V0YWJsZVBhdGgsXG4gICAgICAgICAgfSxcbiAgICAgICAgICAnQ2hyb21pdW0gaXMgcmVhZHknXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYXJncyA9IFsncHVwcGV0ZWVyJywgJ2Jyb3dzZXJzJywgJ2luc3RhbGwnLCAnY2hyb21lJ107XG4gICAgICBpZiAob3B0cy53aXRoRGVwcykgYXJncy5wdXNoKCctLXdpdGgtZGVwcycpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gc3Bhd25TeW5jKCducHgnLCBhcmdzLCB7IHN0ZGlvOiAnaW5oZXJpdCcsIGVudjogcHJvY2Vzcy5lbnYgfSk7XG5cbiAgICAgIGNvbnN0IGFmdGVySW5zdGFsbEluZm8gPSBhd2FpdCBjYW5MYXVuY2hDaHJvbWl1bSgpO1xuICAgICAgaWYgKGFmdGVySW5zdGFsbEluZm8uY2FuTGF1bmNoKSB7XG4gICAgICAgIHV0aWxzLnByaW50U3VjY2VzcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpbnN0YWxsZWQ6IHRydWUsXG4gICAgICAgICAgICBleGVjdXRhYmxlUGF0aDogYWZ0ZXJJbnN0YWxsSW5mby5leGVjdXRhYmxlUGF0aCxcbiAgICAgICAgICAgIGV4aXRDb2RlOiByZXN1bHQuc3RhdHVzID8/IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICAnQ2hyb21pdW0gaW5zdGFsbGVkIGFuZCByZWFkeSdcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHV0aWxzLnByaW50RXJyb3IobmV3IEVycm9yKCdGYWlsZWQgdG8gaW5zdGFsbCBvciBsYXVuY2ggQ2hyb21pdW0nKSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLy8gRmVlZHM6IGRpc2NvdmVyXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnZmVlZHMnKVxuICAgIC5kZXNjcmlwdGlvbignRGlzY292ZXIgaG9tZSBwYWdlIGZlZWRzJylcbiAgICAub3B0aW9uKCctYiwgLS1icm93c2VyLXBhdGggPHBhdGg+JywgJ0N1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJylcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7IGJyb3dzZXJQYXRoPzogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IGZlZWRTZXJ2aWNlID0gbmV3IEZlZWRTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmZWVkU2VydmljZS5nZXRGZWVkTGlzdChvcHRzLmJyb3dzZXJQYXRoKTtcbiAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAvLyBGZWVkczogc2VhcmNoIG5vdGVcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCdzZWFyY2gnKVxuICAgIC5kZXNjcmlwdGlvbignU2VhcmNoIG5vdGVzIGJ5IGtleXdvcmQnKVxuICAgIC5yZXF1aXJlZE9wdGlvbignLWssIC0ta2V5d29yZCA8a2V5d29yZD4nLCAnU2VhcmNoIGtleXdvcmQnKVxuICAgIC5vcHRpb24oJy1iLCAtLWJyb3dzZXItcGF0aCA8cGF0aD4nLCAnQ3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdHM6IHsga2V5d29yZDogc3RyaW5nOyBicm93c2VyUGF0aD86IHN0cmluZyB9KSA9PiB7XG4gICAgICBjb25zdCBmZWVkU2VydmljZSA9IG5ldyBGZWVkU2VydmljZShjb25maWcpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmVlZFNlcnZpY2Uuc2VhcmNoRmVlZHMob3B0cy5rZXl3b3JkLCBvcHRzLmJyb3dzZXJQYXRoKTtcbiAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAvLyBVc2VyIE5vdGVzOiB1bmlmaWVkIGNvbW1hbmQgd2l0aCBzdWJjb21tYW5kc1xuICBjb25zdCB1c2VyTm90ZUNvbW1hbmQgPSBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ3VzZXJub3RlJylcbiAgICAuZGVzY3JpcHRpb24oXCJDdXJyZW50IHVzZXIncyBub3RlIG1hbmFnZW1lbnQgb3BlcmF0aW9uc1wiKTtcblxuICAvLyBVc2VyIE5vdGUgbGlzdCBzdWJjb21tYW5kXG4gIHVzZXJOb3RlQ29tbWFuZFxuICAgIC5jb21tYW5kKCdsaXN0JylcbiAgICAuZGVzY3JpcHRpb24oXCJMaXN0IGN1cnJlbnQgdXNlcidzIHB1Ymxpc2hlZCBub3Rlc1wiKVxuICAgIC5vcHRpb24oJy1sLCAtLWxpbWl0IDxudW1iZXI+JywgJ01heGltdW0gbnVtYmVyIG9mIG5vdGVzIHRvIHJldHJpZXZlJywgJzIwJylcbiAgICAub3B0aW9uKCctYywgLS1jdXJzb3IgPGN1cnNvcj4nLCAnUGFnaW5hdGlvbiBjdXJzb3IgZm9yIG5leHQgcGFnZScpXG4gICAgLm9wdGlvbignLWIsIC0tYnJvd3Nlci1wYXRoIDxwYXRoPicsICdDdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcpXG4gICAgLmFjdGlvbihhc3luYyAob3B0czogeyBsaW1pdDogc3RyaW5nOyBjdXJzb3I/OiBzdHJpbmc7IGJyb3dzZXJQYXRoPzogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IG5vdGVTZXJ2aWNlID0gbmV3IE5vdGVTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBsaW1pdCA9IHBhcnNlSW50KG9wdHMubGltaXQpIHx8IDIwO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBub3RlU2VydmljZS5nZXRVc2VyTm90ZXMobGltaXQsIG9wdHMuY3Vyc29yLCBvcHRzLmJyb3dzZXJQYXRoKTtcbiAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAvLyBVc2VyIE5vdGUgZGVsZXRlIHN1YmNvbW1hbmRcbiAgdXNlck5vdGVDb21tYW5kXG4gICAgLmNvbW1hbmQoJ2RlbGV0ZScpXG4gICAgLmRlc2NyaXB0aW9uKCdEZWxldGUgdXNlciBub3RlcycpXG4gICAgLm9wdGlvbignLS1ub3RlLWlkIDxpZD4nLCAnU3BlY2lmaWMgbm90ZSBJRCB0byBkZWxldGUnKVxuICAgIC5vcHRpb24oJy0tbGFzdC1wdWJsaXNoZWQnLCAnRGVsZXRlIHRoZSBsYXN0IHB1Ymxpc2hlZCBub3RlJylcbiAgICAub3B0aW9uKCctYiwgLS1icm93c2VyLXBhdGggPHBhdGg+JywgJ0N1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJylcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7IG5vdGVJZD86IHN0cmluZzsgbGFzdFB1Ymxpc2hlZD86IGJvb2xlYW47IGJyb3dzZXJQYXRoPzogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IG5vdGVTZXJ2aWNlID0gbmV3IE5vdGVTZXJ2aWNlKGNvbmZpZyk7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAob3B0cy5sYXN0UHVibGlzaGVkKSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbm90ZVNlcnZpY2UuZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUob3B0cy5icm93c2VyUGF0aCk7XG4gICAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICAgIH0gZWxzZSBpZiAob3B0cy5ub3RlSWQpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBub3RlU2VydmljZS5kZWxldGVOb3RlKG9wdHMubm90ZUlkLCBvcHRzLmJyb3dzZXJQYXRoKTtcbiAgICAgICAgICB1dGlscy5wcmludFN1Y2Nlc3MocmVzdWx0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBTaG93IGhlbHAgaW5zdGVhZCBvZiBKU09OIGVycm9yIHdoZW4gbm8gYXJndW1lbnRzIHByb3ZpZGVkXG4gICAgICAgICAgY29uc29sZS5sb2coJ1VzYWdlOiB4aHMtbWNwIHVzZXJub3RlIGRlbGV0ZSBbb3B0aW9uc11cXG4nKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnRGVsZXRlIHVzZXIgbm90ZXNcXG4nKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnT3B0aW9uczonKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnICAtLW5vdGUtaWQgPGlkPiAgICAgICAgICAgICBTcGVjaWZpYyBub3RlIElEIHRvIGRlbGV0ZScpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcgIC0tbGFzdC1wdWJsaXNoZWQgICAgICAgICAgIERlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZScpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcgIC1iLCAtLWJyb3dzZXItcGF0aCA8cGF0aD4gIEN1c3RvbSBicm93c2VyIGJpbmFyeSBwYXRoJyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJyAgLWgsIC0taGVscCAgICAgICAgICAgICAgICAgZGlzcGxheSBoZWxwIGZvciBjb21tYW5kJyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAvLyBGZWVkczogY29tbWVudCBvbiBub3RlXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnY29tbWVudCcpXG4gICAgLmRlc2NyaXB0aW9uKCdDb21tZW50IG9uIGEgbm90ZScpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctLWZlZWQtaWQgPGlkPicsICdGZWVkIElEJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy0teHNlYy10b2tlbiA8dG9rZW4+JywgJ1NlY3VyaXR5IHRva2VuIGZvciB0aGUgZmVlZCcpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctbiwgLS1ub3RlIDx0ZXh0PicsICdDb21tZW50IGNvbnRlbnQnKVxuICAgIC5vcHRpb24oJy1iLCAtLWJyb3dzZXItcGF0aCA8cGF0aD4nLCAnQ3VzdG9tIGJyb3dzZXIgYmluYXJ5IHBhdGgnKVxuICAgIC5hY3Rpb24oXG4gICAgICBhc3luYyAob3B0czogeyBmZWVkSWQ6IHN0cmluZzsgeHNlY1Rva2VuOiBzdHJpbmc7IG5vdGU6IHN0cmluZzsgYnJvd3NlclBhdGg/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCBmZWVkU2VydmljZSA9IG5ldyBGZWVkU2VydmljZShjb25maWcpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZlZWRTZXJ2aWNlLmNvbW1lbnRPbkZlZWQoXG4gICAgICAgICAgICBvcHRzLmZlZWRJZCxcbiAgICAgICAgICAgIG9wdHMueHNlY1Rva2VuLFxuICAgICAgICAgICAgb3B0cy5ub3RlLFxuICAgICAgICAgICAgb3B0cy5icm93c2VyUGF0aFxuICAgICAgICAgICk7XG4gICAgICAgICAgdXRpbHMucHJpbnRTdWNjZXNzKHJlc3VsdCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuXG4gIC8vIFB1Ymxpc2hpbmc6IHVuaWZpZWQgcHVibGlzaCBjb21tYW5kXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgncHVibGlzaCcpXG4gICAgLmRlc2NyaXB0aW9uKCdQdWJsaXNoIGNvbnRlbnQgdG8gWGlhb0hvbmdTaHUgKHN1cHBvcnRzIGJvdGggaW1hZ2VzIGFuZCB2aWRlb3MpJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy10LCAtLXR5cGUgPHR5cGU+JywgJ0NvbnRlbnQgdHlwZTogXCJpbWFnZVwiIGZvciBpbWFnZXMsIFwidmlkZW9cIiBmb3IgdmlkZW9zJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy0tdGl0bGUgPHRpdGxlPicsICdDb250ZW50IHRpdGxlICg8PSAyMCBjaGFycyknKVxuICAgIC5yZXF1aXJlZE9wdGlvbignLS1jb250ZW50IDxjb250ZW50PicsICdDb250ZW50IGRlc2NyaXB0aW9uICg8PSAxMDAwIGNoYXJzKScpXG4gICAgLnJlcXVpcmVkT3B0aW9uKFxuICAgICAgJy1tLCAtLW1lZGlhIDxwYXRocz4nLFxuICAgICAgJ0NvbW1hLXNlcGFyYXRlZCBtZWRpYSBmaWxlIHBhdGhzICgxLTE4IGltYWdlcyBmb3IgaW1hZ2UgcG9zdHMsIGV4YWN0bHkgMSB2aWRlbyBmb3IgdmlkZW9zKSdcbiAgICApXG4gICAgLm9wdGlvbignLS10YWdzIDx0YWdzPicsICdDb21tYS1zZXBhcmF0ZWQgdGFncycpXG4gICAgLm9wdGlvbignLWIsIC0tYnJvd3Nlci1wYXRoIDxwYXRoPicsICdDdXN0b20gYnJvd3NlciBiaW5hcnkgcGF0aCcpXG4gICAgLmFjdGlvbihcbiAgICAgIGFzeW5jIChvcHRzOiB7XG4gICAgICAgIHR5cGU6IHN0cmluZztcbiAgICAgICAgdGl0bGU6IHN0cmluZztcbiAgICAgICAgY29udGVudDogc3RyaW5nO1xuICAgICAgICBtZWRpYTogc3RyaW5nO1xuICAgICAgICB0YWdzPzogc3RyaW5nO1xuICAgICAgICBicm93c2VyUGF0aD86IHN0cmluZztcbiAgICAgIH0pID0+IHtcbiAgICAgICAgY29uc3QgcHVibGlzaFNlcnZpY2UgPSBuZXcgUHVibGlzaFNlcnZpY2UoY29uZmlnKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAob3B0cy50eXBlICE9PSAnaW1hZ2UnICYmIG9wdHMudHlwZSAhPT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgdXRpbHMucHJpbnRFcnJvcihuZXcgRXJyb3IoJ1R5cGUgbXVzdCBiZSBcImltYWdlXCIgb3IgXCJ2aWRlb1wiJykpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IG1lZGlhUGF0aHMgPSBvcHRzLm1lZGlhXG4gICAgICAgICAgICAuc3BsaXQoJywnKVxuICAgICAgICAgICAgLm1hcCgocykgPT4gcy50cmltKCkpXG4gICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHB1Ymxpc2hTZXJ2aWNlLnB1Ymxpc2hDb250ZW50KFxuICAgICAgICAgICAgb3B0cy50eXBlLFxuICAgICAgICAgICAgb3B0cy50aXRsZSxcbiAgICAgICAgICAgIG9wdHMuY29udGVudCxcbiAgICAgICAgICAgIG1lZGlhUGF0aHMsXG4gICAgICAgICAgICBvcHRzLnRhZ3MsXG4gICAgICAgICAgICBvcHRzLmJyb3dzZXJQYXRoXG4gICAgICAgICAgKTtcbiAgICAgICAgICB1dGlscy5wcmludFN1Y2Nlc3MocmVzdWx0KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB1dGlscy5wcmludEVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG5cbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCdtY3AnKVxuICAgIC5kZXNjcmlwdGlvbignU3RhcnQgWEhTIE1DUCBzZXJ2ZXIgKHN0ZGlvIG9yIGh0dHAgbW9kZSknKVxuICAgIC5vcHRpb24oJy1tLCAtLW1vZGUgPG1vZGU+JywgJ1NlcnZlciBtb2RlOiBzdGRpbyBvciBodHRwJywgJ3N0ZGlvJylcbiAgICAub3B0aW9uKCctcCwgLS1wb3J0IDxwb3J0PicsICdIVFRQIHNlcnZlciBwb3J0IChvbmx5IGZvciBodHRwIG1vZGUpJywgJzMwMDAnKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdHM6IHsgbW9kZT86IHN0cmluZzsgcG9ydD86IHN0cmluZyB9KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAob3B0cy5tb2RlID09PSAnaHR0cCcpIHtcbiAgICAgICAgICBjb25zdCBwb3J0ID0gb3B0cy5wb3J0ID8gcGFyc2VJbnQob3B0cy5wb3J0LCAxMCkgOiAzMDAwO1xuICAgICAgICAgIGNvbnN0IGh0dHBTZXJ2ZXIgPSBuZXcgWEhTSFRUUE1DUFNlcnZlcihwb3J0KTtcbiAgICAgICAgICBhd2FpdCBodHRwU2VydmVyLnN0YXJ0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gSW4gc3RkaW8gbW9kZSwgd2UgbXVzdCBub3Qgb3V0cHV0IGFueXRoaW5nIHRvIHN0ZG91dC9zdGRlcnIgZXhjZXB0IE1DUCBwcm90b2NvbCBtZXNzYWdlc1xuICAgICAgICAgIC8vIFRoaXMgcHJldmVudHMgaW50ZXJmZXJlbmNlIHdpdGggTUNQIGNvbW11bmljYXRpb25cbiAgICAgICAgICBjb25zdCBzZXJ2ZXIgPSBuZXcgWEhTTUNQU2VydmVyKCk7XG4gICAgICAgICAgYXdhaXQgc2VydmVyLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIE9ubHkgbG9nIHRvIHN0ZGVyciBpZiBsb2dnaW5nIGlzIGV4cGxpY2l0bHkgZW5hYmxlZFxuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuWEhTX0VOQUJMRV9MT0dHSU5HID09PSAndHJ1ZScpIHtcbiAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgU2VydmVyIGZhaWxlZCB0byBzdGFydDogJHtlcnJvcn1cXG5gKTtcbiAgICAgICAgfVxuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLy8gTGlzdCBNQ1AgdG9vbHNcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCd0b29scycpXG4gICAgLmRlc2NyaXB0aW9uKCdMaXN0IGF2YWlsYWJsZSBNQ1AgdG9vbHMnKVxuICAgIC5vcHRpb24oJy1qLCAtLWpzb24nLCAnT3V0cHV0IGluIEpTT04gZm9ybWF0JylcbiAgICAub3B0aW9uKCctZCwgLS1kZXRhaWxlZCcsICdTaG93IGRldGFpbGVkIHRvb2wgaW5mb3JtYXRpb24nKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdHM6IHsganNvbj86IGJvb2xlYW47IGRldGFpbGVkPzogYm9vbGVhbiB9KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB0b29sU2NoZW1hcyA9IFhIU19UT09MX1NDSEVNQVM7XG5cbiAgICAgICAgaWYgKG9wdHMuanNvbikge1xuICAgICAgICAgIGlmIChvcHRzLmRldGFpbGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh0b29sU2NoZW1hcywgbnVsbCwgMikpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0b29sTmFtZXMgPSB0b29sU2NoZW1hcy5tYXAoKHRvb2wpID0+ICh7XG4gICAgICAgICAgICAgIG5hbWU6IHRvb2wubmFtZSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHRvb2wuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh0b29sTmFtZXMsIG51bGwsIDIpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1xcbvCfk4sgQXZhaWxhYmxlIE1DUCBUb29sczpcXG4nKTtcblxuICAgICAgICAgIHRvb2xTY2hlbWFzLmZvckVhY2goKHRvb2wsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgJHtpbmRleCArIDF9LiAke3Rvb2wubmFtZX1gKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAgICAke3Rvb2wuZGVzY3JpcHRpb259YCk7XG5cbiAgICAgICAgICAgIGlmIChvcHRzLmRldGFpbGVkKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlcXVpcmVkID0gdG9vbC5pbnB1dFNjaGVtYS5yZXF1aXJlZCA/PyBbXTtcbiAgICAgICAgICAgICAgY29uc3QgcHJvcGVydGllcyA9IHRvb2wuaW5wdXRTY2hlbWEucHJvcGVydGllcyA/PyB7fTtcblxuICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMocHJvcGVydGllcykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCcgICBQYXJhbWV0ZXJzOicpO1xuICAgICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHByb3BlcnRpZXMpLmZvckVhY2goKFtrZXksIHByb3BdOiBbc3RyaW5nLCB1bmtub3duXSkgPT4ge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVxdWlyZWRNYXJrID0gcmVxdWlyZWQuaW5jbHVkZXMoa2V5KSA/ICcgKHJlcXVpcmVkKScgOiAnIChvcHRpb25hbCknO1xuICAgICAgICAgICAgICAgICAgY29uc3QgcHJvcERlc2MgPSAocHJvcCBhcyB7IGRlc2NyaXB0aW9uPzogc3RyaW5nIH0pLmRlc2NyaXB0aW9uO1xuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYCAgICAgLSAke2tleX06ICR7cHJvcERlc2MgPz8gJ05vIGRlc2NyaXB0aW9uJ30ke3JlcXVpcmVkTWFya31gKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc29sZS5sb2coYFRvdGFsOiAke3Rvb2xTY2hlbWFzLmxlbmd0aH0gdG9vbHMgYXZhaWxhYmxlYCk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1xcblVzZSAtLWRldGFpbGVkIGZvciBwYXJhbWV0ZXIgaW5mb3JtYXRpb24nKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnVXNlIC0tanNvbiBmb3IgbWFjaGluZS1yZWFkYWJsZSBvdXRwdXQnKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdXRpbHMucHJpbnRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgcHJvZ3JhbS5wYXJzZUFzeW5jKHByb2Nlc3MuYXJndik7XG59XG5cbi8vIEhhbmRsZSBncmFjZWZ1bCBzaHV0ZG93biBmb3IgTUNQIHNlcnZlciBtb2RlXG5wcm9jZXNzLm9uKCdTSUdJTlQnLCAoKSA9PiB7XG4gIC8vIERvbid0IGxvZyB0byBzdGRlcnIgaW4gc3RkaW8gbW9kZSB0byBhdm9pZCBpbnRlcmZlcmluZyB3aXRoIE1DUCBwcm90b2NvbFxuICBwcm9jZXNzLmV4aXQoMCk7XG59KTtcblxucHJvY2Vzcy5vbignU0lHVEVSTScsICgpID0+IHtcbiAgLy8gRG9uJ3QgbG9nIHRvIHN0ZGVyciBpbiBzdGRpbyBtb2RlIHRvIGF2b2lkIGludGVyZmVyaW5nIHdpdGggTUNQIHByb3RvY29sXG4gIHByb2Nlc3MuZXhpdCgwKTtcbn0pO1xuXG4vLyBTdGFydCB0aGUgQ0xJXG5tYWluKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gIC8vIE9ubHkgbG9nIHRvIHN0ZGVyciBpZiBsb2dnaW5nIGlzIGV4cGxpY2l0bHkgZW5hYmxlZFxuICBpZiAocHJvY2Vzcy5lbnYuWEhTX0VOQUJMRV9MT0dHSU5HID09PSAndHJ1ZScpIHtcbiAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgRmF0YWwgZXJyb3I6ICR7ZXJyb3J9XFxuYCk7XG4gIH1cbiAgcHJvY2Vzcy5leGl0KDEpO1xufSk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5582\n\n}");
88
95
 
89
96
  /***/ }),
90
97
 
@@ -102,13 +109,6 @@ module.exports = require("url");
102
109
 
103
110
  /***/ }),
104
111
 
105
- /***/ 7482:
106
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
107
-
108
- eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n NoteService: () => (/* binding */ NoteService)\n});\n\n// EXTERNAL MODULE: ./src/shared/base.service.ts + 2 modules\nvar base_service = __webpack_require__(3100);\n// EXTERNAL MODULE: ./src/shared/logger.ts\nvar logger = __webpack_require__(9135);\n// EXTERNAL MODULE: ./src/shared/utils.ts\nvar utils = __webpack_require__(2094);\n// EXTERNAL MODULE: ./src/shared/errors.ts\nvar errors = __webpack_require__(7636);\n// EXTERNAL MODULE: ./src/shared/selectors.ts\nvar selectors = __webpack_require__(805);\n;// ./src/core/deleting/delete.service.ts\n/**\n * Delete service for XHS MCP Server\n * Handles note deletion operations\n */\n\n\n\n\n\n/**\n * CSS selectors for delete operations - updated for current XiaoHongShu interface\n */\nconst DELETE_SELECTORS = {\n NOTE_ITEM: [\n 'div.note',\n '.note-item',\n '[class*=\"note\"]',\n '[data-impression]',\n '.creator-note-item',\n '.note-card',\n '.content-item'\n ],\n DELETE_BUTTON: [\n '.control.data-del',\n 'span.control.data-del',\n ...selectors/* COMMON_BUTTON_SELECTORS */.ox.DELETE\n ],\n CONFIRM_BUTTON: selectors/* COMMON_BUTTON_SELECTORS */.ox.CONFIRM,\n CANCEL_BUTTON: selectors/* COMMON_BUTTON_SELECTORS */.ox.CANCEL,\n MORE_OPTIONS: selectors/* COMMON_BUTTON_SELECTORS */.ox.MORE_OPTIONS,\n DROPDOWN_MENU: selectors/* COMMON_MODAL_SELECTORS */.TK.DROPDOWN_MENU,\n MODAL_CONFIRM: selectors/* COMMON_MODAL_SELECTORS */.TK.CONFIRM,\n MODAL_CANCEL: selectors/* COMMON_MODAL_SELECTORS */.TK.CANCEL,\n};\nclass DeleteService extends base_service/* BaseService */.d {\n constructor(config) {\n super(config);\n }\n /**\n * Delete a specific note by ID\n * @param noteId - The ID of the note to delete\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteNote(noteId, browserPath) {\n this.validateDeleteParams(noteId);\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n // Navigate to creator center note manager\n await this.navigateToCreatorCenter(page);\n await this.verifyUserAuthentication(page);\n // Find and delete the specific note\n const result = await this.findAndDeleteNote(page, noteId);\n return {\n success: true,\n data: null,\n noteId: result.noteId,\n title: result.title,\n deletedAt: Date.now(),\n message: `Successfully deleted note \"${result.title}\" (ID: ${result.noteId})`,\n operation: 'deleteNote',\n };\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to delete note ${noteId}: ${error}`);\n return {\n success: false,\n data: null,\n error: error instanceof Error ? error.message : String(error),\n message: `Failed to delete note: ${error instanceof Error ? error.message : String(error)}`,\n deletedAt: Date.now(),\n operation: 'deleteNote',\n };\n }\n finally {\n await page.close();\n }\n }\n /**\n * Delete the last published note\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteLastPublishedNote(browserPath) {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n // Navigate to creator center note manager\n await this.navigateToCreatorCenter(page);\n await this.verifyUserAuthentication(page);\n // Find and delete the last published note\n const result = await this.findAndDeleteLastNote(page);\n return {\n success: true,\n data: null,\n noteId: result.noteId,\n title: result.title,\n deletedAt: Date.now(),\n message: `Successfully deleted last published note \"${result.title}\" (ID: ${result.noteId})`,\n operation: 'deleteLastPublishedNote',\n };\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to delete last published note: ${error}`);\n return {\n success: false,\n data: null,\n error: error instanceof Error ? error.message : String(error),\n message: `Failed to delete last published note: ${error instanceof Error ? error.message : String(error)}`,\n deletedAt: Date.now(),\n operation: 'deleteLastPublishedNote',\n };\n }\n finally {\n await page.close();\n }\n }\n /**\n * Validate delete parameters\n */\n validateDeleteParams(noteId) {\n if (!noteId || noteId.trim().length === 0) {\n throw new errors/* DeleteError */.GU('Note ID is required', { noteId });\n }\n }\n /**\n * Navigate to creator center note manager\n */\n async navigateToCreatorCenter(page) {\n try {\n const creatorCenterUrl = 'https://creator.xiaohongshu.com/new/note-manager?source=official';\n await this.getBrowserManager().navigateWithRetry(page, creatorCenterUrl);\n await (0,utils/* sleep */.yy)(5000); // Wait longer for page to load completely\n // Debug: Log page content to understand the structure\n const pageContent = await page.evaluate(() => {\n const noteElements = document.querySelectorAll('div.note, [class*=\"note\"], [data-impression]');\n const allButtons = document.querySelectorAll('button, [role=\"button\"], .btn, [class*=\"button\"]');\n const allLinks = document.querySelectorAll('a[href*=\"/explore/\"]');\n return {\n totalNoteElements: noteElements.length,\n noteElementClasses: Array.from(noteElements).map(el => el.className),\n totalButtons: allButtons.length,\n buttonTexts: Array.from(allButtons).slice(0, 10).map(btn => btn.textContent?.trim()).filter(Boolean),\n buttonClasses: Array.from(allButtons).slice(0, 10).map(btn => btn.className),\n exploreLinks: Array.from(allLinks).map(link => link.getAttribute('href')),\n pageTitle: document.title,\n currentUrl: window.location.href\n };\n });\n logger/* logger */.v.info(`Page loaded: ${JSON.stringify(pageContent, null, 2)}`);\n }\n catch (error) {\n throw new errors/* DeleteError */.GU('Failed to navigate to creator center', { url: 'https://creator.xiaohongshu.com/new/note-manager?source=official' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Verify user is authenticated\n */\n async verifyUserAuthentication(page) {\n try {\n // Check for login elements on the current page\n const loginElements = await page.$$(this.getConfig().xhs.loginOkSelector);\n // Also check for creator center specific elements\n const creatorElements = await page.$$('[class*=\"user\"], [class*=\"profile\"], [class*=\"avatar\"]');\n if (loginElements.length === 0 && creatorElements.length === 0) {\n // Check if we're on a login page\n const currentUrl = page.url();\n if (currentUrl.includes('login') || currentUrl.includes('signin')) {\n throw new errors/* NotLoggedInError */.bG('User not logged in', {\n operation: 'deleteNote',\n url: currentUrl,\n });\n }\n // For creator center, check if we can see note management elements\n const noteElements = await page.$$('div.note');\n if (noteElements.length === 0) {\n throw new errors/* NotLoggedInError */.bG('User not logged in or no notes found', {\n operation: 'deleteNote',\n url: currentUrl,\n });\n }\n }\n }\n catch (error) {\n if (error instanceof errors/* NotLoggedInError */.bG) {\n throw error;\n }\n throw new errors/* DeleteError */.GU('Failed to verify authentication', { operation: 'verifyAuth' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Find and delete a specific note by ID\n */\n async findAndDeleteNote(page, noteId) {\n try {\n const result = await page.evaluate((selectors, targetNoteId) => {\n // Try each note item selector\n let noteElements = [];\n for (const selector of selectors.NOTE_ITEM) {\n const elements = Array.from(document.querySelectorAll(selector));\n if (elements.length > 0) {\n noteElements = elements;\n break;\n }\n }\n if (noteElements.length === 0) {\n return { noteId: targetNoteId, title: '', found: false, error: 'No note elements found on page' };\n }\n for (const noteElement of noteElements) {\n // Check if this is the note we want to delete\n const impressionData = noteElement.getAttribute('data-impression');\n let currentNoteId = '';\n if (impressionData) {\n try {\n const parsed = JSON.parse(impressionData);\n currentNoteId = parsed?.noteTarget?.value?.noteId || '';\n }\n catch (e) {\n // Ignore parsing errors\n }\n }\n // Also try to find note ID in other attributes or data\n if (!currentNoteId) {\n const linkElement = noteElement.querySelector('a[href*=\"/explore/\"], a[href*=\"/note/\"]');\n if (linkElement) {\n const href = linkElement.getAttribute('href') || '';\n const match = href.match(/\\/explore\\/([a-zA-Z0-9]+)/);\n if (match) {\n currentNoteId = match[1];\n }\n }\n }\n if (currentNoteId === targetNoteId) {\n // Found the target note, try to delete it\n const titleElement = noteElement.querySelector('[class*=\"title\"], [class*=\"name\"]');\n const title = titleElement?.textContent?.trim() || 'Unknown';\n // Look for delete button or more options button\n let deleteButton = null;\n // Try each delete button selector\n for (const selector of selectors.DELETE_BUTTON) {\n deleteButton = noteElement.querySelector(selector);\n if (deleteButton) {\n break;\n }\n }\n if (!deleteButton) {\n // Try to find more options button first\n let moreButton = null;\n for (const selector of selectors.MORE_OPTIONS) {\n moreButton = noteElement.querySelector(selector);\n if (moreButton) {\n break;\n }\n }\n if (moreButton) {\n moreButton.click();\n // Wait for dropdown to appear and look for delete option\n setTimeout(() => {\n for (const selector of selectors.DROPDOWN_MENU) {\n const dropdown = document.querySelector(selector);\n if (dropdown) {\n for (const deleteSelector of selectors.DELETE_BUTTON) {\n deleteButton = dropdown.querySelector(deleteSelector);\n if (deleteButton) {\n break;\n }\n }\n if (deleteButton)\n break;\n }\n }\n }, 1000);\n }\n }\n if (deleteButton) {\n deleteButton.click();\n return { noteId: currentNoteId, title, found: true };\n }\n else {\n return { noteId: currentNoteId, title, found: false, error: 'Delete button not found' };\n }\n }\n }\n return { noteId: targetNoteId, title: '', found: false, error: 'Note not found' };\n }, DELETE_SELECTORS, noteId);\n if (!result.found) {\n throw new errors/* DeleteError */.GU(result.error || 'Note not found', { noteId });\n }\n // Wait for confirmation dialog if it appears\n await (0,utils/* sleep */.yy)(1000);\n // Handle confirmation dialog\n await this.handleConfirmationDialog(page);\n return { noteId: result.noteId, title: result.title };\n }\n catch (error) {\n throw new errors/* DeleteError */.GU('Failed to find and delete note', { noteId }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Find and delete the last published note\n */\n async findAndDeleteLastNote(page) {\n try {\n const result = await page.evaluate((selectors) => {\n // Try each note item selector\n let noteElements = [];\n for (const selector of selectors.NOTE_ITEM) {\n const elements = Array.from(document.querySelectorAll(selector));\n if (elements.length > 0) {\n noteElements = elements;\n break;\n }\n }\n if (noteElements.length === 0) {\n return { noteId: '', title: '', found: false, error: 'No notes found' };\n }\n // Get the first note (most recent)\n const firstNote = noteElements[0];\n // Extract note ID\n let noteId = '';\n const impressionData = firstNote.getAttribute('data-impression');\n if (impressionData) {\n try {\n const parsed = JSON.parse(impressionData);\n noteId = parsed?.noteTarget?.value?.noteId || '';\n }\n catch (e) {\n // Ignore parsing errors\n }\n }\n // Also try to find note ID in link\n if (!noteId) {\n const linkElement = firstNote.querySelector('a[href*=\"/explore/\"], a[href*=\"/note/\"]');\n if (linkElement) {\n const href = linkElement.getAttribute('href') || '';\n const match = href.match(/\\/explore\\/([a-zA-Z0-9]+)/);\n if (match) {\n noteId = match[1];\n }\n }\n }\n // Extract title\n const titleElement = firstNote.querySelector('[class*=\"title\"], [class*=\"name\"]');\n const title = titleElement?.textContent?.trim() || 'Unknown';\n // Look for delete button or more options button\n let deleteButton = null;\n // Try each delete button selector\n for (const selector of selectors.DELETE_BUTTON) {\n deleteButton = firstNote.querySelector(selector);\n if (deleteButton) {\n break;\n }\n }\n if (!deleteButton) {\n // Try to find more options button first\n let moreButton = null;\n for (const selector of selectors.MORE_OPTIONS) {\n moreButton = firstNote.querySelector(selector);\n if (moreButton) {\n break;\n }\n }\n if (moreButton) {\n moreButton.click();\n // Wait for dropdown to appear and look for delete option\n setTimeout(() => {\n for (const selector of selectors.DROPDOWN_MENU) {\n const dropdown = document.querySelector(selector);\n if (dropdown) {\n for (const deleteSelector of selectors.DELETE_BUTTON) {\n deleteButton = dropdown.querySelector(deleteSelector);\n if (deleteButton) {\n break;\n }\n }\n if (deleteButton)\n break;\n }\n }\n }, 1000);\n }\n }\n if (deleteButton) {\n deleteButton.click();\n return { noteId, title, found: true };\n }\n else {\n return { noteId, title, found: false, error: 'Delete button not found' };\n }\n }, DELETE_SELECTORS);\n if (!result.found) {\n throw new errors/* DeleteError */.GU(result.error || 'Failed to find delete button', {});\n }\n // Wait for confirmation dialog if it appears\n await (0,utils/* sleep */.yy)(1000);\n // Handle confirmation dialog\n await this.handleConfirmationDialog(page);\n return { noteId: result.noteId, title: result.title };\n }\n catch (error) {\n throw new errors/* DeleteError */.GU('Failed to find and delete last note', {}, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Handle confirmation dialog for delete operation\n */\n async handleConfirmationDialog(page) {\n try {\n // Wait for confirmation dialog to appear\n await (0,utils/* sleep */.yy)(2000);\n // Look for confirmation buttons using all possible selectors\n let confirmButton = null;\n // Try each confirm button selector\n for (const selector of DELETE_SELECTORS.CONFIRM_BUTTON) {\n confirmButton = await page.$(selector);\n if (confirmButton) {\n logger/* logger */.v.info(`Found confirm button with selector: ${selector}`);\n break;\n }\n }\n // If not found, try modal confirm selectors\n if (!confirmButton) {\n for (const selector of DELETE_SELECTORS.MODAL_CONFIRM) {\n confirmButton = await page.$(selector);\n if (confirmButton) {\n logger/* logger */.v.info(`Found modal confirm button with selector: ${selector}`);\n break;\n }\n }\n }\n if (confirmButton) {\n logger/* logger */.v.info('Clicking confirmation button');\n await confirmButton.click();\n await (0,utils/* sleep */.yy)(2000);\n }\n else {\n // If no confirmation dialog, the delete might have been immediate\n logger/* logger */.v.info('No confirmation dialog found, delete might be immediate');\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to handle confirmation dialog: ${error}`);\n // Continue anyway as the delete might still work\n }\n }\n}\n\n;// ./src/core/notes/note.service.ts\n/**\n * Note service for XHS MCP Server\n * Handles user notes/feeds operations\n */\n\n\n\n\n\n/**\n * CSS selectors for note extraction from Creator Center\n */\nconst NOTE_SELECTORS = {\n NOTE_ELEMENTS: 'div.note',\n TITLE_ELEMENTS: '[class*=\"raw\"], [class*=\"title\"], [class*=\"name\"]',\n IMAGE_ELEMENTS: 'img[class*=\"media\"], img[class*=\"cover\"], img[class*=\"thumbnail\"]',\n STAT_ELEMENTS: '[class*=\"count\"], [class*=\"stat\"], [class*=\"number\"]',\n TAG_ELEMENTS: '[class*=\"tag\"], [class*=\"label\"]',\n NOTE_LINK: 'a[href*=\"/explore/\"], a[href*=\"/note/\"]',\n VISIBILITY_INDICATORS: '[class*=\"private\"], [class*=\"visibility\"], [class*=\"lock\"], [class*=\"eye\"], [class*=\"public\"], [class*=\"friends\"], [class*=\"status\"]',\n PUBLISH_TIME: '[class*=\"time\"], [class*=\"date\"], [class*=\"publish-time\"]',\n};\nclass NoteService extends base_service/* BaseService */.d {\n deleteService;\n constructor(config) {\n super(config);\n this.deleteService = new DeleteService(config);\n }\n /**\n * Get current user's published notes from creator center\n * @param limit - Maximum number of notes to return (default: 20)\n * @param cursor - Pagination cursor for next page\n * @param browserPath - Optional custom browser path\n * @returns Promise<UserNotesResult> - User notes with pagination info\n */\n async getUserNotes(limit = 20, cursor, browserPath) {\n this.validateGetUserNotesParams(limit);\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n // Navigate to creator center note manager\n await this.navigateToCreatorCenter(page);\n await this.verifyUserAuthentication(page);\n // Extract notes from creator center\n const notesData = await this.extractNotesFromCreatorCenter(page);\n const limitedNotes = this.limitNotes(notesData, limit);\n return {\n success: true,\n data: limitedNotes,\n total: notesData.length,\n hasMore: notesData.length > limit,\n nextCursor: this.getNextCursor(limitedNotes),\n operation: 'getUserNotes',\n };\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to get user notes: ${error}`);\n return {\n success: false,\n data: [],\n total: 0,\n hasMore: false,\n error: error instanceof Error ? error.message : String(error),\n operation: 'getUserNotes',\n };\n }\n finally {\n await page.close();\n }\n }\n /**\n * Validate parameters for getUserNotes method\n */\n validateGetUserNotesParams(limit) {\n if (limit <= 0) {\n throw new errors/* NoteParsingError */.Vb('Limit must be greater than 0', { limit });\n }\n if (limit > 100) {\n throw new errors/* NoteParsingError */.Vb('Limit cannot exceed 100', { limit });\n }\n }\n /**\n * Navigate to creator center note manager\n */\n async navigateToCreatorCenter(page) {\n try {\n const creatorCenterUrl = 'https://creator.xiaohongshu.com/new/note-manager?source=official';\n await this.getBrowserManager().navigateWithRetry(page, creatorCenterUrl);\n await (0,utils/* sleep */.yy)(3000); // Wait for page to load completely\n }\n catch (error) {\n throw new errors/* NoteParsingError */.Vb('Failed to navigate to creator center', { url: 'https://creator.xiaohongshu.com/new/note-manager?source=official' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Verify user is authenticated\n */\n async verifyUserAuthentication(page) {\n try {\n // Check for login elements on the current page\n const loginElements = await page.$$(this.getConfig().xhs.loginOkSelector);\n // Also check for creator center specific elements\n const creatorElements = await page.$$('[class*=\"user\"], [class*=\"profile\"], [class*=\"avatar\"]');\n if (loginElements.length === 0 && creatorElements.length === 0) {\n // Check if we're on a login page\n const currentUrl = page.url();\n if (currentUrl.includes('login') || currentUrl.includes('signin')) {\n throw new errors/* NotLoggedInError */.bG('User not logged in', {\n operation: 'getUserNotes',\n url: currentUrl,\n });\n }\n // For creator center, check if we can see note management elements\n const noteElements = await page.$$('div.note');\n if (noteElements.length === 0) {\n throw new errors/* NotLoggedInError */.bG('User not logged in or no notes found', {\n operation: 'getUserNotes',\n url: currentUrl,\n });\n }\n }\n }\n catch (error) {\n if (error instanceof errors/* NotLoggedInError */.bG) {\n throw error;\n }\n throw new errors/* NoteParsingError */.Vb('Failed to verify authentication', { operation: 'verifyAuth' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Extract notes from creator center page\n */\n async extractNotesFromCreatorCenter(page) {\n try {\n const notesData = await page.evaluate((selectors) => {\n const notes = [];\n // Find note elements using the creator center selector\n const noteElements = Array.from(document.querySelectorAll(selectors.NOTE_ELEMENTS));\n noteElements.forEach((element) => {\n try {\n // Extract note data from element\n const publishTime = Date.now();\n const note = {\n id: '',\n title: '',\n content: '',\n images: [],\n publishTime,\n updateTime: publishTime,\n likeCount: 0,\n commentCount: 0,\n shareCount: 0,\n collectCount: 0,\n tags: [],\n url: '',\n visibility: 'unknown',\n visibilityText: '',\n };\n // Extract note ID from data attributes or impression data\n const impressionData = element.getAttribute('data-impression');\n if (impressionData) {\n try {\n const parsed = JSON.parse(impressionData);\n const noteId = parsed?.noteTarget?.value?.noteId;\n if (noteId) {\n note.id = noteId;\n note.url = `https://www.xiaohongshu.com/explore/${noteId}`;\n }\n }\n catch (e) {\n // Ignore parsing errors\n }\n }\n // Extract title/content\n const titleElement = element.querySelector(selectors.TITLE_ELEMENTS);\n if (titleElement) {\n const title = titleElement.textContent?.trim() ?? '';\n note.title = title;\n note.content = title;\n }\n // Extract images - try multiple approaches for creator center\n const imageSelectors = [\n selectors.IMAGE_ELEMENTS,\n 'img', // Try all img elements\n '[class*=\"image\"]',\n '[class*=\"photo\"]',\n '[class*=\"pic\"]',\n '[class*=\"img\"]',\n '[style*=\"background-image\"]', // Background images\n 'div[class*=\"cover\"] img',\n 'div[class*=\"thumbnail\"] img',\n 'div[class*=\"media\"] img',\n ];\n let imageElements = [];\n for (const selector of imageSelectors) {\n const elements = element.querySelectorAll(selector);\n if (elements.length > 0) {\n imageElements = Array.from(elements);\n break;\n }\n }\n imageElements.forEach((img) => {\n let src = '';\n // Try different ways to get image source\n const htmlImg = img;\n if (htmlImg.src) {\n src = htmlImg.src;\n }\n else if (htmlImg.style && htmlImg.style.backgroundImage) {\n // Extract from background-image CSS\n const bgMatch = htmlImg.style.backgroundImage.match(/url\\(['\"]?([^'\"]+)['\"]?\\)/);\n if (bgMatch) {\n src = bgMatch[1];\n }\n }\n else if (img.getAttribute('data-src')) {\n // Lazy loaded images\n src = img.getAttribute('data-src') || '';\n }\n else if (img.getAttribute('data-original')) {\n // Another lazy loading attribute\n src = img.getAttribute('data-original') || '';\n }\n if (src &&\n !src.includes('avatar') &&\n !src.includes('icon') &&\n !src.includes('logo') &&\n !src.includes('placeholder') &&\n src.startsWith('http')) {\n note.images.push(src);\n }\n });\n // Extract stats - look for numbers in the element\n const allText = element.textContent || '';\n const numbers = allText.match(/\\d+/g) || [];\n // Try to extract stats from text content\n if (numbers.length >= 4) {\n // Assuming order: like, comment, share, collect, view\n note.likeCount = parseInt(numbers[0] || '0') || 0;\n note.commentCount = parseInt(numbers[1]) || 0;\n note.shareCount = parseInt(numbers[2]) || 0;\n note.collectCount = parseInt(numbers[3]) || 0;\n }\n // Extract publish time\n const timeElement = element.querySelector(selectors.PUBLISH_TIME);\n if (timeElement) {\n const timeText = timeElement.textContent?.trim() || '';\n if (timeText.includes('发布于')) {\n // Parse Chinese date format\n const dateMatch = timeText.match(/(\\d{4})年(\\d{1,2})月(\\d{1,2})日\\s+(\\d{1,2}):(\\d{2})/);\n if (dateMatch) {\n const [, year, month, day, hour, minute] = dateMatch;\n const publishDate = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute));\n note.publishTime = publishDate.getTime();\n note.updateTime = publishDate.getTime();\n }\n }\n }\n // Extract visibility information\n const elementText = element.textContent?.toLowerCase() || '';\n if (elementText.includes('仅自己可见')) {\n note.visibility = 'private';\n note.visibilityText = '仅自己可见';\n }\n else if (elementText.includes('朋友可见')) {\n note.visibility = 'friends';\n note.visibilityText = '朋友可见';\n }\n else if (elementText.includes('公开')) {\n note.visibility = 'public';\n note.visibilityText = '公开';\n }\n else {\n // Default to public for notes without explicit visibility indicators\n note.visibility = 'public';\n note.visibilityText = '公开';\n }\n // Extract tags\n const tagElements = element.querySelectorAll(selectors.TAG_ELEMENTS);\n tagElements.forEach((tag) => {\n const tagText = tag.textContent?.trim();\n if (tagText?.startsWith('#')) {\n note.tags.push(tagText);\n }\n });\n if (note.id) {\n notes.push(note);\n }\n }\n catch (error) {\n // Ignore extraction errors for individual notes\n }\n });\n return notes;\n }, NOTE_SELECTORS);\n return notesData;\n }\n catch (error) {\n throw new errors/* NoteParsingError */.Vb('Failed to extract notes from creator center', { operation: 'extractNotesFromCreatorCenter' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Limit notes array to specified count\n */\n limitNotes(notes, limit) {\n return notes.slice(0, limit).map((note) => ({\n id: note.id,\n title: note.title,\n content: note.content,\n images: Object.freeze([...note.images]),\n publishTime: note.publishTime,\n updateTime: note.updateTime,\n likeCount: note.likeCount,\n commentCount: note.commentCount,\n shareCount: note.shareCount,\n collectCount: note.collectCount,\n tags: Object.freeze([...note.tags]),\n url: note.url,\n visibility: note.visibility,\n visibilityText: note.visibilityText,\n }));\n }\n /**\n * Get next cursor for pagination\n */\n getNextCursor(notes) {\n return notes.length > 0 ? notes[notes.length - 1].id : undefined;\n }\n /**\n * Delete a specific note by ID\n * @param noteId - The ID of the note to delete\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteNote(noteId, browserPath) {\n return this.deleteService.deleteNote(noteId, browserPath);\n }\n /**\n * Delete the last published note\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteLastPublishedNote(browserPath) {\n return this.deleteService.deleteLastPublishedNote(browserPath);\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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aEQsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLHVCQUF1QixDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7Q0FDRiIsInNvdXJjZXMiOlsid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9kZWxldGluZy9kZWxldGUuc2VydmljZS50cz8wMzA5Iiwid2VicGFjazovL3hocy1tY3AvLi9zcmMvY29yZS9ub3Rlcy9ub3RlLnNlcnZpY2UudHM/MWI2NiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIERlbGV0ZSBzZXJ2aWNlIGZvciBYSFMgTUNQIFNlcnZlclxuICogSGFuZGxlcyBub3RlIGRlbGV0aW9uIG9wZXJhdGlvbnNcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENvbmZpZywgWEhTUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvYmFzZS5zZXJ2aWNlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgRGVsZXRlRXJyb3IsIE5vdExvZ2dlZEluRXJyb3IgfSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgQ09NTU9OX0JVVFRPTl9TRUxFQ1RPUlMsIENPTU1PTl9NT0RBTF9TRUxFQ1RPUlMgfSBmcm9tICcuLi8uLi9zaGFyZWQvc2VsZWN0b3JzJztcblxuZXhwb3J0IGludGVyZmFjZSBEZWxldGVSZXN1bHQgZXh0ZW5kcyBYSFNSZXNwb25zZTxudWxsPiB7XG4gIHJlYWRvbmx5IG5vdGVJZD86IHN0cmluZztcbiAgcmVhZG9ubHkgdGl0bGU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRlbGV0ZWRBdDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlbGV0ZU9wdGlvbnMge1xuICBub3RlSWQ/OiBzdHJpbmc7XG4gIGxhc3RQdWJsaXNoZWQ/OiBib29sZWFuO1xuICBicm93c2VyUGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBDU1Mgc2VsZWN0b3JzIGZvciBkZWxldGUgb3BlcmF0aW9ucyAtIHVwZGF0ZWQgZm9yIGN1cnJlbnQgWGlhb0hvbmdTaHUgaW50ZXJmYWNlXG4gKi9cbmNvbnN0IERFTEVURV9TRUxFQ1RPUlMgPSB7XG4gIE5PVEVfSVRFTTogW1xuICAgICdkaXYubm90ZScsXG4gICAgJy5ub3RlLWl0ZW0nLFxuICAgICdbY2xhc3MqPVwibm90ZVwiXScsXG4gICAgJ1tkYXRhLWltcHJlc3Npb25dJyxcbiAgICAnLmNyZWF0b3Itbm90ZS1pdGVtJyxcbiAgICAnLm5vdGUtY2FyZCcsXG4gICAgJy5jb250ZW50LWl0ZW0nXG4gIF0sXG4gIERFTEVURV9CVVRUT046IFtcbiAgICAnLmNvbnRyb2wuZGF0YS1kZWwnLFxuICAgICdzcGFuLmNvbnRyb2wuZGF0YS1kZWwnLFxuICAgIC4uLkNPTU1PTl9CVVRUT05fU0VMRUNUT1JTLkRFTEVURVxuICBdLFxuICBDT05GSVJNX0JVVFRPTjogQ09NTU9OX0JVVFRPTl9TRUxFQ1RPUlMuQ09ORklSTSxcbiAgQ0FOQ0VMX0JVVFRPTjogQ09NTU9OX0JVVFRPTl9TRUxFQ1RPUlMuQ0FOQ0VMLFxuICBNT1JFX09QVElPTlM6IENPTU1PTl9CVVRUT05fU0VMRUNUT1JTLk1PUkVfT1BUSU9OUyxcbiAgRFJPUERPV05fTUVOVTogQ09NTU9OX01PREFMX1NFTEVDVE9SUy5EUk9QRE9XTl9NRU5VLFxuICBNT0RBTF9DT05GSVJNOiBDT01NT05fTU9EQUxfU0VMRUNUT1JTLkNPTkZJUk0sXG4gIE1PREFMX0NBTkNFTDogQ09NTU9OX01PREFMX1NFTEVDVE9SUy5DQU5DRUwsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY2xhc3MgRGVsZXRlU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcpIHtcbiAgICBzdXBlcihjb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhIHNwZWNpZmljIG5vdGUgYnkgSURcbiAgICogQHBhcmFtIG5vdGVJZCAtIFRoZSBJRCBvZiB0aGUgbm90ZSB0byBkZWxldGVcbiAgICogQHBhcmFtIGJyb3dzZXJQYXRoIC0gT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgcGF0aFxuICAgKiBAcmV0dXJucyBQcm9taXNlPERlbGV0ZVJlc3VsdD4gLSBEZWxldGUgb3BlcmF0aW9uIHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlTm90ZShub3RlSWQ6IHN0cmluZywgYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPERlbGV0ZVJlc3VsdD4ge1xuICAgIHRoaXMudmFsaWRhdGVEZWxldGVQYXJhbXMobm90ZUlkKTtcblxuICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZSh0cnVlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gTmF2aWdhdGUgdG8gY3JlYXRvciBjZW50ZXIgbm90ZSBtYW5hZ2VyXG4gICAgICBhd2FpdCB0aGlzLm5hdmlnYXRlVG9DcmVhdG9yQ2VudGVyKHBhZ2UpO1xuICAgICAgYXdhaXQgdGhpcy52ZXJpZnlVc2VyQXV0aGVudGljYXRpb24ocGFnZSk7XG5cbiAgICAgIC8vIEZpbmQgYW5kIGRlbGV0ZSB0aGUgc3BlY2lmaWMgbm90ZVxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5maW5kQW5kRGVsZXRlTm90ZShwYWdlLCBub3RlSWQpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICBkYXRhOiBudWxsLFxuICAgICAgICBub3RlSWQ6IHJlc3VsdC5ub3RlSWQsXG4gICAgICAgIHRpdGxlOiByZXN1bHQudGl0bGUsXG4gICAgICAgIGRlbGV0ZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgICAgbWVzc2FnZTogYFN1Y2Nlc3NmdWxseSBkZWxldGVkIG5vdGUgXCIke3Jlc3VsdC50aXRsZX1cIiAoSUQ6ICR7cmVzdWx0Lm5vdGVJZH0pYCxcbiAgICAgICAgb3BlcmF0aW9uOiAnZGVsZXRlTm90ZScsXG4gICAgICB9IGFzIHVua25vd24gYXMgRGVsZXRlUmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBkZWxldGUgbm90ZSAke25vdGVJZH06ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgZGF0YTogbnVsbCxcbiAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgbWVzc2FnZTogYEZhaWxlZCB0byBkZWxldGUgbm90ZTogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCxcbiAgICAgICAgZGVsZXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICBvcGVyYXRpb246ICdkZWxldGVOb3RlJyxcbiAgICAgIH0gYXMgdW5rbm93biBhcyBEZWxldGVSZXN1bHQ7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBsYXN0IHB1Ymxpc2hlZCBub3RlXG4gICAqIEBwYXJhbSBicm93c2VyUGF0aCAtIE9wdGlvbmFsIGN1c3RvbSBicm93c2VyIHBhdGhcbiAgICogQHJldHVybnMgUHJvbWlzZTxEZWxldGVSZXN1bHQ+IC0gRGVsZXRlIG9wZXJhdGlvbiByZXN1bHRcbiAgICovXG4gIGFzeW5jIGRlbGV0ZUxhc3RQdWJsaXNoZWROb3RlKGJyb3dzZXJQYXRoPzogc3RyaW5nKTogUHJvbWlzZTxEZWxldGVSZXN1bHQ+IHtcbiAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIE5hdmlnYXRlIHRvIGNyZWF0b3IgY2VudGVyIG5vdGUgbWFuYWdlclxuICAgICAgYXdhaXQgdGhpcy5uYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlKTtcbiAgICAgIGF3YWl0IHRoaXMudmVyaWZ5VXNlckF1dGhlbnRpY2F0aW9uKHBhZ2UpO1xuXG4gICAgICAvLyBGaW5kIGFuZCBkZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGVcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZmluZEFuZERlbGV0ZUxhc3ROb3RlKHBhZ2UpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICBkYXRhOiBudWxsLFxuICAgICAgICBub3RlSWQ6IHJlc3VsdC5ub3RlSWQsXG4gICAgICAgIHRpdGxlOiByZXN1bHQudGl0bGUsXG4gICAgICAgIGRlbGV0ZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgICAgbWVzc2FnZTogYFN1Y2Nlc3NmdWxseSBkZWxldGVkIGxhc3QgcHVibGlzaGVkIG5vdGUgXCIke3Jlc3VsdC50aXRsZX1cIiAoSUQ6ICR7cmVzdWx0Lm5vdGVJZH0pYCxcbiAgICAgICAgb3BlcmF0aW9uOiAnZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUnLFxuICAgICAgfSBhcyB1bmtub3duIGFzIERlbGV0ZVJlc3VsdDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZGVsZXRlIGxhc3QgcHVibGlzaGVkIG5vdGU6ICR7ZXJyb3J9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgZGF0YTogbnVsbCxcbiAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgbWVzc2FnZTogYEZhaWxlZCB0byBkZWxldGUgbGFzdCBwdWJsaXNoZWQgbm90ZTogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCxcbiAgICAgICAgZGVsZXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICBvcGVyYXRpb246ICdkZWxldGVMYXN0UHVibGlzaGVkTm90ZScsXG4gICAgICB9IGFzIHVua25vd24gYXMgRGVsZXRlUmVzdWx0O1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBwYWdlLmNsb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGRlbGV0ZSBwYXJhbWV0ZXJzXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlRGVsZXRlUGFyYW1zKG5vdGVJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFub3RlSWQgfHwgbm90ZUlkLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBEZWxldGVFcnJvcignTm90ZSBJRCBpcyByZXF1aXJlZCcsIHsgbm90ZUlkIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOYXZpZ2F0ZSB0byBjcmVhdG9yIGNlbnRlciBub3RlIG1hbmFnZXJcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgbmF2aWdhdGVUb0NyZWF0b3JDZW50ZXIocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjcmVhdG9yQ2VudGVyVXJsID0gJ2h0dHBzOi8vY3JlYXRvci54aWFvaG9uZ3NodS5jb20vbmV3L25vdGUtbWFuYWdlcj9zb3VyY2U9b2ZmaWNpYWwnO1xuICAgICAgYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLm5hdmlnYXRlV2l0aFJldHJ5KHBhZ2UsIGNyZWF0b3JDZW50ZXJVcmwpO1xuICAgICAgYXdhaXQgc2xlZXAoNTAwMCk7IC8vIFdhaXQgbG9uZ2VyIGZvciBwYWdlIHRvIGxvYWQgY29tcGxldGVseVxuXG4gICAgICAvLyBEZWJ1ZzogTG9nIHBhZ2UgY29udGVudCB0byB1bmRlcnN0YW5kIHRoZSBzdHJ1Y3R1cmVcbiAgICAgIGNvbnN0IHBhZ2VDb250ZW50ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7XG4gICAgICAgIGNvbnN0IG5vdGVFbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2Rpdi5ub3RlLCBbY2xhc3MqPVwibm90ZVwiXSwgW2RhdGEtaW1wcmVzc2lvbl0nKTtcbiAgICAgICAgY29uc3QgYWxsQnV0dG9ucyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvbiwgW3JvbGU9XCJidXR0b25cIl0sIC5idG4sIFtjbGFzcyo9XCJidXR0b25cIl0nKTtcbiAgICAgICAgY29uc3QgYWxsTGlua3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdhW2hyZWYqPVwiL2V4cGxvcmUvXCJdJyk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0b3RhbE5vdGVFbGVtZW50czogbm90ZUVsZW1lbnRzLmxlbmd0aCxcbiAgICAgICAgICBub3RlRWxlbWVudENsYXNzZXM6IEFycmF5LmZyb20obm90ZUVsZW1lbnRzKS5tYXAoZWwgPT4gZWwuY2xhc3NOYW1lKSxcbiAgICAgICAgICB0b3RhbEJ1dHRvbnM6IGFsbEJ1dHRvbnMubGVuZ3RoLFxuICAgICAgICAgIGJ1dHRvblRleHRzOiBBcnJheS5mcm9tKGFsbEJ1dHRvbnMpLnNsaWNlKDAsIDEwKS5tYXAoYnRuID0+IGJ0bi50ZXh0Q29udGVudD8udHJpbSgpKS5maWx0ZXIoQm9vbGVhbiksXG4gICAgICAgICAgYnV0dG9uQ2xhc3NlczogQXJyYXkuZnJvbShhbGxCdXR0b25zKS5zbGljZSgwLCAxMCkubWFwKGJ0biA9PiBidG4uY2xhc3NOYW1lKSxcbiAgICAgICAgICBleHBsb3JlTGlua3M6IEFycmF5LmZyb20oYWxsTGlua3MpLm1hcChsaW5rID0+IGxpbmsuZ2V0QXR0cmlidXRlKCdocmVmJykpLFxuICAgICAgICAgIHBhZ2VUaXRsZTogZG9jdW1lbnQudGl0bGUsXG4gICAgICAgICAgY3VycmVudFVybDogd2luZG93LmxvY2F0aW9uLmhyZWZcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgICBsb2dnZXIuaW5mbyhgUGFnZSBsb2FkZWQ6ICR7SlNPTi5zdHJpbmdpZnkocGFnZUNvbnRlbnQsIG51bGwsIDIpfWApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IoXG4gICAgICAgICdGYWlsZWQgdG8gbmF2aWdhdGUgdG8gY3JlYXRvciBjZW50ZXInLFxuICAgICAgICB7IHVybDogJ2h0dHBzOi8vY3JlYXRvci54aWFvaG9uZ3NodS5jb20vbmV3L25vdGUtbWFuYWdlcj9zb3VyY2U9b2ZmaWNpYWwnIH0sXG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHVzZXIgaXMgYXV0aGVudGljYXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB2ZXJpZnlVc2VyQXV0aGVudGljYXRpb24ocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBDaGVjayBmb3IgbG9naW4gZWxlbWVudHMgb24gdGhlIGN1cnJlbnQgcGFnZVxuICAgICAgY29uc3QgbG9naW5FbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQodGhpcy5nZXRDb25maWcoKS54aHMubG9naW5Pa1NlbGVjdG9yKTtcblxuICAgICAgLy8gQWxzbyBjaGVjayBmb3IgY3JlYXRvciBjZW50ZXIgc3BlY2lmaWMgZWxlbWVudHNcbiAgICAgIGNvbnN0IGNyZWF0b3JFbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoXG4gICAgICAgICdbY2xhc3MqPVwidXNlclwiXSwgW2NsYXNzKj1cInByb2ZpbGVcIl0sIFtjbGFzcyo9XCJhdmF0YXJcIl0nXG4gICAgICApO1xuXG4gICAgICBpZiAobG9naW5FbGVtZW50cy5sZW5ndGggPT09IDAgJiYgY3JlYXRvckVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiBhIGxvZ2luIHBhZ2VcbiAgICAgICAgY29uc3QgY3VycmVudFVybCA9IHBhZ2UudXJsKCk7XG4gICAgICAgIGlmIChjdXJyZW50VXJsLmluY2x1ZGVzKCdsb2dpbicpIHx8IGN1cnJlbnRVcmwuaW5jbHVkZXMoJ3NpZ25pbicpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vdExvZ2dlZEluRXJyb3IoJ1VzZXIgbm90IGxvZ2dlZCBpbicsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogJ2RlbGV0ZU5vdGUnLFxuICAgICAgICAgICAgdXJsOiBjdXJyZW50VXJsLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIGNyZWF0b3IgY2VudGVyLCBjaGVjayBpZiB3ZSBjYW4gc2VlIG5vdGUgbWFuYWdlbWVudCBlbGVtZW50c1xuICAgICAgICBjb25zdCBub3RlRWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKCdkaXYubm90ZScpO1xuICAgICAgICBpZiAobm90ZUVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBOb3RMb2dnZWRJbkVycm9yKCdVc2VyIG5vdCBsb2dnZWQgaW4gb3Igbm8gbm90ZXMgZm91bmQnLCB7XG4gICAgICAgICAgICBvcGVyYXRpb246ICdkZWxldGVOb3RlJyxcbiAgICAgICAgICAgIHVybDogY3VycmVudFVybCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb3RMb2dnZWRJbkVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIHZlcmlmeSBhdXRoZW50aWNhdGlvbicsXG4gICAgICAgIHsgb3BlcmF0aW9uOiAndmVyaWZ5QXV0aCcgfSxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGFuZCBkZWxldGUgYSBzcGVjaWZpYyBub3RlIGJ5IElEXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGZpbmRBbmREZWxldGVOb3RlKHBhZ2U6IFBhZ2UsIG5vdGVJZDogc3RyaW5nKTogUHJvbWlzZTx7IG5vdGVJZDogc3RyaW5nOyB0aXRsZTogc3RyaW5nIH0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZShcbiAgICAgICAgKHNlbGVjdG9yczogdHlwZW9mIERFTEVURV9TRUxFQ1RPUlMsIHRhcmdldE5vdGVJZDogc3RyaW5nKSA9PiB7XG5cbiAgICAgICAgICAvLyBUcnkgZWFjaCBub3RlIGl0ZW0gc2VsZWN0b3JcbiAgICAgICAgICBsZXQgbm90ZUVsZW1lbnRzOiBFbGVtZW50W10gPSBbXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycy5OT1RFX0lURU0pIHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG4gICAgICAgICAgICBpZiAoZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBub3RlRWxlbWVudHMgPSBlbGVtZW50cztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5vdGVFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogdGFyZ2V0Tm90ZUlkLCB0aXRsZTogJycsIGZvdW5kOiBmYWxzZSwgZXJyb3I6ICdObyBub3RlIGVsZW1lbnRzIGZvdW5kIG9uIHBhZ2UnIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChjb25zdCBub3RlRWxlbWVudCBvZiBub3RlRWxlbWVudHMpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgdGhlIG5vdGUgd2Ugd2FudCB0byBkZWxldGVcbiAgICAgICAgICAgIGNvbnN0IGltcHJlc3Npb25EYXRhID0gbm90ZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWltcHJlc3Npb24nKTtcbiAgICAgICAgICAgIGxldCBjdXJyZW50Tm90ZUlkID0gJyc7XG5cbiAgICAgICAgICAgIGlmIChpbXByZXNzaW9uRGF0YSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoaW1wcmVzc2lvbkRhdGEpO1xuICAgICAgICAgICAgICAgIGN1cnJlbnROb3RlSWQgPSBwYXJzZWQ/Lm5vdGVUYXJnZXQ/LnZhbHVlPy5ub3RlSWQgfHwgJyc7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBJZ25vcmUgcGFyc2luZyBlcnJvcnNcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBbHNvIHRyeSB0byBmaW5kIG5vdGUgSUQgaW4gb3RoZXIgYXR0cmlidXRlcyBvciBkYXRhXG4gICAgICAgICAgICBpZiAoIWN1cnJlbnROb3RlSWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgbGlua0VsZW1lbnQgPSBub3RlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdhW2hyZWYqPVwiL2V4cGxvcmUvXCJdLCBhW2hyZWYqPVwiL25vdGUvXCJdJyk7XG4gICAgICAgICAgICAgIGlmIChsaW5rRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhyZWYgPSBsaW5rRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSB8fCAnJztcbiAgICAgICAgICAgICAgICBjb25zdCBtYXRjaCA9IGhyZWYubWF0Y2goL1xcL2V4cGxvcmVcXC8oW2EtekEtWjAtOV0rKS8pO1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgY3VycmVudE5vdGVJZCA9IG1hdGNoWzFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY3VycmVudE5vdGVJZCA9PT0gdGFyZ2V0Tm90ZUlkKSB7XG4gICAgICAgICAgICAgIC8vIEZvdW5kIHRoZSB0YXJnZXQgbm90ZSwgdHJ5IHRvIGRlbGV0ZSBpdFxuICAgICAgICAgICAgICBjb25zdCB0aXRsZUVsZW1lbnQgPSBub3RlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdbY2xhc3MqPVwidGl0bGVcIl0sIFtjbGFzcyo9XCJuYW1lXCJdJyk7XG4gICAgICAgICAgICAgIGNvbnN0IHRpdGxlID0gdGl0bGVFbGVtZW50Py50ZXh0Q29udGVudD8udHJpbSgpIHx8ICdVbmtub3duJztcblxuICAgICAgICAgICAgICAvLyBMb29rIGZvciBkZWxldGUgYnV0dG9uIG9yIG1vcmUgb3B0aW9ucyBidXR0b25cbiAgICAgICAgICAgICAgbGV0IGRlbGV0ZUJ1dHRvbjogRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gICAgICAgICAgICAgIC8vIFRyeSBlYWNoIGRlbGV0ZSBidXR0b24gc2VsZWN0b3JcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuREVMRVRFX0JVVFRPTikge1xuICAgICAgICAgICAgICAgIGRlbGV0ZUJ1dHRvbiA9IG5vdGVFbGVtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgIGlmIChkZWxldGVCdXR0b24pIHtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICghZGVsZXRlQnV0dG9uKSB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IHRvIGZpbmQgbW9yZSBvcHRpb25zIGJ1dHRvbiBmaXJzdFxuICAgICAgICAgICAgICAgIGxldCBtb3JlQnV0dG9uOiBFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuTU9SRV9PUFRJT05TKSB7XG4gICAgICAgICAgICAgICAgICBtb3JlQnV0dG9uID0gbm90ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgICBpZiAobW9yZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAobW9yZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgKG1vcmVCdXR0b24gYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7XG5cbiAgICAgICAgICAgICAgICAgIC8vIFdhaXQgZm9yIGRyb3Bkb3duIHRvIGFwcGVhciBhbmQgbG9vayBmb3IgZGVsZXRlIG9wdGlvblxuICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygc2VsZWN0b3JzLkRST1BET1dOX01FTlUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkcm9wZG93biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChkcm9wZG93bikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBkZWxldGVTZWxlY3RvciBvZiBzZWxlY3RvcnMuREVMRVRFX0JVVFRPTikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVCdXR0b24gPSBkcm9wZG93bi5xdWVyeVNlbGVjdG9yKGRlbGV0ZVNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGV0ZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVsZXRlQnV0dG9uKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0sIDEwMDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChkZWxldGVCdXR0b24pIHtcbiAgICAgICAgICAgICAgICAoZGVsZXRlQnV0dG9uIGFzIEhUTUxFbGVtZW50KS5jbGljaygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogY3VycmVudE5vdGVJZCwgdGl0bGUsIGZvdW5kOiB0cnVlIH07XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgbm90ZUlkOiBjdXJyZW50Tm90ZUlkLCB0aXRsZSwgZm91bmQ6IGZhbHNlLCBlcnJvcjogJ0RlbGV0ZSBidXR0b24gbm90IGZvdW5kJyB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHsgbm90ZUlkOiB0YXJnZXROb3RlSWQsIHRpdGxlOiAnJywgZm91bmQ6IGZhbHNlLCBlcnJvcjogJ05vdGUgbm90IGZvdW5kJyB9O1xuICAgICAgICB9LFxuICAgICAgICBERUxFVEVfU0VMRUNUT1JTLFxuICAgICAgICBub3RlSWRcbiAgICAgICk7XG5cbiAgICAgIGlmICghcmVzdWx0LmZvdW5kKSB7XG4gICAgICAgIHRocm93IG5ldyBEZWxldGVFcnJvcihyZXN1bHQuZXJyb3IgfHwgJ05vdGUgbm90IGZvdW5kJywgeyBub3RlSWQgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFdhaXQgZm9yIGNvbmZpcm1hdGlvbiBkaWFsb2cgaWYgaXQgYXBwZWFyc1xuICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG5cbiAgICAgIC8vIEhhbmRsZSBjb25maXJtYXRpb24gZGlhbG9nXG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZUNvbmZpcm1hdGlvbkRpYWxvZyhwYWdlKTtcblxuICAgICAgcmV0dXJuIHsgbm90ZUlkOiByZXN1bHQubm90ZUlkLCB0aXRsZTogcmVzdWx0LnRpdGxlIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBEZWxldGVFcnJvcihcbiAgICAgICAgJ0ZhaWxlZCB0byBmaW5kIGFuZCBkZWxldGUgbm90ZScsXG4gICAgICAgIHsgbm90ZUlkIH0sXG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhbmQgZGVsZXRlIHRoZSBsYXN0IHB1Ymxpc2hlZCBub3RlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGZpbmRBbmREZWxldGVMYXN0Tm90ZShwYWdlOiBQYWdlKTogUHJvbWlzZTx7IG5vdGVJZDogc3RyaW5nOyB0aXRsZTogc3RyaW5nIH0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoc2VsZWN0b3JzOiB0eXBlb2YgREVMRVRFX1NFTEVDVE9SUykgPT4ge1xuXG4gICAgICAgIC8vIFRyeSBlYWNoIG5vdGUgaXRlbSBzZWxlY3RvclxuICAgICAgICBsZXQgbm90ZUVsZW1lbnRzOiBFbGVtZW50W10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuTk9URV9JVEVNKSB7XG4gICAgICAgICAgY29uc3QgZWxlbWVudHMgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTtcbiAgICAgICAgICBpZiAoZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbm90ZUVsZW1lbnRzID0gZWxlbWVudHM7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobm90ZUVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogJycsIHRpdGxlOiAnJywgZm91bmQ6IGZhbHNlLCBlcnJvcjogJ05vIG5vdGVzIGZvdW5kJyB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IHRoZSBmaXJzdCBub3RlIChtb3N0IHJlY2VudClcbiAgICAgICAgY29uc3QgZmlyc3ROb3RlID0gbm90ZUVsZW1lbnRzWzBdO1xuXG4gICAgICAgIC8vIEV4dHJhY3Qgbm90ZSBJRFxuICAgICAgICBsZXQgbm90ZUlkID0gJyc7XG4gICAgICAgIGNvbnN0IGltcHJlc3Npb25EYXRhID0gZmlyc3ROb3RlLmdldEF0dHJpYnV0ZSgnZGF0YS1pbXByZXNzaW9uJyk7XG5cbiAgICAgICAgaWYgKGltcHJlc3Npb25EYXRhKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoaW1wcmVzc2lvbkRhdGEpO1xuICAgICAgICAgICAgbm90ZUlkID0gcGFyc2VkPy5ub3RlVGFyZ2V0Py52YWx1ZT8ubm90ZUlkIHx8ICcnO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBwYXJzaW5nIGVycm9yc1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFsc28gdHJ5IHRvIGZpbmQgbm90ZSBJRCBpbiBsaW5rXG4gICAgICAgIGlmICghbm90ZUlkKSB7XG4gICAgICAgICAgY29uc3QgbGlua0VsZW1lbnQgPSBmaXJzdE5vdGUucXVlcnlTZWxlY3RvcignYVtocmVmKj1cIi9leHBsb3JlL1wiXSwgYVtocmVmKj1cIi9ub3RlL1wiXScpO1xuICAgICAgICAgIGlmIChsaW5rRWxlbWVudCkge1xuICAgICAgICAgICAgY29uc3QgaHJlZiA9IGxpbmtFbGVtZW50LmdldEF0dHJpYnV0ZSgnaHJlZicpIHx8ICcnO1xuICAgICAgICAgICAgY29uc3QgbWF0Y2ggPSBocmVmLm1hdGNoKC9cXC9leHBsb3JlXFwvKFthLXpBLVowLTldKykvKTtcbiAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICBub3RlSWQgPSBtYXRjaFsxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFeHRyYWN0IHRpdGxlXG4gICAgICAgIGNvbnN0IHRpdGxlRWxlbWVudCA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKCdbY2xhc3MqPVwidGl0bGVcIl0sIFtjbGFzcyo9XCJuYW1lXCJdJyk7XG4gICAgICAgIGNvbnN0IHRpdGxlID0gdGl0bGVFbGVtZW50Py50ZXh0Q29udGVudD8udHJpbSgpIHx8ICdVbmtub3duJztcblxuICAgICAgICAvLyBMb29rIGZvciBkZWxldGUgYnV0dG9uIG9yIG1vcmUgb3B0aW9ucyBidXR0b25cbiAgICAgICAgbGV0IGRlbGV0ZUJ1dHRvbjogRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gICAgICAgIC8vIFRyeSBlYWNoIGRlbGV0ZSBidXR0b24gc2VsZWN0b3JcbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuREVMRVRFX0JVVFRPTikge1xuICAgICAgICAgIGRlbGV0ZUJ1dHRvbiA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICBpZiAoZGVsZXRlQnV0dG9uKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWRlbGV0ZUJ1dHRvbikge1xuICAgICAgICAgIC8vIFRyeSB0byBmaW5kIG1vcmUgb3B0aW9ucyBidXR0b24gZmlyc3RcbiAgICAgICAgICBsZXQgbW9yZUJ1dHRvbjogRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICAgICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygc2VsZWN0b3JzLk1PUkVfT1BUSU9OUykge1xuICAgICAgICAgICAgbW9yZUJ1dHRvbiA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICAgIGlmIChtb3JlQnV0dG9uKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChtb3JlQnV0dG9uKSB7XG4gICAgICAgICAgICAobW9yZUJ1dHRvbiBhcyBIVE1MRWxlbWVudCkuY2xpY2soKTtcblxuICAgICAgICAgICAgLy8gV2FpdCBmb3IgZHJvcGRvd24gdG8gYXBwZWFyIGFuZCBsb29rIGZvciBkZWxldGUgb3B0aW9uXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuRFJPUERPV05fTUVOVSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRyb3Bkb3duID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgaWYgKGRyb3Bkb3duKSB7XG4gICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGRlbGV0ZVNlbGVjdG9yIG9mIHNlbGVjdG9ycy5ERUxFVEVfQlVUVE9OKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZUJ1dHRvbiA9IGRyb3Bkb3duLnF1ZXJ5U2VsZWN0b3IoZGVsZXRlU2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGVsZXRlQnV0dG9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGlmIChkZWxldGVCdXR0b24pIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgMTAwMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRlbGV0ZUJ1dHRvbikge1xuICAgICAgICAgIChkZWxldGVCdXR0b24gYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7XG4gICAgICAgICAgcmV0dXJuIHsgbm90ZUlkLCB0aXRsZSwgZm91bmQ6IHRydWUgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4geyBub3RlSWQsIHRpdGxlLCBmb3VuZDogZmFsc2UsIGVycm9yOiAnRGVsZXRlIGJ1dHRvbiBub3QgZm91bmQnIH07XG4gICAgICAgIH1cbiAgICAgIH0sIERFTEVURV9TRUxFQ1RPUlMpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5mb3VuZCkge1xuICAgICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IocmVzdWx0LmVycm9yIHx8ICdGYWlsZWQgdG8gZmluZCBkZWxldGUgYnV0dG9uJywge30pO1xuICAgICAgfVxuXG4gICAgICAvLyBXYWl0IGZvciBjb25maXJtYXRpb24gZGlhbG9nIGlmIGl0IGFwcGVhcnNcbiAgICAgIGF3YWl0IHNsZWVwKDEwMDApO1xuXG4gICAgICAvLyBIYW5kbGUgY29uZmlybWF0aW9uIGRpYWxvZ1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVDb25maXJtYXRpb25EaWFsb2cocGFnZSk7XG5cbiAgICAgIHJldHVybiB7IG5vdGVJZDogcmVzdWx0Lm5vdGVJZCwgdGl0bGU6IHJlc3VsdC50aXRsZSB9O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IoXG4gICAgICAgICdGYWlsZWQgdG8gZmluZCBhbmQgZGVsZXRlIGxhc3Qgbm90ZScsXG4gICAgICAgIHt9LFxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBjb25maXJtYXRpb24gZGlhbG9nIGZvciBkZWxldGUgb3BlcmF0aW9uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGhhbmRsZUNvbmZpcm1hdGlvbkRpYWxvZyhwYWdlOiBQYWdlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFdhaXQgZm9yIGNvbmZpcm1hdGlvbiBkaWFsb2cgdG8gYXBwZWFyXG4gICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcblxuICAgICAgLy8gTG9vayBmb3IgY29uZmlybWF0aW9uIGJ1dHRvbnMgdXNpbmcgYWxsIHBvc3NpYmxlIHNlbGVjdG9yc1xuICAgICAgbGV0IGNvbmZpcm1CdXR0b24gPSBudWxsO1xuXG4gICAgICAvLyBUcnkgZWFjaCBjb25maXJtIGJ1dHRvbiBzZWxlY3RvclxuICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBERUxFVEVfU0VMRUNUT1JTLkNPTkZJUk1fQlVUVE9OKSB7XG4gICAgICAgIGNvbmZpcm1CdXR0b24gPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICBpZiAoY29uZmlybUJ1dHRvbikge1xuICAgICAgICAgIGxvZ2dlci5pbmZvKGBGb3VuZCBjb25maXJtIGJ1dHRvbiB3aXRoIHNlbGVjdG9yOiAke3NlbGVjdG9yfWApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIElmIG5vdCBmb3VuZCwgdHJ5IG1vZGFsIGNvbmZpcm0gc2VsZWN0b3JzXG4gICAgICBpZiAoIWNvbmZpcm1CdXR0b24pIHtcbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBERUxFVEVfU0VMRUNUT1JTLk1PREFMX0NPTkZJUk0pIHtcbiAgICAgICAgICBjb25maXJtQnV0dG9uID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgICBpZiAoY29uZmlybUJ1dHRvbikge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYEZvdW5kIG1vZGFsIGNvbmZpcm0gYnV0dG9uIHdpdGggc2VsZWN0b3I6ICR7c2VsZWN0b3J9YCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpcm1CdXR0b24pIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ0NsaWNraW5nIGNvbmZpcm1hdGlvbiBidXR0b24nKTtcbiAgICAgICAgYXdhaXQgY29uZmlybUJ1dHRvbi5jbGljaygpO1xuICAgICAgICBhd2FpdCBzbGVlcCgyMDAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIG5vIGNvbmZpcm1hdGlvbiBkaWFsb2csIHRoZSBkZWxldGUgbWlnaHQgaGF2ZSBiZWVuIGltbWVkaWF0ZVxuICAgICAgICBsb2dnZXIuaW5mbygnTm8gY29uZmlybWF0aW9uIGRpYWxvZyBmb3VuZCwgZGVsZXRlIG1pZ2h0IGJlIGltbWVkaWF0ZScpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgRmFpbGVkIHRvIGhhbmRsZSBjb25maXJtYXRpb24gZGlhbG9nOiAke2Vycm9yfWApO1xuICAgICAgLy8gQ29udGludWUgYW55d2F5IGFzIHRoZSBkZWxldGUgbWlnaHQgc3RpbGwgd29ya1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBOb3RlIHNlcnZpY2UgZm9yIFhIUyBNQ1AgU2VydmVyXG4gKiBIYW5kbGVzIHVzZXIgbm90ZXMvZmVlZHMgb3BlcmF0aW9uc1xuICovXG5cbmltcG9ydCB0eXBlIHsgQ29uZmlnLCBYSFNSZXNwb25zZSB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBCYXNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9iYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscyc7XG5pbXBvcnQgeyBQcm9maWxlRXJyb3IsIE5vdGVQYXJzaW5nRXJyb3IsIE5vdExvZ2dlZEluRXJyb3IgfSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IERlbGV0ZVNlcnZpY2UsIERlbGV0ZVJlc3VsdCB9IGZyb20gJy4uL2RlbGV0aW5nL2RlbGV0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVzZXJOb3RlIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcmVhZG9ubHkgY29udGVudDogc3RyaW5nO1xuICByZWFkb25seSBpbWFnZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICByZWFkb25seSB2aWRlbz86IHN0cmluZztcbiAgcmVhZG9ubHkgcHVibGlzaFRpbWU6IG51bWJlcjtcbiAgcmVhZG9ubHkgdXBkYXRlVGltZTogbnVtYmVyO1xuICByZWFkb25seSBsaWtlQ291bnQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgY29tbWVudENvdW50OiBudW1iZXI7XG4gIHJlYWRvbmx5IHNoYXJlQ291bnQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgY29sbGVjdENvdW50OiBudW1iZXI7XG4gIHJlYWRvbmx5IHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICByZWFkb25seSB1cmw6IHN0cmluZztcbiAgcmVhZG9ubHkgdmlzaWJpbGl0eTogJ3B1YmxpYycgfCAncHJpdmF0ZScgfCAnZnJpZW5kcycgfCAndW5rbm93bic7XG4gIHJlYWRvbmx5IHZpc2liaWxpdHlUZXh0Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVzZXJOb3Rlc1Jlc3VsdCBleHRlbmRzIFhIU1Jlc3BvbnNlPFVzZXJOb3RlW10+IHtcbiAgcmVhZG9ubHkgdG90YWw6IG51bWJlcjtcbiAgcmVhZG9ubHkgaGFzTW9yZTogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbmV4dEN1cnNvcj86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIE5vdGVFeHRyYWN0aW9uRGF0YSB7XG4gIGlkOiBzdHJpbmc7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGNvbnRlbnQ6IHN0cmluZztcbiAgaW1hZ2VzOiBzdHJpbmdbXTtcbiAgcHVibGlzaFRpbWU6IG51bWJlcjtcbiAgdXBkYXRlVGltZTogbnVtYmVyO1xuICBsaWtlQ291bnQ6IG51bWJlcjtcbiAgY29tbWVudENvdW50OiBudW1iZXI7XG4gIHNoYXJlQ291bnQ6IG51bWJlcjtcbiAgY29sbGVjdENvdW50OiBudW1iZXI7XG4gIHRhZ3M6IHN0cmluZ1tdO1xuICB1cmw6IHN0cmluZztcbiAgdmlzaWJpbGl0eTogJ3B1YmxpYycgfCAncHJpdmF0ZScgfCAnZnJpZW5kcycgfCAndW5rbm93bic7XG4gIHZpc2liaWxpdHlUZXh0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ1NTIHNlbGVjdG9ycyBmb3Igbm90ZSBleHRyYWN0aW9uIGZyb20gQ3JlYXRvciBDZW50ZXJcbiAqL1xuY29uc3QgTk9URV9TRUxFQ1RPUlMgPSB7XG4gIE5PVEVfRUxFTUVOVFM6ICdkaXYubm90ZScsXG4gIFRJVExFX0VMRU1FTlRTOiAnW2NsYXNzKj1cInJhd1wiXSwgW2NsYXNzKj1cInRpdGxlXCJdLCBbY2xhc3MqPVwibmFtZVwiXScsXG4gIElNQUdFX0VMRU1FTlRTOiAnaW1nW2NsYXNzKj1cIm1lZGlhXCJdLCBpbWdbY2xhc3MqPVwiY292ZXJcIl0sIGltZ1tjbGFzcyo9XCJ0aHVtYm5haWxcIl0nLFxuICBTVEFUX0VMRU1FTlRTOiAnW2NsYXNzKj1cImNvdW50XCJdLCBbY2xhc3MqPVwic3RhdFwiXSwgW2NsYXNzKj1cIm51bWJlclwiXScsXG4gIFRBR19FTEVNRU5UUzogJ1tjbGFzcyo9XCJ0YWdcIl0sIFtjbGFzcyo9XCJsYWJlbFwiXScsXG4gIE5PVEVfTElOSzogJ2FbaHJlZio9XCIvZXhwbG9yZS9cIl0sIGFbaHJlZio9XCIvbm90ZS9cIl0nLFxuICBWSVNJQklMSVRZX0lORElDQVRPUlM6XG4gICAgJ1tjbGFzcyo9XCJwcml2YXRlXCJdLCBbY2xhc3MqPVwidmlzaWJpbGl0eVwiXSwgW2NsYXNzKj1cImxvY2tcIl0sIFtjbGFzcyo9XCJleWVcIl0sIFtjbGFzcyo9XCJwdWJsaWNcIl0sIFtjbGFzcyo9XCJmcmllbmRzXCJdLCBbY2xhc3MqPVwic3RhdHVzXCJdJyxcbiAgUFVCTElTSF9USU1FOiAnW2NsYXNzKj1cInRpbWVcIl0sIFtjbGFzcyo9XCJkYXRlXCJdLCBbY2xhc3MqPVwicHVibGlzaC10aW1lXCJdJyxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjbGFzcyBOb3RlU2VydmljZSBleHRlbmRzIEJhc2VTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBkZWxldGVTZXJ2aWNlOiBEZWxldGVTZXJ2aWNlO1xuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnKSB7XG4gICAgc3VwZXIoY29uZmlnKTtcbiAgICB0aGlzLmRlbGV0ZVNlcnZpY2UgPSBuZXcgRGVsZXRlU2VydmljZShjb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHVzZXIncyBwdWJsaXNoZWQgbm90ZXMgZnJvbSBjcmVhdG9yIGNlbnRlclxuICAgKiBAcGFyYW0gbGltaXQgLSBNYXhpbXVtIG51bWJlciBvZiBub3RlcyB0byByZXR1cm4gKGRlZmF1bHQ6IDIwKVxuICAgKiBAcGFyYW0gY3Vyc29yIC0gUGFnaW5hdGlvbiBjdXJzb3IgZm9yIG5leHQgcGFnZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8VXNlck5vdGVzUmVzdWx0PiAtIFVzZXIgbm90ZXMgd2l0aCBwYWdpbmF0aW9uIGluZm9cbiAgICovXG4gIGFzeW5jIGdldFVzZXJOb3RlcyhcbiAgICBsaW1pdDogbnVtYmVyID0gMjAsXG4gICAgY3Vyc29yPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8VXNlck5vdGVzUmVzdWx0PiB7XG4gICAgdGhpcy52YWxpZGF0ZUdldFVzZXJOb3Rlc1BhcmFtcyhsaW1pdCk7XG5cbiAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIE5hdmlnYXRlIHRvIGNyZWF0b3IgY2VudGVyIG5vdGUgbWFuYWdlclxuICAgICAgYXdhaXQgdGhpcy5uYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlKTtcbiAgICAgIGF3YWl0IHRoaXMudmVyaWZ5VXNlckF1dGhlbnRpY2F0aW9uKHBhZ2UpO1xuXG4gICAgICAvLyBFeHRyYWN0IG5vdGVzIGZyb20gY3JlYXRvciBjZW50ZXJcbiAgICAgIGNvbnN0IG5vdGVzRGF0YSA9IGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVzRnJvbUNyZWF0b3JDZW50ZXIocGFnZSk7XG4gICAgICBjb25zdCBsaW1pdGVkTm90ZXMgPSB0aGlzLmxpbWl0Tm90ZXMobm90ZXNEYXRhLCBsaW1pdCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGRhdGE6IGxpbWl0ZWROb3RlcyxcbiAgICAgICAgdG90YWw6IG5vdGVzRGF0YS5sZW5ndGgsXG4gICAgICAgIGhhc01vcmU6IG5vdGVzRGF0YS5sZW5ndGggPiBsaW1pdCxcbiAgICAgICAgbmV4dEN1cnNvcjogdGhpcy5nZXROZXh0Q3Vyc29yKGxpbWl0ZWROb3RlcyksXG4gICAgICAgIG9wZXJhdGlvbjogJ2dldFVzZXJOb3RlcycsXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlck5vdGVzUmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgdXNlciBub3RlczogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgdG90YWw6IDAsXG4gICAgICAgIGhhc01vcmU6IGZhbHNlLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICBvcGVyYXRpb246ICdnZXRVc2VyTm90ZXMnLFxuICAgICAgfSBhcyB1bmtub3duIGFzIFVzZXJOb3Rlc1Jlc3VsdDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBwYXJhbWV0ZXJzIGZvciBnZXRVc2VyTm90ZXMgbWV0aG9kXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlR2V0VXNlck5vdGVzUGFyYW1zKGxpbWl0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAobGltaXQgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IE5vdGVQYXJzaW5nRXJyb3IoJ0xpbWl0IG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnLCB7IGxpbWl0IH0pO1xuICAgIH1cbiAgICBpZiAobGltaXQgPiAxMDApIHtcbiAgICAgIHRocm93IG5ldyBOb3RlUGFyc2luZ0Vycm9yKCdMaW1pdCBjYW5ub3QgZXhjZWVkIDEwMCcsIHsgbGltaXQgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE5hdmlnYXRlIHRvIGNyZWF0b3IgY2VudGVyIG5vdGUgbWFuYWdlclxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBuYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlOiBQYWdlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNyZWF0b3JDZW50ZXJVcmwgPSAnaHR0cHM6Ly9jcmVhdG9yLnhpYW9ob25nc2h1LmNvbS9uZXcvbm90ZS1tYW5hZ2VyP3NvdXJjZT1vZmZpY2lhbCc7XG4gICAgICBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkubmF2aWdhdGVXaXRoUmV0cnkocGFnZSwgY3JlYXRvckNlbnRlclVybCk7XG4gICAgICBhd2FpdCBzbGVlcCgzMDAwKTsgLy8gV2FpdCBmb3IgcGFnZSB0byBsb2FkIGNvbXBsZXRlbHlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IE5vdGVQYXJzaW5nRXJyb3IoXG4gICAgICAgICdGYWlsZWQgdG8gbmF2aWdhdGUgdG8gY3JlYXRvciBjZW50ZXInLFxuICAgICAgICB7IHVybDogJ2h0dHBzOi8vY3JlYXRvci54aWFvaG9uZ3NodS5jb20vbmV3L25vdGUtbWFuYWdlcj9zb3VyY2U9b2ZmaWNpYWwnIH0sXG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHVzZXIgaXMgYXV0aGVudGljYXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB2ZXJpZnlVc2VyQXV0aGVudGljYXRpb24ocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBDaGVjayBmb3IgbG9naW4gZWxlbWVudHMgb24gdGhlIGN1cnJlbnQgcGFnZVxuICAgICAgY29uc3QgbG9naW5FbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQodGhpcy5nZXRDb25maWcoKS54aHMubG9naW5Pa1NlbGVjdG9yKTtcblxuICAgICAgLy8gQWxzbyBjaGVjayBmb3IgY3JlYXRvciBjZW50ZXIgc3BlY2lmaWMgZWxlbWVudHNcbiAgICAgIGNvbnN0IGNyZWF0b3JFbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoXG4gICAgICAgICdbY2xhc3MqPVwidXNlclwiXSwgW2NsYXNzKj1cInByb2ZpbGVcIl0sIFtjbGFzcyo9XCJhdmF0YXJcIl0nXG4gICAgICApO1xuXG4gICAgICBpZiAobG9naW5FbGVtZW50cy5sZW5ndGggPT09IDAgJiYgY3JlYXRvckVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiBhIGxvZ2luIHBhZ2VcbiAgICAgICAgY29uc3QgY3VycmVudFVybCA9IHBhZ2UudXJsKCk7XG4gICAgICAgIGlmIChjdXJyZW50VXJsLmluY2x1ZGVzKCdsb2dpbicpIHx8IGN1cnJlbnRVcmwuaW5jbHVkZXMoJ3NpZ25pbicpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vdExvZ2dlZEluRXJyb3IoJ1VzZXIgbm90IGxvZ2dlZCBpbicsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogJ2dldFVzZXJOb3RlcycsXG4gICAgICAgICAgICB1cmw6IGN1cnJlbnRVcmwsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3IgY3JlYXRvciBjZW50ZXIsIGNoZWNrIGlmIHdlIGNhbiBzZWUgbm90ZSBtYW5hZ2VtZW50IGVsZW1lbnRzXG4gICAgICAgIGNvbnN0IG5vdGVFbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQoJ2Rpdi5ub3RlJyk7XG4gICAgICAgIGlmIChub3RlRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vdExvZ2dlZEluRXJyb3IoJ1VzZXIgbm90IGxvZ2dlZCBpbiBvciBubyBub3RlcyBmb3VuZCcsIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbjogJ2dldFVzZXJOb3RlcycsXG4gICAgICAgICAgICB1cmw6IGN1cnJlbnRVcmwsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm90TG9nZ2VkSW5FcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBOb3RlUGFyc2luZ0Vycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIHZlcmlmeSBhdXRoZW50aWNhdGlvbicsXG4gICAgICAgIHsgb3BlcmF0aW9uOiAndmVyaWZ5QXV0aCcgfSxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0IG5vdGVzIGZyb20gY3JlYXRvciBjZW50ZXIgcGFnZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleHRyYWN0Tm90ZXNGcm9tQ3JlYXRvckNlbnRlcihwYWdlOiBQYWdlKTogUHJvbWlzZTxOb3RlRXh0cmFjdGlvbkRhdGFbXT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBub3Rlc0RhdGEgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChzZWxlY3RvcnM6IHR5cGVvZiBOT1RFX1NFTEVDVE9SUykgPT4ge1xuICAgICAgICBjb25zdCBub3RlczogTm90ZUV4dHJhY3Rpb25EYXRhW10gPSBbXTtcblxuICAgICAgICAvLyBGaW5kIG5vdGUgZWxlbWVudHMgdXNpbmcgdGhlIGNyZWF0b3IgY2VudGVyIHNlbGVjdG9yXG4gICAgICAgIGNvbnN0IG5vdGVFbGVtZW50cyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcnMuTk9URV9FTEVNRU5UUykpO1xuXG4gICAgICAgIG5vdGVFbGVtZW50cy5mb3JFYWNoKChlbGVtZW50OiBFbGVtZW50KSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEV4dHJhY3Qgbm90ZSBkYXRhIGZyb20gZWxlbWVudFxuICAgICAgICAgICAgY29uc3QgcHVibGlzaFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgY29uc3Qgbm90ZTogTm90ZUV4dHJhY3Rpb25EYXRhID0ge1xuICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgIHRpdGxlOiAnJyxcbiAgICAgICAgICAgICAgY29udGVudDogJycsXG4gICAgICAgICAgICAgIGltYWdlczogW10sXG4gICAgICAgICAgICAgIHB1Ymxpc2hUaW1lLFxuICAgICAgICAgICAgICB1cGRhdGVUaW1lOiBwdWJsaXNoVGltZSxcbiAgICAgICAgICAgICAgbGlrZUNvdW50OiAwLFxuICAgICAgICAgICAgICBjb21tZW50Q291bnQ6IDAsXG4gICAgICAgICAgICAgIHNoYXJlQ291bnQ6IDAsXG4gICAgICAgICAgICAgIGNvbGxlY3RDb3VudDogMCxcbiAgICAgICAgICAgICAgdGFnczogW10sXG4gICAgICAgICAgICAgIHVybDogJycsXG4gICAgICAgICAgICAgIHZpc2liaWxpdHk6ICd1bmtub3duJyxcbiAgICAgICAgICAgICAgdmlzaWJpbGl0eVRleHQ6ICcnLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gRXh0cmFjdCBub3RlIElEIGZyb20gZGF0YSBhdHRyaWJ1dGVzIG9yIGltcHJlc3Npb24gZGF0YVxuICAgICAgICAgICAgY29uc3QgaW1wcmVzc2lvbkRhdGEgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1pbXByZXNzaW9uJyk7XG4gICAgICAgICAgICBpZiAoaW1wcmVzc2lvbkRhdGEpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGltcHJlc3Npb25EYXRhKTtcbiAgICAgICAgICAgICAgICBjb25zdCBub3RlSWQgPSBwYXJzZWQ/Lm5vdGVUYXJnZXQ/LnZhbHVlPy5ub3RlSWQ7XG4gICAgICAgICAgICAgICAgaWYgKG5vdGVJZCkge1xuICAgICAgICAgICAgICAgICAgbm90ZS5pZCA9IG5vdGVJZDtcbiAgICAgICAgICAgICAgICAgIG5vdGUudXJsID0gYGh0dHBzOi8vd3d3LnhpYW9ob25nc2h1LmNvbS9leHBsb3JlLyR7bm90ZUlkfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gSWdub3JlIHBhcnNpbmcgZXJyb3JzXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRXh0cmFjdCB0aXRsZS9jb250ZW50XG4gICAgICAgICAgICBjb25zdCB0aXRsZUVsZW1lbnQgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3JzLlRJVExFX0VMRU1FTlRTKTtcbiAgICAgICAgICAgIGlmICh0aXRsZUVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGl0bGUgPSB0aXRsZUVsZW1lbnQudGV4dENvbnRlbnQ/LnRyaW0oKSA/PyAnJztcbiAgICAgICAgICAgICAgbm90ZS50aXRsZSA9IHRpdGxlO1xuICAgICAgICAgICAgICBub3RlLmNvbnRlbnQgPSB0aXRsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRXh0cmFjdCBpbWFnZXMgLSB0cnkgbXVsdGlwbGUgYXBwcm9hY2hlcyBmb3IgY3JlYXRvciBjZW50ZXJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlU2VsZWN0b3JzID0gW1xuICAgICAgICAgICAgICBzZWxlY3RvcnMuSU1BR0VfRUxFTUVOVFMsXG4gICAgICAgICAgICAgICdpbWcnLCAvLyBUcnkgYWxsIGltZyBlbGVtZW50c1xuICAgICAgICAgICAgICAnW2NsYXNzKj1cImltYWdlXCJdJyxcbiAgICAgICAgICAgICAgJ1tjbGFzcyo9XCJwaG90b1wiXScsXG4gICAgICAgICAgICAgICdbY2xhc3MqPVwicGljXCJdJyxcbiAgICAgICAgICAgICAgJ1tjbGFzcyo9XCJpbWdcIl0nLFxuICAgICAgICAgICAgICAnW3N0eWxlKj1cImJhY2tncm91bmQtaW1hZ2VcIl0nLCAvLyBCYWNrZ3JvdW5kIGltYWdlc1xuICAgICAgICAgICAgICAnZGl2W2NsYXNzKj1cImNvdmVyXCJdIGltZycsXG4gICAgICAgICAgICAgICdkaXZbY2xhc3MqPVwidGh1bWJuYWlsXCJdIGltZycsXG4gICAgICAgICAgICAgICdkaXZbY2xhc3MqPVwibWVkaWFcIl0gaW1nJyxcbiAgICAgICAgICAgIF07XG5cbiAgICAgICAgICAgIGxldCBpbWFnZUVsZW1lbnRzOiBhbnlbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBpbWFnZVNlbGVjdG9ycykge1xuICAgICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gICAgICAgICAgICAgIGlmIChlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgaW1hZ2VFbGVtZW50cyA9IEFycmF5LmZyb20oZWxlbWVudHMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGltYWdlRWxlbWVudHMuZm9yRWFjaCgoaW1nOiBFbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgIGxldCBzcmMgPSAnJztcblxuICAgICAgICAgICAgICAvLyBUcnkgZGlmZmVyZW50IHdheXMgdG8gZ2V0IGltYWdlIHNvdXJjZVxuICAgICAgICAgICAgICBjb25zdCBodG1sSW1nID0gaW1nIGFzIEhUTUxJbWFnZUVsZW1lbnQ7XG4gICAgICAgICAgICAgIGlmIChodG1sSW1nLnNyYykge1xuICAgICAgICAgICAgICAgIHNyYyA9IGh0bWxJbWcuc3JjO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGh0bWxJbWcuc3R5bGUgJiYgaHRtbEltZy5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UpIHtcbiAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGZyb20gYmFja2dyb3VuZC1pbWFnZSBDU1NcbiAgICAgICAgICAgICAgICBjb25zdCBiZ01hdGNoID0gaHRtbEltZy5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2UubWF0Y2goL3VybFxcKFsnXCJdPyhbXidcIl0rKVsnXCJdP1xcKS8pO1xuICAgICAgICAgICAgICAgIGlmIChiZ01hdGNoKSB7XG4gICAgICAgICAgICAgICAgICBzcmMgPSBiZ01hdGNoWzFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbWcuZ2V0QXR0cmlidXRlKCdkYXRhLXNyYycpKSB7XG4gICAgICAgICAgICAgICAgLy8gTGF6eSBsb2FkZWQgaW1hZ2VzXG4gICAgICAgICAgICAgICAgc3JjID0gaW1nLmdldEF0dHJpYnV0ZSgnZGF0YS1zcmMnKSB8fCAnJztcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbWcuZ2V0QXR0cmlidXRlKCdkYXRhLW9yaWdpbmFsJykpIHtcbiAgICAgICAgICAgICAgICAvLyBBbm90aGVyIGxhenkgbG9hZGluZyBhdHRyaWJ1dGVcbiAgICAgICAgICAgICAgICBzcmMgPSBpbWcuZ2V0QXR0cmlidXRlKCdkYXRhLW9yaWdpbmFsJykgfHwgJyc7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc3JjICYmXG4gICAgICAgICAgICAgICAgIXNyYy5pbmNsdWRlcygnYXZhdGFyJykgJiZcbiAgICAgICAgICAgICAgICAhc3JjLmluY2x1ZGVzKCdpY29uJykgJiZcbiAgICAgICAgICAgICAgICAhc3JjLmluY2x1ZGVzKCdsb2dvJykgJiZcbiAgICAgICAgICAgICAgICAhc3JjLmluY2x1ZGVzKCdwbGFjZWhvbGRlcicpICYmXG4gICAgICAgICAgICAgICAgc3JjLnN0YXJ0c1dpdGgoJ2h0dHAnKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBub3RlLmltYWdlcy5wdXNoKHNyYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgICAgIC8vIEV4dHJhY3Qgc3RhdHMgLSBsb29rIGZvciBudW1iZXJzIGluIHRoZSBlbGVtZW50XG4gICAgICAgICAgICBjb25zdCBhbGxUZXh0ID0gZWxlbWVudC50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgICAgIGNvbnN0IG51bWJlcnMgPSBhbGxUZXh0Lm1hdGNoKC9cXGQrL2cpIHx8IFtdO1xuXG4gICAgICAgICAgICAvLyBUcnkgdG8gZXh0cmFjdCBzdGF0cyBmcm9tIHRleHQgY29udGVudFxuICAgICAgICAgICAgaWYgKG51bWJlcnMubGVuZ3RoID49IDQpIHtcbiAgICAgICAgICAgICAgLy8gQXNzdW1pbmcgb3JkZXI6IGxpa2UsIGNvbW1lbnQsIHNoYXJlLCBjb2xsZWN0LCB2aWV3XG4gICAgICAgICAgICAgIG5vdGUubGlrZUNvdW50ID0gcGFyc2VJbnQobnVtYmVyc1swXSB8fCAnMCcpIHx8IDA7XG4gICAgICAgICAgICAgIG5vdGUuY29tbWVudENvdW50ID0gcGFyc2VJbnQobnVtYmVyc1sxXSkgfHwgMDtcbiAgICAgICAgICAgICAgbm90ZS5zaGFyZUNvdW50ID0gcGFyc2VJbnQobnVtYmVyc1syXSkgfHwgMDtcbiAgICAgICAgICAgICAgbm90ZS5jb2xsZWN0Q291bnQgPSBwYXJzZUludChudW1iZXJzWzNdKSB8fCAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IHB1Ymxpc2ggdGltZVxuICAgICAgICAgICAgY29uc3QgdGltZUVsZW1lbnQgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3JzLlBVQkxJU0hfVElNRSk7XG4gICAgICAgICAgICBpZiAodGltZUVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGltZVRleHQgPSB0aW1lRWxlbWVudC50ZXh0Q29udGVudD8udHJpbSgpIHx8ICcnO1xuICAgICAgICAgICAgICBpZiAodGltZVRleHQuaW5jbHVkZXMoJ+WPkeW4g+S6jicpKSB7XG4gICAgICAgICAgICAgICAgLy8gUGFyc2UgQ2hpbmVzZSBkYXRlIGZvcm1hdFxuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGVNYXRjaCA9IHRpbWVUZXh0Lm1hdGNoKFxuICAgICAgICAgICAgICAgICAgLyhcXGR7NH0p5bm0KFxcZHsxLDJ9KeaciChcXGR7MSwyfSnml6VcXHMrKFxcZHsxLDJ9KTooXFxkezJ9KS9cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGlmIChkYXRlTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IFssIHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZV0gPSBkYXRlTWF0Y2g7XG4gICAgICAgICAgICAgICAgICBjb25zdCBwdWJsaXNoRGF0ZSA9IG5ldyBEYXRlKFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUludCh5ZWFyKSxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQobW9udGgpIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQoZGF5KSxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQoaG91ciksXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlSW50KG1pbnV0ZSlcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICBub3RlLnB1Ymxpc2hUaW1lID0gcHVibGlzaERhdGUuZ2V0VGltZSgpO1xuICAgICAgICAgICAgICAgICAgbm90ZS51cGRhdGVUaW1lID0gcHVibGlzaERhdGUuZ2V0VGltZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IHZpc2liaWxpdHkgaW5mb3JtYXRpb25cbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRUZXh0ID0gZWxlbWVudC50ZXh0Q29udGVudD8udG9Mb3dlckNhc2UoKSB8fCAnJztcbiAgICAgICAgICAgIGlmIChlbGVtZW50VGV4dC5pbmNsdWRlcygn5LuF6Ieq5bex5Y+v6KeBJykpIHtcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5ID0gJ3ByaXZhdGUnO1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHlUZXh0ID0gJ+S7heiHquW3seWPr+ingSc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnRUZXh0LmluY2x1ZGVzKCfmnIvlj4vlj6/op4EnKSkge1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHkgPSAnZnJpZW5kcyc7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eVRleHQgPSAn5pyL5Y+L5Y+v6KeBJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudFRleHQuaW5jbHVkZXMoJ+WFrOW8gCcpKSB7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eSA9ICdwdWJsaWMnO1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHlUZXh0ID0gJ+WFrOW8gCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBEZWZhdWx0IHRvIHB1YmxpYyBmb3Igbm90ZXMgd2l0aG91dCBleHBsaWNpdCB2aXNpYmlsaXR5IGluZGljYXRvcnNcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5ID0gJ3B1YmxpYyc7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eVRleHQgPSAn5YWs5byAJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRXh0cmFjdCB0YWdzXG4gICAgICAgICAgICBjb25zdCB0YWdFbGVtZW50cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcnMuVEFHX0VMRU1FTlRTKTtcbiAgICAgICAgICAgIHRhZ0VsZW1lbnRzLmZvckVhY2goKHRhZzogRWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB0YWdUZXh0ID0gdGFnLnRleHRDb250ZW50Py50cmltKCk7XG4gICAgICAgICAgICAgIGlmICh0YWdUZXh0Py5zdGFydHNXaXRoKCcjJykpIHtcbiAgICAgICAgICAgICAgICBub3RlLnRhZ3MucHVzaCh0YWdUZXh0KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChub3RlLmlkKSB7XG4gICAgICAgICAgICAgIG5vdGVzLnB1c2gobm90ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBleHRyYWN0aW9uIGVycm9ycyBmb3IgaW5kaXZpZHVhbCBub3Rlc1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIG5vdGVzO1xuICAgICAgfSwgTk9URV9TRUxFQ1RPUlMpO1xuXG4gICAgICByZXR1cm4gbm90ZXNEYXRhO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgTm90ZVBhcnNpbmdFcnJvcihcbiAgICAgICAgJ0ZhaWxlZCB0byBleHRyYWN0IG5vdGVzIGZyb20gY3JlYXRvciBjZW50ZXInLFxuICAgICAgICB7IG9wZXJhdGlvbjogJ2V4dHJhY3ROb3Rlc0Zyb21DcmVhdG9yQ2VudGVyJyB9LFxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExpbWl0IG5vdGVzIGFycmF5IHRvIHNwZWNpZmllZCBjb3VudFxuICAgKi9cbiAgcHJpdmF0ZSBsaW1pdE5vdGVzKG5vdGVzOiBOb3RlRXh0cmFjdGlvbkRhdGFbXSwgbGltaXQ6IG51bWJlcik6IFVzZXJOb3RlW10ge1xuICAgIHJldHVybiBub3Rlcy5zbGljZSgwLCBsaW1pdCkubWFwKChub3RlKSA9PiAoe1xuICAgICAgaWQ6IG5vdGUuaWQsXG4gICAgICB0aXRsZTogbm90ZS50aXRsZSxcbiAgICAgIGNvbnRlbnQ6IG5vdGUuY29udGVudCxcbiAgICAgIGltYWdlczogT2JqZWN0LmZyZWV6ZShbLi4ubm90ZS5pbWFnZXNdKSxcbiAgICAgIHB1Ymxpc2hUaW1lOiBub3RlLnB1Ymxpc2hUaW1lLFxuICAgICAgdXBkYXRlVGltZTogbm90ZS51cGRhdGVUaW1lLFxuICAgICAgbGlrZUNvdW50OiBub3RlLmxpa2VDb3VudCxcbiAgICAgIGNvbW1lbnRDb3VudDogbm90ZS5jb21tZW50Q291bnQsXG4gICAgICBzaGFyZUNvdW50OiBub3RlLnNoYXJlQ291bnQsXG4gICAgICBjb2xsZWN0Q291bnQ6IG5vdGUuY29sbGVjdENvdW50LFxuICAgICAgdGFnczogT2JqZWN0LmZyZWV6ZShbLi4ubm90ZS50YWdzXSksXG4gICAgICB1cmw6IG5vdGUudXJsLFxuICAgICAgdmlzaWJpbGl0eTogbm90ZS52aXNpYmlsaXR5LFxuICAgICAgdmlzaWJpbGl0eVRleHQ6IG5vdGUudmlzaWJpbGl0eVRleHQsXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBuZXh0IGN1cnNvciBmb3IgcGFnaW5hdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBnZXROZXh0Q3Vyc29yKG5vdGVzOiBVc2VyTm90ZVtdKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gbm90ZXMubGVuZ3RoID4gMCA/IG5vdGVzW25vdGVzLmxlbmd0aCAtIDFdLmlkIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhIHNwZWNpZmljIG5vdGUgYnkgSURcbiAgICogQHBhcmFtIG5vdGVJZCAtIFRoZSBJRCBvZiB0aGUgbm90ZSB0byBkZWxldGVcbiAgICogQHBhcmFtIGJyb3dzZXJQYXRoIC0gT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgcGF0aFxuICAgKiBAcmV0dXJucyBQcm9taXNlPERlbGV0ZVJlc3VsdD4gLSBEZWxldGUgb3BlcmF0aW9uIHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlTm90ZShub3RlSWQ6IHN0cmluZywgYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPERlbGV0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLmRlbGV0ZVNlcnZpY2UuZGVsZXRlTm90ZShub3RlSWQsIGJyb3dzZXJQYXRoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGVcbiAgICogQHBhcmFtIGJyb3dzZXJQYXRoIC0gT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgcGF0aFxuICAgKiBAcmV0dXJucyBQcm9taXNlPERlbGV0ZVJlc3VsdD4gLSBEZWxldGUgb3BlcmF0aW9uIHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUoYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPERlbGV0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLmRlbGV0ZVNlcnZpY2UuZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUoYnJvd3NlclBhdGgpO1xuICB9XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7482\n\n}");
109
-
110
- /***/ }),
111
-
112
112
  /***/ 7598:
113
113
  /***/ ((module) => {
114
114
 
@@ -130,6 +130,13 @@ module.exports = require("util");
130
130
 
131
131
  /***/ }),
132
132
 
133
+ /***/ 9113:
134
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
135
+
136
+ eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n NoteService: () => (/* binding */ NoteService)\n});\n\n// EXTERNAL MODULE: ./src/shared/base.service.ts\nvar base_service = __webpack_require__(103);\n// EXTERNAL MODULE: ./src/shared/logger.ts\nvar logger = __webpack_require__(9135);\n// EXTERNAL MODULE: ./src/shared/errors.ts\nvar errors = __webpack_require__(7636);\n// EXTERNAL MODULE: ./src/shared/utils.ts\nvar utils = __webpack_require__(2094);\n;// ./src/shared/creator-center.ts\n/**\n * Shared helpers for Creator Center page operations\n */\n\n\nconst CREATOR_CENTER_URL = 'https://creator.xiaohongshu.com/new/note-manager?source=official';\nasync function navigateToCreatorCenter(page) {\n try {\n await page.goto(CREATOR_CENTER_URL, { waitUntil: 'load', timeout: 30000 });\n await (0,utils/* sleep */.yy)(3000);\n }\n catch (error) {\n throw new errors/* XHSError */.a_('Failed to navigate to creator center', 'CreatorCenterError', { url: CREATOR_CENTER_URL }, error instanceof Error ? error : new Error(String(error)));\n }\n}\nasync function verifyCreatorAuth(page, loginOkSelector) {\n try {\n const loginElements = await page.$$(loginOkSelector);\n const creatorElements = await page.$$('[class*=\"user\"], [class*=\"profile\"], [class*=\"avatar\"]');\n if (loginElements.length === 0 && creatorElements.length === 0) {\n const currentUrl = page.url();\n if (currentUrl.includes('login') || currentUrl.includes('signin')) {\n throw new errors/* NotLoggedInError */.bG('User not logged in', { url: currentUrl });\n }\n const noteElements = await page.$$('div.note');\n if (noteElements.length === 0) {\n throw new errors/* NotLoggedInError */.bG('User not logged in or no notes found', { url: currentUrl });\n }\n }\n }\n catch (error) {\n if (error instanceof errors/* NotLoggedInError */.bG) {\n throw error;\n }\n throw new errors/* XHSError */.a_('Failed to verify authentication', 'CreatorCenterError', { operation: 'verifyAuth' }, error instanceof Error ? error : new Error(String(error)));\n }\n}\n\n// EXTERNAL MODULE: ./src/shared/selectors.ts\nvar selectors = __webpack_require__(805);\n;// ./src/core/deleting/delete.service.ts\n/**\n * Delete service for XHS MCP Server\n * Handles note deletion operations\n */\n\n\n\n\n\n\n/**\n * CSS selectors for delete operations - updated for current XiaoHongShu interface\n */\nconst DELETE_SELECTORS = {\n NOTE_ITEM: [\n 'div.note',\n '.note-item',\n '[class*=\"note\"]',\n '[data-impression]',\n '.creator-note-item',\n '.note-card',\n '.content-item'\n ],\n DELETE_BUTTON: [\n '.control.data-del',\n 'span.control.data-del',\n ...selectors/* COMMON_BUTTON_SELECTORS */.ox.DELETE\n ],\n CONFIRM_BUTTON: selectors/* COMMON_BUTTON_SELECTORS */.ox.CONFIRM,\n CANCEL_BUTTON: selectors/* COMMON_BUTTON_SELECTORS */.ox.CANCEL,\n MORE_OPTIONS: selectors/* COMMON_BUTTON_SELECTORS */.ox.MORE_OPTIONS,\n DROPDOWN_MENU: selectors/* COMMON_MODAL_SELECTORS */.TK.DROPDOWN_MENU,\n MODAL_CONFIRM: selectors/* COMMON_MODAL_SELECTORS */.TK.CONFIRM,\n MODAL_CANCEL: selectors/* COMMON_MODAL_SELECTORS */.TK.CANCEL,\n};\nclass DeleteService extends base_service/* BaseService */.d {\n constructor(config, browserManager) {\n super(config, browserManager);\n }\n /**\n * Delete a specific note by ID\n * @param noteId - The ID of the note to delete\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteNote(noteId, browserPath) {\n this.validateDeleteParams(noteId);\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n // Navigate to creator center note manager\n await navigateToCreatorCenter(page);\n await verifyCreatorAuth(page, this.getConfig().xhs.loginOkSelector);\n // Find and delete the specific note\n const result = await this.findAndDeleteNote(page, noteId);\n return {\n success: true,\n data: null,\n noteId: result.noteId,\n title: result.title,\n deletedAt: Date.now(),\n message: `Successfully deleted note \"${result.title}\" (ID: ${result.noteId})`,\n operation: 'deleteNote',\n };\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to delete note ${noteId}: ${error}`);\n return {\n success: false,\n data: null,\n error: error instanceof Error ? error.message : String(error),\n message: `Failed to delete note: ${error instanceof Error ? error.message : String(error)}`,\n deletedAt: Date.now(),\n operation: 'deleteNote',\n };\n }\n finally {\n await page.close();\n }\n }\n /**\n * Delete the last published note\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteLastPublishedNote(browserPath) {\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n // Navigate to creator center note manager\n await navigateToCreatorCenter(page);\n await verifyCreatorAuth(page, this.getConfig().xhs.loginOkSelector);\n // Find and delete the last published note\n const result = await this.findAndDeleteLastNote(page);\n return {\n success: true,\n data: null,\n noteId: result.noteId,\n title: result.title,\n deletedAt: Date.now(),\n message: `Successfully deleted last published note \"${result.title}\" (ID: ${result.noteId})`,\n operation: 'deleteLastPublishedNote',\n };\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to delete last published note: ${error}`);\n return {\n success: false,\n data: null,\n error: error instanceof Error ? error.message : String(error),\n message: `Failed to delete last published note: ${error instanceof Error ? error.message : String(error)}`,\n deletedAt: Date.now(),\n operation: 'deleteLastPublishedNote',\n };\n }\n finally {\n await page.close();\n }\n }\n /**\n * Validate delete parameters\n */\n validateDeleteParams(noteId) {\n if (!noteId || noteId.trim().length === 0) {\n throw new errors/* DeleteError */.GU('Note ID is required', { noteId });\n }\n }\n /**\n * Find and delete a specific note by ID\n */\n async findAndDeleteNote(page, noteId) {\n try {\n // Step 1: Locate the note and try to find a direct delete button or more-options button\n const result = await page.evaluate((selectors, targetNoteId) => {\n let noteElements = [];\n for (const selector of selectors.NOTE_ITEM) {\n const elements = Array.from(document.querySelectorAll(selector));\n if (elements.length > 0) {\n noteElements = elements;\n break;\n }\n }\n if (noteElements.length === 0) {\n return { noteId: targetNoteId, title: '', found: false, error: 'No note elements found on page' };\n }\n for (const noteElement of noteElements) {\n const impressionData = noteElement.getAttribute('data-impression');\n let currentNoteId = '';\n if (impressionData) {\n try {\n const parsed = JSON.parse(impressionData);\n currentNoteId = parsed?.noteTarget?.value?.noteId || '';\n }\n catch {\n // Ignore parsing errors\n }\n }\n if (!currentNoteId) {\n const linkElement = noteElement.querySelector('a[href*=\"/explore/\"], a[href*=\"/note/\"]');\n if (linkElement) {\n const href = linkElement.getAttribute('href') || '';\n const match = href.match(/\\/explore\\/([a-zA-Z0-9]+)/);\n if (match) {\n currentNoteId = match[1];\n }\n }\n }\n if (currentNoteId === targetNoteId) {\n const titleElement = noteElement.querySelector('[class*=\"title\"], [class*=\"name\"]');\n const title = titleElement?.textContent?.trim() || 'Unknown';\n // Try to find a direct delete button first\n for (const selector of selectors.DELETE_BUTTON) {\n const deleteButton = noteElement.querySelector(selector);\n if (deleteButton) {\n deleteButton.click();\n return { noteId: currentNoteId, title, found: true, needsDropdown: false };\n }\n }\n // No direct delete button — check for a more-options button\n for (const selector of selectors.MORE_OPTIONS) {\n const moreButton = noteElement.querySelector(selector);\n if (moreButton) {\n moreButton.click();\n return { noteId: currentNoteId, title, found: true, needsDropdown: true };\n }\n }\n return { noteId: currentNoteId, title, found: false, error: 'Delete button not found' };\n }\n }\n return { noteId: targetNoteId, title: '', found: false, error: 'Note not found' };\n }, DELETE_SELECTORS, noteId);\n if (!result.found) {\n throw new errors/* DeleteError */.GU(result.error || 'Note not found', { noteId });\n }\n // Step 2: If we clicked \"more options\", wait for dropdown then click delete in it\n if (result.needsDropdown) {\n await (0,utils/* sleep */.yy)(1000);\n let clicked = false;\n for (const selector of DELETE_SELECTORS.DROPDOWN_MENU) {\n const dropdown = await page.$(selector);\n if (dropdown) {\n for (const deleteSelector of DELETE_SELECTORS.DELETE_BUTTON) {\n const deleteBtn = await dropdown.$(deleteSelector);\n if (deleteBtn) {\n await deleteBtn.click();\n clicked = true;\n break;\n }\n }\n if (clicked)\n break;\n }\n }\n if (!clicked) {\n throw new errors/* DeleteError */.GU('Delete button not found in dropdown menu', { noteId });\n }\n }\n await (0,utils/* sleep */.yy)(1000);\n await this.handleConfirmationDialog(page);\n return { noteId: result.noteId, title: result.title };\n }\n catch (error) {\n throw new errors/* DeleteError */.GU('Failed to find and delete note', { noteId }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Find and delete the last published note\n */\n async findAndDeleteLastNote(page) {\n try {\n const result = await page.evaluate((selectors) => {\n // Try each note item selector\n let noteElements = [];\n for (const selector of selectors.NOTE_ITEM) {\n const elements = Array.from(document.querySelectorAll(selector));\n if (elements.length > 0) {\n noteElements = elements;\n break;\n }\n }\n if (noteElements.length === 0) {\n return { noteId: '', title: '', found: false, error: 'No notes found' };\n }\n // Get the first note (most recent)\n const firstNote = noteElements[0];\n // Extract note ID\n let noteId = '';\n const impressionData = firstNote.getAttribute('data-impression');\n if (impressionData) {\n try {\n const parsed = JSON.parse(impressionData);\n noteId = parsed?.noteTarget?.value?.noteId || '';\n }\n catch (e) {\n // Ignore parsing errors\n }\n }\n // Also try to find note ID in link\n if (!noteId) {\n const linkElement = firstNote.querySelector('a[href*=\"/explore/\"], a[href*=\"/note/\"]');\n if (linkElement) {\n const href = linkElement.getAttribute('href') || '';\n const match = href.match(/\\/explore\\/([a-zA-Z0-9]+)/);\n if (match) {\n noteId = match[1];\n }\n }\n }\n // Extract title\n const titleElement = firstNote.querySelector('[class*=\"title\"], [class*=\"name\"]');\n const title = titleElement?.textContent?.trim() || 'Unknown';\n // Try to find a direct delete button first\n for (const selector of selectors.DELETE_BUTTON) {\n const deleteButton = firstNote.querySelector(selector);\n if (deleteButton) {\n deleteButton.click();\n return { noteId, title, found: true, needsDropdown: false };\n }\n }\n // No direct delete button — check for a more-options button\n for (const selector of selectors.MORE_OPTIONS) {\n const moreButton = firstNote.querySelector(selector);\n if (moreButton) {\n moreButton.click();\n return { noteId, title, found: true, needsDropdown: true };\n }\n }\n return { noteId, title, found: false, error: 'Delete button not found' };\n }, DELETE_SELECTORS);\n if (!result.found) {\n throw new errors/* DeleteError */.GU(result.error || 'Failed to find delete button', {});\n }\n // If we clicked \"more options\", wait for dropdown then click delete in it\n if (result.needsDropdown) {\n await (0,utils/* sleep */.yy)(1000);\n let clicked = false;\n for (const selector of DELETE_SELECTORS.DROPDOWN_MENU) {\n const dropdown = await page.$(selector);\n if (dropdown) {\n for (const deleteSelector of DELETE_SELECTORS.DELETE_BUTTON) {\n const deleteBtn = await dropdown.$(deleteSelector);\n if (deleteBtn) {\n await deleteBtn.click();\n clicked = true;\n break;\n }\n }\n if (clicked)\n break;\n }\n }\n if (!clicked) {\n throw new errors/* DeleteError */.GU('Delete button not found in dropdown menu', {});\n }\n }\n // Wait for confirmation dialog if it appears\n await (0,utils/* sleep */.yy)(1000);\n // Handle confirmation dialog\n await this.handleConfirmationDialog(page);\n return { noteId: result.noteId, title: result.title };\n }\n catch (error) {\n throw new errors/* DeleteError */.GU('Failed to find and delete last note', {}, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Handle confirmation dialog for delete operation\n */\n async handleConfirmationDialog(page) {\n try {\n // Wait for confirmation dialog to appear\n await (0,utils/* sleep */.yy)(2000);\n // Look for confirmation buttons using all possible selectors\n let confirmButton = null;\n // Try each confirm button selector\n for (const selector of DELETE_SELECTORS.CONFIRM_BUTTON) {\n confirmButton = await page.$(selector);\n if (confirmButton) {\n logger/* logger */.v.info(`Found confirm button with selector: ${selector}`);\n break;\n }\n }\n // If not found, try modal confirm selectors\n if (!confirmButton) {\n for (const selector of DELETE_SELECTORS.MODAL_CONFIRM) {\n confirmButton = await page.$(selector);\n if (confirmButton) {\n logger/* logger */.v.info(`Found modal confirm button with selector: ${selector}`);\n break;\n }\n }\n }\n if (confirmButton) {\n logger/* logger */.v.info('Clicking confirmation button');\n await confirmButton.click();\n await (0,utils/* sleep */.yy)(2000);\n }\n else {\n // If no confirmation dialog, the delete might have been immediate\n logger/* logger */.v.info('No confirmation dialog found, delete might be immediate');\n }\n }\n catch (error) {\n logger/* logger */.v.warn(`Failed to handle confirmation dialog: ${error}`);\n // Continue anyway as the delete might still work\n }\n }\n}\n\n;// ./src/core/notes/note.service.ts\n/**\n * Note service for XHS MCP Server\n * Handles user notes/feeds operations\n */\n\n\n\n\n\n/**\n * CSS selectors for note extraction from Creator Center\n */\nconst NOTE_SELECTORS = {\n NOTE_ELEMENTS: 'div.note',\n TITLE_ELEMENTS: '[class*=\"raw\"], [class*=\"title\"], [class*=\"name\"]',\n IMAGE_ELEMENTS: 'img[class*=\"media\"], img[class*=\"cover\"], img[class*=\"thumbnail\"]',\n STAT_ELEMENTS: '[class*=\"count\"], [class*=\"stat\"], [class*=\"number\"]',\n TAG_ELEMENTS: '[class*=\"tag\"], [class*=\"label\"]',\n NOTE_LINK: 'a[href*=\"/explore/\"], a[href*=\"/note/\"]',\n VISIBILITY_INDICATORS: '[class*=\"private\"], [class*=\"visibility\"], [class*=\"lock\"], [class*=\"eye\"], [class*=\"public\"], [class*=\"friends\"], [class*=\"status\"]',\n PUBLISH_TIME: '[class*=\"time\"], [class*=\"date\"], [class*=\"publish-time\"]',\n};\nclass NoteService extends base_service/* BaseService */.d {\n deleteService;\n constructor(config, browserManager) {\n super(config, browserManager);\n this.deleteService = new DeleteService(config, this.browserManager);\n }\n /**\n * Get current user's published notes from creator center\n * @param limit - Maximum number of notes to return (default: 20)\n * @param cursor - Pagination cursor for next page\n * @param browserPath - Optional custom browser path\n * @returns Promise<UserNotesResult> - User notes with pagination info\n */\n async getUserNotes(limit = 20, cursor, browserPath) {\n this.validateGetUserNotesParams(limit);\n const page = await this.getBrowserManager().createPage(true, browserPath, true);\n try {\n // Navigate to creator center note manager\n await navigateToCreatorCenter(page);\n await verifyCreatorAuth(page, this.getConfig().xhs.loginOkSelector);\n // Extract notes from creator center\n const notesData = await this.extractNotesFromCreatorCenter(page);\n const limitedNotes = this.limitNotes(notesData, limit);\n return {\n success: true,\n data: limitedNotes,\n total: notesData.length,\n hasMore: notesData.length > limit,\n nextCursor: this.getNextCursor(limitedNotes),\n operation: 'getUserNotes',\n };\n }\n catch (error) {\n logger/* logger */.v.error(`Failed to get user notes: ${error}`);\n return {\n success: false,\n data: [],\n total: 0,\n hasMore: false,\n error: error instanceof Error ? error.message : String(error),\n operation: 'getUserNotes',\n };\n }\n finally {\n await page.close();\n }\n }\n /**\n * Validate parameters for getUserNotes method\n */\n validateGetUserNotesParams(limit) {\n if (limit <= 0) {\n throw new errors/* NoteParsingError */.Vb('Limit must be greater than 0', { limit });\n }\n if (limit > 100) {\n throw new errors/* NoteParsingError */.Vb('Limit cannot exceed 100', { limit });\n }\n }\n /**\n * Extract notes from creator center page\n */\n async extractNotesFromCreatorCenter(page) {\n try {\n const notesData = await page.evaluate((selectors) => {\n const notes = [];\n // Find note elements using the creator center selector\n const noteElements = Array.from(document.querySelectorAll(selectors.NOTE_ELEMENTS));\n noteElements.forEach((element) => {\n try {\n // Extract note data from element\n const publishTime = Date.now();\n const note = {\n id: '',\n title: '',\n content: '',\n images: [],\n publishTime,\n updateTime: publishTime,\n likeCount: 0,\n commentCount: 0,\n shareCount: 0,\n collectCount: 0,\n tags: [],\n url: '',\n visibility: 'unknown',\n visibilityText: '',\n };\n // Extract note ID from data attributes or impression data\n const impressionData = element.getAttribute('data-impression');\n if (impressionData) {\n try {\n const parsed = JSON.parse(impressionData);\n const noteId = parsed?.noteTarget?.value?.noteId;\n if (noteId) {\n note.id = noteId;\n note.url = `https://www.xiaohongshu.com/explore/${noteId}`;\n }\n }\n catch (e) {\n // Ignore parsing errors\n }\n }\n // Extract title/content\n const titleElement = element.querySelector(selectors.TITLE_ELEMENTS);\n if (titleElement) {\n const title = titleElement.textContent?.trim() ?? '';\n note.title = title;\n note.content = title;\n }\n // Extract images - try multiple approaches for creator center\n const imageSelectors = [\n selectors.IMAGE_ELEMENTS,\n 'img', // Try all img elements\n '[class*=\"image\"]',\n '[class*=\"photo\"]',\n '[class*=\"pic\"]',\n '[class*=\"img\"]',\n '[style*=\"background-image\"]', // Background images\n 'div[class*=\"cover\"] img',\n 'div[class*=\"thumbnail\"] img',\n 'div[class*=\"media\"] img',\n ];\n let imageElements = [];\n for (const selector of imageSelectors) {\n const elements = element.querySelectorAll(selector);\n if (elements.length > 0) {\n imageElements = Array.from(elements);\n break;\n }\n }\n imageElements.forEach((img) => {\n let src = '';\n // Try different ways to get image source\n const htmlImg = img;\n if (htmlImg.src) {\n src = htmlImg.src;\n }\n else if (htmlImg.style && htmlImg.style.backgroundImage) {\n // Extract from background-image CSS\n const bgMatch = htmlImg.style.backgroundImage.match(/url\\(['\"]?([^'\"]+)['\"]?\\)/);\n if (bgMatch) {\n src = bgMatch[1];\n }\n }\n else if (img.getAttribute('data-src')) {\n // Lazy loaded images\n src = img.getAttribute('data-src') || '';\n }\n else if (img.getAttribute('data-original')) {\n // Another lazy loading attribute\n src = img.getAttribute('data-original') || '';\n }\n if (src &&\n !src.includes('avatar') &&\n !src.includes('icon') &&\n !src.includes('logo') &&\n !src.includes('placeholder') &&\n src.startsWith('http')) {\n note.images.push(src);\n }\n });\n // Extract stats - look for numbers in the element\n const allText = element.textContent || '';\n const numbers = allText.match(/\\d+/g) || [];\n // Try to extract stats from text content\n if (numbers.length >= 4) {\n // Assuming order: like, comment, share, collect, view\n note.likeCount = parseInt(numbers[0] || '0') || 0;\n note.commentCount = parseInt(numbers[1]) || 0;\n note.shareCount = parseInt(numbers[2]) || 0;\n note.collectCount = parseInt(numbers[3]) || 0;\n }\n // Extract publish time\n const timeElement = element.querySelector(selectors.PUBLISH_TIME);\n if (timeElement) {\n const timeText = timeElement.textContent?.trim() || '';\n if (timeText.includes('发布于')) {\n // Parse Chinese date format\n const dateMatch = timeText.match(/(\\d{4})年(\\d{1,2})月(\\d{1,2})日\\s+(\\d{1,2}):(\\d{2})/);\n if (dateMatch) {\n const [, year, month, day, hour, minute] = dateMatch;\n const publishDate = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute));\n note.publishTime = publishDate.getTime();\n note.updateTime = publishDate.getTime();\n }\n }\n }\n // Extract visibility information\n const elementText = element.textContent?.toLowerCase() || '';\n if (elementText.includes('仅自己可见')) {\n note.visibility = 'private';\n note.visibilityText = '仅自己可见';\n }\n else if (elementText.includes('朋友可见')) {\n note.visibility = 'friends';\n note.visibilityText = '朋友可见';\n }\n else if (elementText.includes('公开')) {\n note.visibility = 'public';\n note.visibilityText = '公开';\n }\n else {\n // Default to public for notes without explicit visibility indicators\n note.visibility = 'public';\n note.visibilityText = '公开';\n }\n // Extract tags\n const tagElements = element.querySelectorAll(selectors.TAG_ELEMENTS);\n tagElements.forEach((tag) => {\n const tagText = tag.textContent?.trim();\n if (tagText?.startsWith('#')) {\n note.tags.push(tagText);\n }\n });\n if (note.id) {\n notes.push(note);\n }\n }\n catch (error) {\n // Ignore extraction errors for individual notes\n }\n });\n return notes;\n }, NOTE_SELECTORS);\n return notesData;\n }\n catch (error) {\n throw new errors/* NoteParsingError */.Vb('Failed to extract notes from creator center', { operation: 'extractNotesFromCreatorCenter' }, error instanceof Error ? error : new Error(String(error)));\n }\n }\n /**\n * Limit notes array to specified count\n */\n limitNotes(notes, limit) {\n return notes.slice(0, limit).map((note) => ({\n id: note.id,\n title: note.title,\n content: note.content,\n images: Object.freeze([...note.images]),\n publishTime: note.publishTime,\n updateTime: note.updateTime,\n likeCount: note.likeCount,\n commentCount: note.commentCount,\n shareCount: note.shareCount,\n collectCount: note.collectCount,\n tags: Object.freeze([...note.tags]),\n url: note.url,\n visibility: note.visibility,\n visibilityText: note.visibilityText,\n }));\n }\n /**\n * Get next cursor for pagination\n */\n getNextCursor(notes) {\n return notes.length > 0 ? notes[notes.length - 1].id : undefined;\n }\n /**\n * Delete a specific note by ID\n * @param noteId - The ID of the note to delete\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteNote(noteId, browserPath) {\n return this.deleteService.deleteNote(noteId, browserPath);\n }\n /**\n * Delete the last published note\n * @param browserPath - Optional custom browser path\n * @returns Promise<DeleteResult> - Delete operation result\n */\n async deleteLastPublishedNote(browserPath) {\n return this.deleteService.deleteLastPublishedNote(browserPath);\n }\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNuRSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQWMsRUFBRSxXQUFvQjtRQUNuRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxXQUFvQjtRQUNoRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsdUJBQXVCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDakUsQ0FBQztDQUNGIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8veGhzLW1jcC8uL3NyYy9zaGFyZWQvY3JlYXRvci1jZW50ZXIudHM/MWQ4NCIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvZGVsZXRpbmcvZGVsZXRlLnNlcnZpY2UudHM/MDMwOSIsIndlYnBhY2s6Ly94aHMtbWNwLy4vc3JjL2NvcmUvbm90ZXMvbm90ZS5zZXJ2aWNlLnRzPzFiNjYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTaGFyZWQgaGVscGVycyBmb3IgQ3JlYXRvciBDZW50ZXIgcGFnZSBvcGVyYXRpb25zXG4gKi9cblxuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBOb3RMb2dnZWRJbkVycm9yLCBYSFNFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi91dGlscyc7XG5cbmV4cG9ydCBjb25zdCBDUkVBVE9SX0NFTlRFUl9VUkwgPVxuICAnaHR0cHM6Ly9jcmVhdG9yLnhpYW9ob25nc2h1LmNvbS9uZXcvbm90ZS1tYW5hZ2VyP3NvdXJjZT1vZmZpY2lhbCc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBuYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlOiBQYWdlKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgcGFnZS5nb3RvKENSRUFUT1JfQ0VOVEVSX1VSTCwgeyB3YWl0VW50aWw6ICdsb2FkJywgdGltZW91dDogMzAwMDAgfSk7XG4gICAgYXdhaXQgc2xlZXAoMzAwMCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IFhIU0Vycm9yKFxuICAgICAgJ0ZhaWxlZCB0byBuYXZpZ2F0ZSB0byBjcmVhdG9yIGNlbnRlcicsXG4gICAgICAnQ3JlYXRvckNlbnRlckVycm9yJyxcbiAgICAgIHsgdXJsOiBDUkVBVE9SX0NFTlRFUl9VUkwgfSxcbiAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZlcmlmeUNyZWF0b3JBdXRoKHBhZ2U6IFBhZ2UsIGxvZ2luT2tTZWxlY3Rvcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgbG9naW5FbGVtZW50cyA9IGF3YWl0IHBhZ2UuJCQobG9naW5Pa1NlbGVjdG9yKTtcbiAgICBjb25zdCBjcmVhdG9yRWxlbWVudHMgPSBhd2FpdCBwYWdlLiQkKCdbY2xhc3MqPVwidXNlclwiXSwgW2NsYXNzKj1cInByb2ZpbGVcIl0sIFtjbGFzcyo9XCJhdmF0YXJcIl0nKTtcblxuICAgIGlmIChsb2dpbkVsZW1lbnRzLmxlbmd0aCA9PT0gMCAmJiBjcmVhdG9yRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zdCBjdXJyZW50VXJsID0gcGFnZS51cmwoKTtcbiAgICAgIGlmIChjdXJyZW50VXJsLmluY2x1ZGVzKCdsb2dpbicpIHx8IGN1cnJlbnRVcmwuaW5jbHVkZXMoJ3NpZ25pbicpKSB7XG4gICAgICAgIHRocm93IG5ldyBOb3RMb2dnZWRJbkVycm9yKCdVc2VyIG5vdCBsb2dnZWQgaW4nLCB7IHVybDogY3VycmVudFVybCB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm90ZUVsZW1lbnRzID0gYXdhaXQgcGFnZS4kJCgnZGl2Lm5vdGUnKTtcbiAgICAgIGlmIChub3RlRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBOb3RMb2dnZWRJbkVycm9yKCdVc2VyIG5vdCBsb2dnZWQgaW4gb3Igbm8gbm90ZXMgZm91bmQnLCB7IHVybDogY3VycmVudFVybCB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm90TG9nZ2VkSW5FcnJvcikge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIHRocm93IG5ldyBYSFNFcnJvcihcbiAgICAgICdGYWlsZWQgdG8gdmVyaWZ5IGF1dGhlbnRpY2F0aW9uJyxcbiAgICAgICdDcmVhdG9yQ2VudGVyRXJyb3InLFxuICAgICAgeyBvcGVyYXRpb246ICd2ZXJpZnlBdXRoJyB9LFxuICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgKTtcbiAgfVxufVxuIiwiLyoqXG4gKiBEZWxldGUgc2VydmljZSBmb3IgWEhTIE1DUCBTZXJ2ZXJcbiAqIEhhbmRsZXMgbm90ZSBkZWxldGlvbiBvcGVyYXRpb25zXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBDb25maWcsIFhIU1Jlc3BvbnNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IEJhc2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBCcm93c2VyTWFuYWdlciB9IGZyb20gJy4uL2Jyb3dzZXIvYnJvd3Nlci5tYW5hZ2VyJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9sb2dnZXInO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMnO1xuaW1wb3J0IHsgRGVsZXRlRXJyb3IgfSBmcm9tICcuLi8uLi9zaGFyZWQvZXJyb3JzJztcbmltcG9ydCB7IG5hdmlnYXRlVG9DcmVhdG9yQ2VudGVyLCB2ZXJpZnlDcmVhdG9yQXV0aCB9IGZyb20gJy4uLy4uL3NoYXJlZC9jcmVhdG9yLWNlbnRlcic7XG5pbXBvcnQgeyBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IENPTU1PTl9CVVRUT05fU0VMRUNUT1JTLCBDT01NT05fTU9EQUxfU0VMRUNUT1JTIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3NlbGVjdG9ycyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVsZXRlUmVzdWx0IGV4dGVuZHMgWEhTUmVzcG9uc2U8bnVsbD4ge1xuICByZWFkb25seSBub3RlSWQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRpdGxlPzogc3RyaW5nO1xuICByZWFkb25seSBkZWxldGVkQXQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZWxldGVPcHRpb25zIHtcbiAgbm90ZUlkPzogc3RyaW5nO1xuICBsYXN0UHVibGlzaGVkPzogYm9vbGVhbjtcbiAgYnJvd3NlclBhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ1NTIHNlbGVjdG9ycyBmb3IgZGVsZXRlIG9wZXJhdGlvbnMgLSB1cGRhdGVkIGZvciBjdXJyZW50IFhpYW9Ib25nU2h1IGludGVyZmFjZVxuICovXG5jb25zdCBERUxFVEVfU0VMRUNUT1JTID0ge1xuICBOT1RFX0lURU06IFtcbiAgICAnZGl2Lm5vdGUnLFxuICAgICcubm90ZS1pdGVtJyxcbiAgICAnW2NsYXNzKj1cIm5vdGVcIl0nLFxuICAgICdbZGF0YS1pbXByZXNzaW9uXScsXG4gICAgJy5jcmVhdG9yLW5vdGUtaXRlbScsXG4gICAgJy5ub3RlLWNhcmQnLFxuICAgICcuY29udGVudC1pdGVtJ1xuICBdLFxuICBERUxFVEVfQlVUVE9OOiBbXG4gICAgJy5jb250cm9sLmRhdGEtZGVsJyxcbiAgICAnc3Bhbi5jb250cm9sLmRhdGEtZGVsJyxcbiAgICAuLi5DT01NT05fQlVUVE9OX1NFTEVDVE9SUy5ERUxFVEVcbiAgXSxcbiAgQ09ORklSTV9CVVRUT046IENPTU1PTl9CVVRUT05fU0VMRUNUT1JTLkNPTkZJUk0sXG4gIENBTkNFTF9CVVRUT046IENPTU1PTl9CVVRUT05fU0VMRUNUT1JTLkNBTkNFTCxcbiAgTU9SRV9PUFRJT05TOiBDT01NT05fQlVUVE9OX1NFTEVDVE9SUy5NT1JFX09QVElPTlMsXG4gIERST1BET1dOX01FTlU6IENPTU1PTl9NT0RBTF9TRUxFQ1RPUlMuRFJPUERPV05fTUVOVSxcbiAgTU9EQUxfQ09ORklSTTogQ09NTU9OX01PREFMX1NFTEVDVE9SUy5DT05GSVJNLFxuICBNT0RBTF9DQU5DRUw6IENPTU1PTl9NT0RBTF9TRUxFQ1RPUlMuQ0FOQ0VMLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IGNsYXNzIERlbGV0ZVNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogQ29uZmlnLCBicm93c2VyTWFuYWdlcj86IEJyb3dzZXJNYW5hZ2VyKSB7XG4gICAgc3VwZXIoY29uZmlnLCBicm93c2VyTWFuYWdlcik7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGEgc3BlY2lmaWMgbm90ZSBieSBJRFxuICAgKiBAcGFyYW0gbm90ZUlkIC0gVGhlIElEIG9mIHRoZSBub3RlIHRvIGRlbGV0ZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8RGVsZXRlUmVzdWx0PiAtIERlbGV0ZSBvcGVyYXRpb24gcmVzdWx0XG4gICAqL1xuICBhc3luYyBkZWxldGVOb3RlKG5vdGVJZDogc3RyaW5nLCBicm93c2VyUGF0aD86IHN0cmluZyk6IFByb21pc2U8RGVsZXRlUmVzdWx0PiB7XG4gICAgdGhpcy52YWxpZGF0ZURlbGV0ZVBhcmFtcyhub3RlSWQpO1xuXG4gICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZ2V0QnJvd3Nlck1hbmFnZXIoKS5jcmVhdGVQYWdlKHRydWUsIGJyb3dzZXJQYXRoLCB0cnVlKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBOYXZpZ2F0ZSB0byBjcmVhdG9yIGNlbnRlciBub3RlIG1hbmFnZXJcbiAgICAgIGF3YWl0IG5hdmlnYXRlVG9DcmVhdG9yQ2VudGVyKHBhZ2UpO1xuICAgICAgYXdhaXQgdmVyaWZ5Q3JlYXRvckF1dGgocGFnZSwgdGhpcy5nZXRDb25maWcoKS54aHMubG9naW5Pa1NlbGVjdG9yKTtcblxuICAgICAgLy8gRmluZCBhbmQgZGVsZXRlIHRoZSBzcGVjaWZpYyBub3RlXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmZpbmRBbmREZWxldGVOb3RlKHBhZ2UsIG5vdGVJZCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGRhdGE6IG51bGwsXG4gICAgICAgIG5vdGVJZDogcmVzdWx0Lm5vdGVJZCxcbiAgICAgICAgdGl0bGU6IHJlc3VsdC50aXRsZSxcbiAgICAgICAgZGVsZXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICBtZXNzYWdlOiBgU3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgbm90ZSBcIiR7cmVzdWx0LnRpdGxlfVwiIChJRDogJHtyZXN1bHQubm90ZUlkfSlgLFxuICAgICAgICBvcGVyYXRpb246ICdkZWxldGVOb3RlJyxcbiAgICAgIH0gYXMgdW5rbm93biBhcyBEZWxldGVSZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBub3RlICR7bm90ZUlkfTogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBkYXRhOiBudWxsLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICBtZXNzYWdlOiBgRmFpbGVkIHRvIGRlbGV0ZSBub3RlOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gLFxuICAgICAgICBkZWxldGVkQXQ6IERhdGUubm93KCksXG4gICAgICAgIG9wZXJhdGlvbjogJ2RlbGV0ZU5vdGUnLFxuICAgICAgfSBhcyB1bmtub3duIGFzIERlbGV0ZVJlc3VsdDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGVcbiAgICogQHBhcmFtIGJyb3dzZXJQYXRoIC0gT3B0aW9uYWwgY3VzdG9tIGJyb3dzZXIgcGF0aFxuICAgKiBAcmV0dXJucyBQcm9taXNlPERlbGV0ZVJlc3VsdD4gLSBEZWxldGUgb3BlcmF0aW9uIHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgZGVsZXRlTGFzdFB1Ymxpc2hlZE5vdGUoYnJvd3NlclBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPERlbGV0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJNYW5hZ2VyKCkuY3JlYXRlUGFnZSh0cnVlLCBicm93c2VyUGF0aCwgdHJ1ZSk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gTmF2aWdhdGUgdG8gY3JlYXRvciBjZW50ZXIgbm90ZSBtYW5hZ2VyXG4gICAgICBhd2FpdCBuYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlcihwYWdlKTtcbiAgICAgIGF3YWl0IHZlcmlmeUNyZWF0b3JBdXRoKHBhZ2UsIHRoaXMuZ2V0Q29uZmlnKCkueGhzLmxvZ2luT2tTZWxlY3Rvcik7XG5cbiAgICAgIC8vIEZpbmQgYW5kIGRlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZVxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5maW5kQW5kRGVsZXRlTGFzdE5vdGUocGFnZSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGRhdGE6IG51bGwsXG4gICAgICAgIG5vdGVJZDogcmVzdWx0Lm5vdGVJZCxcbiAgICAgICAgdGl0bGU6IHJlc3VsdC50aXRsZSxcbiAgICAgICAgZGVsZXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICBtZXNzYWdlOiBgU3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgbGFzdCBwdWJsaXNoZWQgbm90ZSBcIiR7cmVzdWx0LnRpdGxlfVwiIChJRDogJHtyZXN1bHQubm90ZUlkfSlgLFxuICAgICAgICBvcGVyYXRpb246ICdkZWxldGVMYXN0UHVibGlzaGVkTm90ZScsXG4gICAgICB9IGFzIHVua25vd24gYXMgRGVsZXRlUmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBkZWxldGUgbGFzdCBwdWJsaXNoZWQgbm90ZTogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBkYXRhOiBudWxsLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICBtZXNzYWdlOiBgRmFpbGVkIHRvIGRlbGV0ZSBsYXN0IHB1Ymxpc2hlZCBub3RlOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gLFxuICAgICAgICBkZWxldGVkQXQ6IERhdGUubm93KCksXG4gICAgICAgIG9wZXJhdGlvbjogJ2RlbGV0ZUxhc3RQdWJsaXNoZWROb3RlJyxcbiAgICAgIH0gYXMgdW5rbm93biBhcyBEZWxldGVSZXN1bHQ7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHBhZ2UuY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgZGVsZXRlIHBhcmFtZXRlcnNcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVEZWxldGVQYXJhbXMobm90ZUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIW5vdGVJZCB8fCBub3RlSWQudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKCdOb3RlIElEIGlzIHJlcXVpcmVkJywgeyBub3RlSWQgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgYW5kIGRlbGV0ZSBhIHNwZWNpZmljIG5vdGUgYnkgSURcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmluZEFuZERlbGV0ZU5vdGUocGFnZTogUGFnZSwgbm90ZUlkOiBzdHJpbmcpOiBQcm9taXNlPHsgbm90ZUlkOiBzdHJpbmc7IHRpdGxlOiBzdHJpbmcgfT4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBTdGVwIDE6IExvY2F0ZSB0aGUgbm90ZSBhbmQgdHJ5IHRvIGZpbmQgYSBkaXJlY3QgZGVsZXRlIGJ1dHRvbiBvciBtb3JlLW9wdGlvbnMgYnV0dG9uXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKFxuICAgICAgICAoc2VsZWN0b3JzOiB0eXBlb2YgREVMRVRFX1NFTEVDVE9SUywgdGFyZ2V0Tm90ZUlkOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICBsZXQgbm90ZUVsZW1lbnRzOiBFbGVtZW50W10gPSBbXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycy5OT1RFX0lURU0pIHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG4gICAgICAgICAgICBpZiAoZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBub3RlRWxlbWVudHMgPSBlbGVtZW50cztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5vdGVFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogdGFyZ2V0Tm90ZUlkLCB0aXRsZTogJycsIGZvdW5kOiBmYWxzZSwgZXJyb3I6ICdObyBub3RlIGVsZW1lbnRzIGZvdW5kIG9uIHBhZ2UnIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChjb25zdCBub3RlRWxlbWVudCBvZiBub3RlRWxlbWVudHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGltcHJlc3Npb25EYXRhID0gbm90ZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWltcHJlc3Npb24nKTtcbiAgICAgICAgICAgIGxldCBjdXJyZW50Tm90ZUlkID0gJyc7XG5cbiAgICAgICAgICAgIGlmIChpbXByZXNzaW9uRGF0YSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoaW1wcmVzc2lvbkRhdGEpO1xuICAgICAgICAgICAgICAgIGN1cnJlbnROb3RlSWQgPSBwYXJzZWQ/Lm5vdGVUYXJnZXQ/LnZhbHVlPy5ub3RlSWQgfHwgJyc7XG4gICAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgIC8vIElnbm9yZSBwYXJzaW5nIGVycm9yc1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghY3VycmVudE5vdGVJZCkge1xuICAgICAgICAgICAgICBjb25zdCBsaW5rRWxlbWVudCA9IG5vdGVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ2FbaHJlZio9XCIvZXhwbG9yZS9cIl0sIGFbaHJlZio9XCIvbm90ZS9cIl0nKTtcbiAgICAgICAgICAgICAgaWYgKGxpbmtFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHJlZiA9IGxpbmtFbGVtZW50LmdldEF0dHJpYnV0ZSgnaHJlZicpIHx8ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gaHJlZi5tYXRjaCgvXFwvZXhwbG9yZVxcLyhbYS16QS1aMC05XSspLyk7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICBjdXJyZW50Tm90ZUlkID0gbWF0Y2hbMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50Tm90ZUlkID09PSB0YXJnZXROb3RlSWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGl0bGVFbGVtZW50ID0gbm90ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignW2NsYXNzKj1cInRpdGxlXCJdLCBbY2xhc3MqPVwibmFtZVwiXScpO1xuICAgICAgICAgICAgICBjb25zdCB0aXRsZSA9IHRpdGxlRWxlbWVudD8udGV4dENvbnRlbnQ/LnRyaW0oKSB8fCAnVW5rbm93bic7XG5cbiAgICAgICAgICAgICAgLy8gVHJ5IHRvIGZpbmQgYSBkaXJlY3QgZGVsZXRlIGJ1dHRvbiBmaXJzdFxuICAgICAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycy5ERUxFVEVfQlVUVE9OKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVsZXRlQnV0dG9uID0gbm90ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgaWYgKGRlbGV0ZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgKGRlbGV0ZUJ1dHRvbiBhcyBIVE1MRWxlbWVudCkuY2xpY2soKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogY3VycmVudE5vdGVJZCwgdGl0bGUsIGZvdW5kOiB0cnVlLCBuZWVkc0Ryb3Bkb3duOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIE5vIGRpcmVjdCBkZWxldGUgYnV0dG9uIOKAlCBjaGVjayBmb3IgYSBtb3JlLW9wdGlvbnMgYnV0dG9uXG4gICAgICAgICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygc2VsZWN0b3JzLk1PUkVfT1BUSU9OUykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1vcmVCdXR0b24gPSBub3RlRWxlbWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgICBpZiAobW9yZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgICAgKG1vcmVCdXR0b24gYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4geyBub3RlSWQ6IGN1cnJlbnROb3RlSWQsIHRpdGxlLCBmb3VuZDogdHJ1ZSwgbmVlZHNEcm9wZG93bjogdHJ1ZSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHJldHVybiB7IG5vdGVJZDogY3VycmVudE5vdGVJZCwgdGl0bGUsIGZvdW5kOiBmYWxzZSwgZXJyb3I6ICdEZWxldGUgYnV0dG9uIG5vdCBmb3VuZCcgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4geyBub3RlSWQ6IHRhcmdldE5vdGVJZCwgdGl0bGU6ICcnLCBmb3VuZDogZmFsc2UsIGVycm9yOiAnTm90ZSBub3QgZm91bmQnIH07XG4gICAgICAgIH0sXG4gICAgICAgIERFTEVURV9TRUxFQ1RPUlMsXG4gICAgICAgIG5vdGVJZFxuICAgICAgKTtcblxuICAgICAgaWYgKCFyZXN1bHQuZm91bmQpIHtcbiAgICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKHJlc3VsdC5lcnJvciB8fCAnTm90ZSBub3QgZm91bmQnLCB7IG5vdGVJZCB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gU3RlcCAyOiBJZiB3ZSBjbGlja2VkIFwibW9yZSBvcHRpb25zXCIsIHdhaXQgZm9yIGRyb3Bkb3duIHRoZW4gY2xpY2sgZGVsZXRlIGluIGl0XG4gICAgICBpZiAocmVzdWx0Lm5lZWRzRHJvcGRvd24pIHtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG4gICAgICAgIGxldCBjbGlja2VkID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgREVMRVRFX1NFTEVDVE9SUy5EUk9QRE9XTl9NRU5VKSB7XG4gICAgICAgICAgY29uc3QgZHJvcGRvd24gPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICAgIGlmIChkcm9wZG93bikge1xuICAgICAgICAgICAgZm9yIChjb25zdCBkZWxldGVTZWxlY3RvciBvZiBERUxFVEVfU0VMRUNUT1JTLkRFTEVURV9CVVRUT04pIHtcbiAgICAgICAgICAgICAgY29uc3QgZGVsZXRlQnRuID0gYXdhaXQgZHJvcGRvd24uJChkZWxldGVTZWxlY3Rvcik7XG4gICAgICAgICAgICAgIGlmIChkZWxldGVCdG4pIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBkZWxldGVCdG4uY2xpY2soKTtcbiAgICAgICAgICAgICAgICBjbGlja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNsaWNrZWQpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNsaWNrZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IoJ0RlbGV0ZSBidXR0b24gbm90IGZvdW5kIGluIGRyb3Bkb3duIG1lbnUnLCB7IG5vdGVJZCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ29uZmlybWF0aW9uRGlhbG9nKHBhZ2UpO1xuXG4gICAgICByZXR1cm4geyBub3RlSWQ6IHJlc3VsdC5ub3RlSWQsIHRpdGxlOiByZXN1bHQudGl0bGUgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIGZpbmQgYW5kIGRlbGV0ZSBub3RlJyxcbiAgICAgICAgeyBub3RlSWQgfSxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIGFuZCBkZWxldGUgdGhlIGxhc3QgcHVibGlzaGVkIG5vdGVcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmluZEFuZERlbGV0ZUxhc3ROb3RlKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPHsgbm90ZUlkOiBzdHJpbmc7IHRpdGxlOiBzdHJpbmcgfT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChzZWxlY3RvcnM6IHR5cGVvZiBERUxFVEVfU0VMRUNUT1JTKSA9PiB7XG5cbiAgICAgICAgLy8gVHJ5IGVhY2ggbm90ZSBpdGVtIHNlbGVjdG9yXG4gICAgICAgIGxldCBub3RlRWxlbWVudHM6IEVsZW1lbnRbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIHNlbGVjdG9ycy5OT1RFX0lURU0pIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikpO1xuICAgICAgICAgIGlmIChlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBub3RlRWxlbWVudHMgPSBlbGVtZW50cztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChub3RlRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHsgbm90ZUlkOiAnJywgdGl0bGU6ICcnLCBmb3VuZDogZmFsc2UsIGVycm9yOiAnTm8gbm90ZXMgZm91bmQnIH07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIGZpcnN0IG5vdGUgKG1vc3QgcmVjZW50KVxuICAgICAgICBjb25zdCBmaXJzdE5vdGUgPSBub3RlRWxlbWVudHNbMF07XG5cbiAgICAgICAgLy8gRXh0cmFjdCBub3RlIElEXG4gICAgICAgIGxldCBub3RlSWQgPSAnJztcbiAgICAgICAgY29uc3QgaW1wcmVzc2lvbkRhdGEgPSBmaXJzdE5vdGUuZ2V0QXR0cmlidXRlKCdkYXRhLWltcHJlc3Npb24nKTtcblxuICAgICAgICBpZiAoaW1wcmVzc2lvbkRhdGEpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShpbXByZXNzaW9uRGF0YSk7XG4gICAgICAgICAgICBub3RlSWQgPSBwYXJzZWQ/Lm5vdGVUYXJnZXQ/LnZhbHVlPy5ub3RlSWQgfHwgJyc7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gSWdub3JlIHBhcnNpbmcgZXJyb3JzXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWxzbyB0cnkgdG8gZmluZCBub3RlIElEIGluIGxpbmtcbiAgICAgICAgaWYgKCFub3RlSWQpIHtcbiAgICAgICAgICBjb25zdCBsaW5rRWxlbWVudCA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKCdhW2hyZWYqPVwiL2V4cGxvcmUvXCJdLCBhW2hyZWYqPVwiL25vdGUvXCJdJyk7XG4gICAgICAgICAgaWYgKGxpbmtFbGVtZW50KSB7XG4gICAgICAgICAgICBjb25zdCBocmVmID0gbGlua0VsZW1lbnQuZ2V0QXR0cmlidXRlKCdocmVmJykgfHwgJyc7XG4gICAgICAgICAgICBjb25zdCBtYXRjaCA9IGhyZWYubWF0Y2goL1xcL2V4cGxvcmVcXC8oW2EtekEtWjAtOV0rKS8pO1xuICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgIG5vdGVJZCA9IG1hdGNoWzFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEV4dHJhY3QgdGl0bGVcbiAgICAgICAgY29uc3QgdGl0bGVFbGVtZW50ID0gZmlyc3ROb3RlLnF1ZXJ5U2VsZWN0b3IoJ1tjbGFzcyo9XCJ0aXRsZVwiXSwgW2NsYXNzKj1cIm5hbWVcIl0nKTtcbiAgICAgICAgY29uc3QgdGl0bGUgPSB0aXRsZUVsZW1lbnQ/LnRleHRDb250ZW50Py50cmltKCkgfHwgJ1Vua25vd24nO1xuXG4gICAgICAgIC8vIFRyeSB0byBmaW5kIGEgZGlyZWN0IGRlbGV0ZSBidXR0b24gZmlyc3RcbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuREVMRVRFX0JVVFRPTikge1xuICAgICAgICAgIGNvbnN0IGRlbGV0ZUJ1dHRvbiA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICBpZiAoZGVsZXRlQnV0dG9uKSB7XG4gICAgICAgICAgICAoZGVsZXRlQnV0dG9uIGFzIEhUTUxFbGVtZW50KS5jbGljaygpO1xuICAgICAgICAgICAgcmV0dXJuIHsgbm90ZUlkLCB0aXRsZSwgZm91bmQ6IHRydWUsIG5lZWRzRHJvcGRvd246IGZhbHNlIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTm8gZGlyZWN0IGRlbGV0ZSBidXR0b24g4oCUIGNoZWNrIGZvciBhIG1vcmUtb3B0aW9ucyBidXR0b25cbiAgICAgICAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBzZWxlY3RvcnMuTU9SRV9PUFRJT05TKSB7XG4gICAgICAgICAgY29uc3QgbW9yZUJ1dHRvbiA9IGZpcnN0Tm90ZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgICBpZiAobW9yZUJ1dHRvbikge1xuICAgICAgICAgICAgKG1vcmVCdXR0b24gYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCk7XG4gICAgICAgICAgICByZXR1cm4geyBub3RlSWQsIHRpdGxlLCBmb3VuZDogdHJ1ZSwgbmVlZHNEcm9wZG93bjogdHJ1ZSB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IG5vdGVJZCwgdGl0bGUsIGZvdW5kOiBmYWxzZSwgZXJyb3I6ICdEZWxldGUgYnV0dG9uIG5vdCBmb3VuZCcgfTtcbiAgICAgIH0sIERFTEVURV9TRUxFQ1RPUlMpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5mb3VuZCkge1xuICAgICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IocmVzdWx0LmVycm9yIHx8ICdGYWlsZWQgdG8gZmluZCBkZWxldGUgYnV0dG9uJywge30pO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiB3ZSBjbGlja2VkIFwibW9yZSBvcHRpb25zXCIsIHdhaXQgZm9yIGRyb3Bkb3duIHRoZW4gY2xpY2sgZGVsZXRlIGluIGl0XG4gICAgICBpZiAocmVzdWx0Lm5lZWRzRHJvcGRvd24pIHtcbiAgICAgICAgYXdhaXQgc2xlZXAoMTAwMCk7XG4gICAgICAgIGxldCBjbGlja2VkID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgREVMRVRFX1NFTEVDVE9SUy5EUk9QRE9XTl9NRU5VKSB7XG4gICAgICAgICAgY29uc3QgZHJvcGRvd24gPSBhd2FpdCBwYWdlLiQoc2VsZWN0b3IpO1xuICAgICAgICAgIGlmIChkcm9wZG93bikge1xuICAgICAgICAgICAgZm9yIChjb25zdCBkZWxldGVTZWxlY3RvciBvZiBERUxFVEVfU0VMRUNUT1JTLkRFTEVURV9CVVRUT04pIHtcbiAgICAgICAgICAgICAgY29uc3QgZGVsZXRlQnRuID0gYXdhaXQgZHJvcGRvd24uJChkZWxldGVTZWxlY3Rvcik7XG4gICAgICAgICAgICAgIGlmIChkZWxldGVCdG4pIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBkZWxldGVCdG4uY2xpY2soKTtcbiAgICAgICAgICAgICAgICBjbGlja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNsaWNrZWQpIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNsaWNrZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRGVsZXRlRXJyb3IoJ0RlbGV0ZSBidXR0b24gbm90IGZvdW5kIGluIGRyb3Bkb3duIG1lbnUnLCB7fSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gV2FpdCBmb3IgY29uZmlybWF0aW9uIGRpYWxvZyBpZiBpdCBhcHBlYXJzXG4gICAgICBhd2FpdCBzbGVlcCgxMDAwKTtcblxuICAgICAgLy8gSGFuZGxlIGNvbmZpcm1hdGlvbiBkaWFsb2dcbiAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ29uZmlybWF0aW9uRGlhbG9nKHBhZ2UpO1xuXG4gICAgICByZXR1cm4geyBub3RlSWQ6IHJlc3VsdC5ub3RlSWQsIHRpdGxlOiByZXN1bHQudGl0bGUgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IERlbGV0ZUVycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIGZpbmQgYW5kIGRlbGV0ZSBsYXN0IG5vdGUnLFxuICAgICAgICB7fSxcbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgY29uZmlybWF0aW9uIGRpYWxvZyBmb3IgZGVsZXRlIG9wZXJhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVDb25maXJtYXRpb25EaWFsb2cocGFnZTogUGFnZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBXYWl0IGZvciBjb25maXJtYXRpb24gZGlhbG9nIHRvIGFwcGVhclxuICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG5cbiAgICAgIC8vIExvb2sgZm9yIGNvbmZpcm1hdGlvbiBidXR0b25zIHVzaW5nIGFsbCBwb3NzaWJsZSBzZWxlY3RvcnNcbiAgICAgIGxldCBjb25maXJtQnV0dG9uOiBpbXBvcnQoJ3B1cHBldGVlcicpLkVsZW1lbnRIYW5kbGU8RWxlbWVudD4gfCBudWxsID0gbnVsbDtcblxuICAgICAgLy8gVHJ5IGVhY2ggY29uZmlybSBidXR0b24gc2VsZWN0b3JcbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgREVMRVRFX1NFTEVDVE9SUy5DT05GSVJNX0JVVFRPTikge1xuICAgICAgICBjb25maXJtQnV0dG9uID0gYXdhaXQgcGFnZS4kKHNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGNvbmZpcm1CdXR0b24pIHtcbiAgICAgICAgICBsb2dnZXIuaW5mbyhgRm91bmQgY29uZmlybSBidXR0b24gd2l0aCBzZWxlY3RvcjogJHtzZWxlY3Rvcn1gKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBJZiBub3QgZm91bmQsIHRyeSBtb2RhbCBjb25maXJtIHNlbGVjdG9yc1xuICAgICAgaWYgKCFjb25maXJtQnV0dG9uKSB7XG4gICAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgREVMRVRFX1NFTEVDVE9SUy5NT0RBTF9DT05GSVJNKSB7XG4gICAgICAgICAgY29uZmlybUJ1dHRvbiA9IGF3YWl0IHBhZ2UuJChzZWxlY3Rvcik7XG4gICAgICAgICAgaWYgKGNvbmZpcm1CdXR0b24pIHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBGb3VuZCBtb2RhbCBjb25maXJtIGJ1dHRvbiB3aXRoIHNlbGVjdG9yOiAke3NlbGVjdG9yfWApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maXJtQnV0dG9uKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdDbGlja2luZyBjb25maXJtYXRpb24gYnV0dG9uJyk7XG4gICAgICAgIGF3YWl0IGNvbmZpcm1CdXR0b24uY2xpY2soKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoMjAwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiBubyBjb25maXJtYXRpb24gZGlhbG9nLCB0aGUgZGVsZXRlIG1pZ2h0IGhhdmUgYmVlbiBpbW1lZGlhdGVcbiAgICAgICAgbG9nZ2VyLmluZm8oJ05vIGNvbmZpcm1hdGlvbiBkaWFsb2cgZm91bmQsIGRlbGV0ZSBtaWdodCBiZSBpbW1lZGlhdGUnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBoYW5kbGUgY29uZmlybWF0aW9uIGRpYWxvZzogJHtlcnJvcn1gKTtcbiAgICAgIC8vIENvbnRpbnVlIGFueXdheSBhcyB0aGUgZGVsZXRlIG1pZ2h0IHN0aWxsIHdvcmtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogTm90ZSBzZXJ2aWNlIGZvciBYSFMgTUNQIFNlcnZlclxuICogSGFuZGxlcyB1c2VyIG5vdGVzL2ZlZWRzIG9wZXJhdGlvbnNcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENvbmZpZywgWEhTUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvYmFzZS5zZXJ2aWNlJztcbmltcG9ydCB7IEJyb3dzZXJNYW5hZ2VyIH0gZnJvbSAnLi4vYnJvd3Nlci9icm93c2VyLm1hbmFnZXInO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2xvZ2dlcic7XG5pbXBvcnQgeyBOb3RlUGFyc2luZ0Vycm9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Vycm9ycyc7XG5pbXBvcnQgeyBuYXZpZ2F0ZVRvQ3JlYXRvckNlbnRlciwgdmVyaWZ5Q3JlYXRvckF1dGggfSBmcm9tICcuLi8uLi9zaGFyZWQvY3JlYXRvci1jZW50ZXInO1xuaW1wb3J0IHsgRGVsZXRlU2VydmljZSwgRGVsZXRlUmVzdWx0IH0gZnJvbSAnLi4vZGVsZXRpbmcvZGVsZXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlck5vdGUge1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuICByZWFkb25seSB0aXRsZTogc3RyaW5nO1xuICByZWFkb25seSBjb250ZW50OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGltYWdlczogcmVhZG9ubHkgc3RyaW5nW107XG4gIHJlYWRvbmx5IHZpZGVvPzogc3RyaW5nO1xuICByZWFkb25seSBwdWJsaXNoVGltZTogbnVtYmVyO1xuICByZWFkb25seSB1cGRhdGVUaW1lOiBudW1iZXI7XG4gIHJlYWRvbmx5IGxpa2VDb3VudDogbnVtYmVyO1xuICByZWFkb25seSBjb21tZW50Q291bnQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgc2hhcmVDb3VudDogbnVtYmVyO1xuICByZWFkb25seSBjb2xsZWN0Q291bnQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgdGFnczogcmVhZG9ubHkgc3RyaW5nW107XG4gIHJlYWRvbmx5IHVybDogc3RyaW5nO1xuICByZWFkb25seSB2aXNpYmlsaXR5OiAncHVibGljJyB8ICdwcml2YXRlJyB8ICdmcmllbmRzJyB8ICd1bmtub3duJztcbiAgcmVhZG9ubHkgdmlzaWJpbGl0eVRleHQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlck5vdGVzUmVzdWx0IGV4dGVuZHMgWEhTUmVzcG9uc2U8VXNlck5vdGVbXT4ge1xuICByZWFkb25seSB0b3RhbDogbnVtYmVyO1xuICByZWFkb25seSBoYXNNb3JlOiBib29sZWFuO1xuICByZWFkb25seSBuZXh0Q3Vyc29yPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgTm90ZUV4dHJhY3Rpb25EYXRhIHtcbiAgaWQ6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xuICBpbWFnZXM6IHN0cmluZ1tdO1xuICBwdWJsaXNoVGltZTogbnVtYmVyO1xuICB1cGRhdGVUaW1lOiBudW1iZXI7XG4gIGxpa2VDb3VudDogbnVtYmVyO1xuICBjb21tZW50Q291bnQ6IG51bWJlcjtcbiAgc2hhcmVDb3VudDogbnVtYmVyO1xuICBjb2xsZWN0Q291bnQ6IG51bWJlcjtcbiAgdGFnczogc3RyaW5nW107XG4gIHVybDogc3RyaW5nO1xuICB2aXNpYmlsaXR5OiAncHVibGljJyB8ICdwcml2YXRlJyB8ICdmcmllbmRzJyB8ICd1bmtub3duJztcbiAgdmlzaWJpbGl0eVRleHQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBDU1Mgc2VsZWN0b3JzIGZvciBub3RlIGV4dHJhY3Rpb24gZnJvbSBDcmVhdG9yIENlbnRlclxuICovXG5jb25zdCBOT1RFX1NFTEVDVE9SUyA9IHtcbiAgTk9URV9FTEVNRU5UUzogJ2Rpdi5ub3RlJyxcbiAgVElUTEVfRUxFTUVOVFM6ICdbY2xhc3MqPVwicmF3XCJdLCBbY2xhc3MqPVwidGl0bGVcIl0sIFtjbGFzcyo9XCJuYW1lXCJdJyxcbiAgSU1BR0VfRUxFTUVOVFM6ICdpbWdbY2xhc3MqPVwibWVkaWFcIl0sIGltZ1tjbGFzcyo9XCJjb3ZlclwiXSwgaW1nW2NsYXNzKj1cInRodW1ibmFpbFwiXScsXG4gIFNUQVRfRUxFTUVOVFM6ICdbY2xhc3MqPVwiY291bnRcIl0sIFtjbGFzcyo9XCJzdGF0XCJdLCBbY2xhc3MqPVwibnVtYmVyXCJdJyxcbiAgVEFHX0VMRU1FTlRTOiAnW2NsYXNzKj1cInRhZ1wiXSwgW2NsYXNzKj1cImxhYmVsXCJdJyxcbiAgTk9URV9MSU5LOiAnYVtocmVmKj1cIi9leHBsb3JlL1wiXSwgYVtocmVmKj1cIi9ub3RlL1wiXScsXG4gIFZJU0lCSUxJVFlfSU5ESUNBVE9SUzpcbiAgICAnW2NsYXNzKj1cInByaXZhdGVcIl0sIFtjbGFzcyo9XCJ2aXNpYmlsaXR5XCJdLCBbY2xhc3MqPVwibG9ja1wiXSwgW2NsYXNzKj1cImV5ZVwiXSwgW2NsYXNzKj1cInB1YmxpY1wiXSwgW2NsYXNzKj1cImZyaWVuZHNcIl0sIFtjbGFzcyo9XCJzdGF0dXNcIl0nLFxuICBQVUJMSVNIX1RJTUU6ICdbY2xhc3MqPVwidGltZVwiXSwgW2NsYXNzKj1cImRhdGVcIl0sIFtjbGFzcyo9XCJwdWJsaXNoLXRpbWVcIl0nLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IGNsYXNzIE5vdGVTZXJ2aWNlIGV4dGVuZHMgQmFzZVNlcnZpY2Uge1xuICBwcml2YXRlIGRlbGV0ZVNlcnZpY2U6IERlbGV0ZVNlcnZpY2U7XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcsIGJyb3dzZXJNYW5hZ2VyPzogQnJvd3Nlck1hbmFnZXIpIHtcbiAgICBzdXBlcihjb25maWcsIGJyb3dzZXJNYW5hZ2VyKTtcbiAgICB0aGlzLmRlbGV0ZVNlcnZpY2UgPSBuZXcgRGVsZXRlU2VydmljZShjb25maWcsIHRoaXMuYnJvd3Nlck1hbmFnZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHVzZXIncyBwdWJsaXNoZWQgbm90ZXMgZnJvbSBjcmVhdG9yIGNlbnRlclxuICAgKiBAcGFyYW0gbGltaXQgLSBNYXhpbXVtIG51bWJlciBvZiBub3RlcyB0byByZXR1cm4gKGRlZmF1bHQ6IDIwKVxuICAgKiBAcGFyYW0gY3Vyc29yIC0gUGFnaW5hdGlvbiBjdXJzb3IgZm9yIG5leHQgcGFnZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8VXNlck5vdGVzUmVzdWx0PiAtIFVzZXIgbm90ZXMgd2l0aCBwYWdpbmF0aW9uIGluZm9cbiAgICovXG4gIGFzeW5jIGdldFVzZXJOb3RlcyhcbiAgICBsaW1pdDogbnVtYmVyID0gMjAsXG4gICAgY3Vyc29yPzogc3RyaW5nLFxuICAgIGJyb3dzZXJQYXRoPzogc3RyaW5nXG4gICk6IFByb21pc2U8VXNlck5vdGVzUmVzdWx0PiB7XG4gICAgdGhpcy52YWxpZGF0ZUdldFVzZXJOb3Rlc1BhcmFtcyhsaW1pdCk7XG5cbiAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5nZXRCcm93c2VyTWFuYWdlcigpLmNyZWF0ZVBhZ2UodHJ1ZSwgYnJvd3NlclBhdGgsIHRydWUpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIE5hdmlnYXRlIHRvIGNyZWF0b3IgY2VudGVyIG5vdGUgbWFuYWdlclxuICAgICAgYXdhaXQgbmF2aWdhdGVUb0NyZWF0b3JDZW50ZXIocGFnZSk7XG4gICAgICBhd2FpdCB2ZXJpZnlDcmVhdG9yQXV0aChwYWdlLCB0aGlzLmdldENvbmZpZygpLnhocy5sb2dpbk9rU2VsZWN0b3IpO1xuXG4gICAgICAvLyBFeHRyYWN0IG5vdGVzIGZyb20gY3JlYXRvciBjZW50ZXJcbiAgICAgIGNvbnN0IG5vdGVzRGF0YSA9IGF3YWl0IHRoaXMuZXh0cmFjdE5vdGVzRnJvbUNyZWF0b3JDZW50ZXIocGFnZSk7XG4gICAgICBjb25zdCBsaW1pdGVkTm90ZXMgPSB0aGlzLmxpbWl0Tm90ZXMobm90ZXNEYXRhLCBsaW1pdCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGRhdGE6IGxpbWl0ZWROb3RlcyxcbiAgICAgICAgdG90YWw6IG5vdGVzRGF0YS5sZW5ndGgsXG4gICAgICAgIGhhc01vcmU6IG5vdGVzRGF0YS5sZW5ndGggPiBsaW1pdCxcbiAgICAgICAgbmV4dEN1cnNvcjogdGhpcy5nZXROZXh0Q3Vyc29yKGxpbWl0ZWROb3RlcyksXG4gICAgICAgIG9wZXJhdGlvbjogJ2dldFVzZXJOb3RlcycsXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlck5vdGVzUmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgdXNlciBub3RlczogJHtlcnJvcn1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgdG90YWw6IDAsXG4gICAgICAgIGhhc01vcmU6IGZhbHNlLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICBvcGVyYXRpb246ICdnZXRVc2VyTm90ZXMnLFxuICAgICAgfSBhcyB1bmtub3duIGFzIFVzZXJOb3Rlc1Jlc3VsdDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcGFnZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBwYXJhbWV0ZXJzIGZvciBnZXRVc2VyTm90ZXMgbWV0aG9kXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlR2V0VXNlck5vdGVzUGFyYW1zKGxpbWl0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAobGltaXQgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IE5vdGVQYXJzaW5nRXJyb3IoJ0xpbWl0IG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnLCB7IGxpbWl0IH0pO1xuICAgIH1cbiAgICBpZiAobGltaXQgPiAxMDApIHtcbiAgICAgIHRocm93IG5ldyBOb3RlUGFyc2luZ0Vycm9yKCdMaW1pdCBjYW5ub3QgZXhjZWVkIDEwMCcsIHsgbGltaXQgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3Qgbm90ZXMgZnJvbSBjcmVhdG9yIGNlbnRlciBwYWdlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4dHJhY3ROb3Rlc0Zyb21DcmVhdG9yQ2VudGVyKHBhZ2U6IFBhZ2UpOiBQcm9taXNlPE5vdGVFeHRyYWN0aW9uRGF0YVtdPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG5vdGVzRGF0YSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKHNlbGVjdG9yczogdHlwZW9mIE5PVEVfU0VMRUNUT1JTKSA9PiB7XG4gICAgICAgIGNvbnN0IG5vdGVzOiBOb3RlRXh0cmFjdGlvbkRhdGFbXSA9IFtdO1xuXG4gICAgICAgIC8vIEZpbmQgbm90ZSBlbGVtZW50cyB1c2luZyB0aGUgY3JlYXRvciBjZW50ZXIgc2VsZWN0b3JcbiAgICAgICAgY29uc3Qgbm90ZUVsZW1lbnRzID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9ycy5OT1RFX0VMRU1FTlRTKSk7XG5cbiAgICAgICAgbm90ZUVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQ6IEVsZW1lbnQpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRXh0cmFjdCBub3RlIGRhdGEgZnJvbSBlbGVtZW50XG4gICAgICAgICAgICBjb25zdCBwdWJsaXNoVGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBjb25zdCBub3RlOiBOb3RlRXh0cmFjdGlvbkRhdGEgPSB7XG4gICAgICAgICAgICAgIGlkOiAnJyxcbiAgICAgICAgICAgICAgdGl0bGU6ICcnLFxuICAgICAgICAgICAgICBjb250ZW50OiAnJyxcbiAgICAgICAgICAgICAgaW1hZ2VzOiBbXSxcbiAgICAgICAgICAgICAgcHVibGlzaFRpbWUsXG4gICAgICAgICAgICAgIHVwZGF0ZVRpbWU6IHB1Ymxpc2hUaW1lLFxuICAgICAgICAgICAgICBsaWtlQ291bnQ6IDAsXG4gICAgICAgICAgICAgIGNvbW1lbnRDb3VudDogMCxcbiAgICAgICAgICAgICAgc2hhcmVDb3VudDogMCxcbiAgICAgICAgICAgICAgY29sbGVjdENvdW50OiAwLFxuICAgICAgICAgICAgICB0YWdzOiBbXSxcbiAgICAgICAgICAgICAgdXJsOiAnJyxcbiAgICAgICAgICAgICAgdmlzaWJpbGl0eTogJ3Vua25vd24nLFxuICAgICAgICAgICAgICB2aXNpYmlsaXR5VGV4dDogJycsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IG5vdGUgSUQgZnJvbSBkYXRhIGF0dHJpYnV0ZXMgb3IgaW1wcmVzc2lvbiBkYXRhXG4gICAgICAgICAgICBjb25zdCBpbXByZXNzaW9uRGF0YSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWltcHJlc3Npb24nKTtcbiAgICAgICAgICAgIGlmIChpbXByZXNzaW9uRGF0YSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoaW1wcmVzc2lvbkRhdGEpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG5vdGVJZCA9IHBhcnNlZD8ubm90ZVRhcmdldD8udmFsdWU/Lm5vdGVJZDtcbiAgICAgICAgICAgICAgICBpZiAobm90ZUlkKSB7XG4gICAgICAgICAgICAgICAgICBub3RlLmlkID0gbm90ZUlkO1xuICAgICAgICAgICAgICAgICAgbm90ZS51cmwgPSBgaHR0cHM6Ly93d3cueGlhb2hvbmdzaHUuY29tL2V4cGxvcmUvJHtub3RlSWR9YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBJZ25vcmUgcGFyc2luZyBlcnJvcnNcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IHRpdGxlL2NvbnRlbnRcbiAgICAgICAgICAgIGNvbnN0IHRpdGxlRWxlbWVudCA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcnMuVElUTEVfRUxFTUVOVFMpO1xuICAgICAgICAgICAgaWYgKHRpdGxlRWxlbWVudCkge1xuICAgICAgICAgICAgICBjb25zdCB0aXRsZSA9IHRpdGxlRWxlbWVudC50ZXh0Q29udGVudD8udHJpbSgpID8/ICcnO1xuICAgICAgICAgICAgICBub3RlLnRpdGxlID0gdGl0bGU7XG4gICAgICAgICAgICAgIG5vdGUuY29udGVudCA9IHRpdGxlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IGltYWdlcyAtIHRyeSBtdWx0aXBsZSBhcHByb2FjaGVzIGZvciBjcmVhdG9yIGNlbnRlclxuICAgICAgICAgICAgY29uc3QgaW1hZ2VTZWxlY3RvcnMgPSBbXG4gICAgICAgICAgICAgIHNlbGVjdG9ycy5JTUFHRV9FTEVNRU5UUyxcbiAgICAgICAgICAgICAgJ2ltZycsIC8vIFRyeSBhbGwgaW1nIGVsZW1lbnRzXG4gICAgICAgICAgICAgICdbY2xhc3MqPVwiaW1hZ2VcIl0nLFxuICAgICAgICAgICAgICAnW2NsYXNzKj1cInBob3RvXCJdJyxcbiAgICAgICAgICAgICAgJ1tjbGFzcyo9XCJwaWNcIl0nLFxuICAgICAgICAgICAgICAnW2NsYXNzKj1cImltZ1wiXScsXG4gICAgICAgICAgICAgICdbc3R5bGUqPVwiYmFja2dyb3VuZC1pbWFnZVwiXScsIC8vIEJhY2tncm91bmQgaW1hZ2VzXG4gICAgICAgICAgICAgICdkaXZbY2xhc3MqPVwiY292ZXJcIl0gaW1nJyxcbiAgICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJ0aHVtYm5haWxcIl0gaW1nJyxcbiAgICAgICAgICAgICAgJ2RpdltjbGFzcyo9XCJtZWRpYVwiXSBpbWcnLFxuICAgICAgICAgICAgXTtcblxuICAgICAgICAgICAgbGV0IGltYWdlRWxlbWVudHM6IGFueVtdID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNlbGVjdG9yIG9mIGltYWdlU2VsZWN0b3JzKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBpbWFnZUVsZW1lbnRzID0gQXJyYXkuZnJvbShlbGVtZW50cyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaW1hZ2VFbGVtZW50cy5mb3JFYWNoKChpbWc6IEVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgICAgbGV0IHNyYyA9ICcnO1xuXG4gICAgICAgICAgICAgIC8vIFRyeSBkaWZmZXJlbnQgd2F5cyB0byBnZXQgaW1hZ2Ugc291cmNlXG4gICAgICAgICAgICAgIGNvbnN0IGh0bWxJbWcgPSBpbWcgYXMgSFRNTEltYWdlRWxlbWVudDtcbiAgICAgICAgICAgICAgaWYgKGh0bWxJbWcuc3JjKSB7XG4gICAgICAgICAgICAgICAgc3JjID0gaHRtbEltZy5zcmM7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoaHRtbEltZy5zdHlsZSAmJiBodG1sSW1nLnN0eWxlLmJhY2tncm91bmRJbWFnZSkge1xuICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgZnJvbSBiYWNrZ3JvdW5kLWltYWdlIENTU1xuICAgICAgICAgICAgICAgIGNvbnN0IGJnTWF0Y2ggPSBodG1sSW1nLnN0eWxlLmJhY2tncm91bmRJbWFnZS5tYXRjaCgvdXJsXFwoWydcIl0/KFteJ1wiXSspWydcIl0/XFwpLyk7XG4gICAgICAgICAgICAgICAgaWYgKGJnTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgIHNyYyA9IGJnTWF0Y2hbMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGltZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtc3JjJykpIHtcbiAgICAgICAgICAgICAgICAvLyBMYXp5IGxvYWRlZCBpbWFnZXNcbiAgICAgICAgICAgICAgICBzcmMgPSBpbWcuZ2V0QXR0cmlidXRlKCdkYXRhLXNyYycpIHx8ICcnO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGltZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JpZ2luYWwnKSkge1xuICAgICAgICAgICAgICAgIC8vIEFub3RoZXIgbGF6eSBsb2FkaW5nIGF0dHJpYnV0ZVxuICAgICAgICAgICAgICAgIHNyYyA9IGltZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtb3JpZ2luYWwnKSB8fCAnJztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzcmMgJiZcbiAgICAgICAgICAgICAgICAhc3JjLmluY2x1ZGVzKCdhdmF0YXInKSAmJlxuICAgICAgICAgICAgICAgICFzcmMuaW5jbHVkZXMoJ2ljb24nKSAmJlxuICAgICAgICAgICAgICAgICFzcmMuaW5jbHVkZXMoJ2xvZ28nKSAmJlxuICAgICAgICAgICAgICAgICFzcmMuaW5jbHVkZXMoJ3BsYWNlaG9sZGVyJykgJiZcbiAgICAgICAgICAgICAgICBzcmMuc3RhcnRzV2l0aCgnaHR0cCcpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIG5vdGUuaW1hZ2VzLnB1c2goc3JjKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cblxuICAgICAgICAgICAgLy8gRXh0cmFjdCBzdGF0cyAtIGxvb2sgZm9yIG51bWJlcnMgaW4gdGhlIGVsZW1lbnRcbiAgICAgICAgICAgIGNvbnN0IGFsbFRleHQgPSBlbGVtZW50LnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgICAgICAgY29uc3QgbnVtYmVycyA9IGFsbFRleHQubWF0Y2goL1xcZCsvZykgfHwgW107XG5cbiAgICAgICAgICAgIC8vIFRyeSB0byBleHRyYWN0IHN0YXRzIGZyb20gdGV4dCBjb250ZW50XG4gICAgICAgICAgICBpZiAobnVtYmVycy5sZW5ndGggPj0gNCkge1xuICAgICAgICAgICAgICAvLyBBc3N1bWluZyBvcmRlcjogbGlrZSwgY29tbWVudCwgc2hhcmUsIGNvbGxlY3QsIHZpZXdcbiAgICAgICAgICAgICAgbm90ZS5saWtlQ291bnQgPSBwYXJzZUludChudW1iZXJzWzBdIHx8ICcwJykgfHwgMDtcbiAgICAgICAgICAgICAgbm90ZS5jb21tZW50Q291bnQgPSBwYXJzZUludChudW1iZXJzWzFdKSB8fCAwO1xuICAgICAgICAgICAgICBub3RlLnNoYXJlQ291bnQgPSBwYXJzZUludChudW1iZXJzWzJdKSB8fCAwO1xuICAgICAgICAgICAgICBub3RlLmNvbGxlY3RDb3VudCA9IHBhcnNlSW50KG51bWJlcnNbM10pIHx8IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEV4dHJhY3QgcHVibGlzaCB0aW1lXG4gICAgICAgICAgICBjb25zdCB0aW1lRWxlbWVudCA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcnMuUFVCTElTSF9USU1FKTtcbiAgICAgICAgICAgIGlmICh0aW1lRWxlbWVudCkge1xuICAgICAgICAgICAgICBjb25zdCB0aW1lVGV4dCA9IHRpbWVFbGVtZW50LnRleHRDb250ZW50Py50cmltKCkgfHwgJyc7XG4gICAgICAgICAgICAgIGlmICh0aW1lVGV4dC5pbmNsdWRlcygn5Y+R5biD5LqOJykpIHtcbiAgICAgICAgICAgICAgICAvLyBQYXJzZSBDaGluZXNlIGRhdGUgZm9ybWF0XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZU1hdGNoID0gdGltZVRleHQubWF0Y2goXG4gICAgICAgICAgICAgICAgICAvKFxcZHs0fSnlubQoXFxkezEsMn0p5pyIKFxcZHsxLDJ9KeaXpVxccysoXFxkezEsMn0pOihcXGR7Mn0pL1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGVNYXRjaCkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgWywgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlXSA9IGRhdGVNYXRjaDtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHB1Ymxpc2hEYXRlID0gbmV3IERhdGUoXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlSW50KHllYXIpLFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUludChtb250aCkgLSAxLFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUludChkYXkpLFxuICAgICAgICAgICAgICAgICAgICBwYXJzZUludChob3VyKSxcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQobWludXRlKVxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIG5vdGUucHVibGlzaFRpbWUgPSBwdWJsaXNoRGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgICBub3RlLnVwZGF0ZVRpbWUgPSBwdWJsaXNoRGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEV4dHJhY3QgdmlzaWJpbGl0eSBpbmZvcm1hdGlvblxuICAgICAgICAgICAgY29uc3QgZWxlbWVudFRleHQgPSBlbGVtZW50LnRleHRDb250ZW50Py50b0xvd2VyQ2FzZSgpIHx8ICcnO1xuICAgICAgICAgICAgaWYgKGVsZW1lbnRUZXh0LmluY2x1ZGVzKCfku4Xoh6rlt7Hlj6/op4EnKSkge1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHkgPSAncHJpdmF0ZSc7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eVRleHQgPSAn5LuF6Ieq5bex5Y+v6KeBJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudFRleHQuaW5jbHVkZXMoJ+aci+WPi+WPr+ingScpKSB7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eSA9ICdmcmllbmRzJztcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5VGV4dCA9ICfmnIvlj4vlj6/op4EnO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50VGV4dC5pbmNsdWRlcygn5YWs5byAJykpIHtcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5ID0gJ3B1YmxpYyc7XG4gICAgICAgICAgICAgIG5vdGUudmlzaWJpbGl0eVRleHQgPSAn5YWs5byAJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIERlZmF1bHQgdG8gcHVibGljIGZvciBub3RlcyB3aXRob3V0IGV4cGxpY2l0IHZpc2liaWxpdHkgaW5kaWNhdG9yc1xuICAgICAgICAgICAgICBub3RlLnZpc2liaWxpdHkgPSAncHVibGljJztcbiAgICAgICAgICAgICAgbm90ZS52aXNpYmlsaXR5VGV4dCA9ICflhazlvIAnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFeHRyYWN0IHRhZ3NcbiAgICAgICAgICAgIGNvbnN0IHRhZ0VsZW1lbnRzID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9ycy5UQUdfRUxFTUVOVFMpO1xuICAgICAgICAgICAgdGFnRWxlbWVudHMuZm9yRWFjaCgodGFnOiBFbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHRhZ1RleHQgPSB0YWcudGV4dENvbnRlbnQ/LnRyaW0oKTtcbiAgICAgICAgICAgICAgaWYgKHRhZ1RleHQ/LnN0YXJ0c1dpdGgoJyMnKSkge1xuICAgICAgICAgICAgICAgIG5vdGUudGFncy5wdXNoKHRhZ1RleHQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKG5vdGUuaWQpIHtcbiAgICAgICAgICAgICAgbm90ZXMucHVzaChub3RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gSWdub3JlIGV4dHJhY3Rpb24gZXJyb3JzIGZvciBpbmRpdmlkdWFsIG5vdGVzXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbm90ZXM7XG4gICAgICB9LCBOT1RFX1NFTEVDVE9SUyk7XG5cbiAgICAgIHJldHVybiBub3Rlc0RhdGE7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBOb3RlUGFyc2luZ0Vycm9yKFxuICAgICAgICAnRmFpbGVkIHRvIGV4dHJhY3Qgbm90ZXMgZnJvbSBjcmVhdG9yIGNlbnRlcicsXG4gICAgICAgIHsgb3BlcmF0aW9uOiAnZXh0cmFjdE5vdGVzRnJvbUNyZWF0b3JDZW50ZXInIH0sXG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGltaXQgbm90ZXMgYXJyYXkgdG8gc3BlY2lmaWVkIGNvdW50XG4gICAqL1xuICBwcml2YXRlIGxpbWl0Tm90ZXMobm90ZXM6IE5vdGVFeHRyYWN0aW9uRGF0YVtdLCBsaW1pdDogbnVtYmVyKTogVXNlck5vdGVbXSB7XG4gICAgcmV0dXJuIG5vdGVzLnNsaWNlKDAsIGxpbWl0KS5tYXAoKG5vdGUpID0+ICh7XG4gICAgICBpZDogbm90ZS5pZCxcbiAgICAgIHRpdGxlOiBub3RlLnRpdGxlLFxuICAgICAgY29udGVudDogbm90ZS5jb250ZW50LFxuICAgICAgaW1hZ2VzOiBPYmplY3QuZnJlZXplKFsuLi5ub3RlLmltYWdlc10pLFxuICAgICAgcHVibGlzaFRpbWU6IG5vdGUucHVibGlzaFRpbWUsXG4gICAgICB1cGRhdGVUaW1lOiBub3RlLnVwZGF0ZVRpbWUsXG4gICAgICBsaWtlQ291bnQ6IG5vdGUubGlrZUNvdW50LFxuICAgICAgY29tbWVudENvdW50OiBub3RlLmNvbW1lbnRDb3VudCxcbiAgICAgIHNoYXJlQ291bnQ6IG5vdGUuc2hhcmVDb3VudCxcbiAgICAgIGNvbGxlY3RDb3VudDogbm90ZS5jb2xsZWN0Q291bnQsXG4gICAgICB0YWdzOiBPYmplY3QuZnJlZXplKFsuLi5ub3RlLnRhZ3NdKSxcbiAgICAgIHVybDogbm90ZS51cmwsXG4gICAgICB2aXNpYmlsaXR5OiBub3RlLnZpc2liaWxpdHksXG4gICAgICB2aXNpYmlsaXR5VGV4dDogbm90ZS52aXNpYmlsaXR5VGV4dCxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IG5leHQgY3Vyc29yIGZvciBwYWdpbmF0aW9uXG4gICAqL1xuICBwcml2YXRlIGdldE5leHRDdXJzb3Iobm90ZXM6IFVzZXJOb3RlW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBub3Rlcy5sZW5ndGggPiAwID8gbm90ZXNbbm90ZXMubGVuZ3RoIC0gMV0uaWQgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGEgc3BlY2lmaWMgbm90ZSBieSBJRFxuICAgKiBAcGFyYW0gbm90ZUlkIC0gVGhlIElEIG9mIHRoZSBub3RlIHRvIGRlbGV0ZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8RGVsZXRlUmVzdWx0PiAtIERlbGV0ZSBvcGVyYXRpb24gcmVzdWx0XG4gICAqL1xuICBhc3luYyBkZWxldGVOb3RlKG5vdGVJZDogc3RyaW5nLCBicm93c2VyUGF0aD86IHN0cmluZyk6IFByb21pc2U8RGVsZXRlUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZXRlU2VydmljZS5kZWxldGVOb3RlKG5vdGVJZCwgYnJvd3NlclBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgbGFzdCBwdWJsaXNoZWQgbm90ZVxuICAgKiBAcGFyYW0gYnJvd3NlclBhdGggLSBPcHRpb25hbCBjdXN0b20gYnJvd3NlciBwYXRoXG4gICAqIEByZXR1cm5zIFByb21pc2U8RGVsZXRlUmVzdWx0PiAtIERlbGV0ZSBvcGVyYXRpb24gcmVzdWx0XG4gICAqL1xuICBhc3luYyBkZWxldGVMYXN0UHVibGlzaGVkTm90ZShicm93c2VyUGF0aD86IHN0cmluZyk6IFByb21pc2U8RGVsZXRlUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZXRlU2VydmljZS5kZWxldGVMYXN0UHVibGlzaGVkTm90ZShicm93c2VyUGF0aCk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9113\n\n}");
137
+
138
+ /***/ }),
139
+
133
140
  /***/ 9135:
134
141
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
135
142